Hi,
let's say that I want to use SPI with DMA channel and then without DMA channel.
To use DMA I set channel in DPORT_SPI_DMA_CHAN_SEL_REG register. I set DPORT_SPI3_DMA_CHAN_SEL to either 1 or 2.
SPI DMA transmission is successful but how to stop using DMA now? When I set DPORT_SPI3_DMA_CHAN_SEL to 0 SPI still keeps reading wrong data (= still somehow uses DMA).
How can i stop using DMA once it has been configured? I am using my custom SPI driver, not ESP-IDF one.
periph_module_disable() & periph_module_enable() seems to work but isn't there any other better way?
[SPI] how to stop using DMA
-
- Posts: 9766
- Joined: Thu Nov 26, 2015 4:08 am
Re: [SPI] how to stop using DMA
If you don't set dma_out_link.start and dma_in_link.start at the beginning of a transaction, DMA should automatically be inhibited. No need to enable/disable/deselect/... DMA on a peripheral level.
Also, out of curiosity, is there a reason you're writing your own driver, foregoing the one in esp-idf?
Also, out of curiosity, is there a reason you're writing your own driver, foregoing the one in esp-idf?
Re: [SPI] how to stop using DMA
Found the issue, it is not even DMA related. If you set SPI_FASTRD_MODE to 0 and SPI_FREAD_QIO to 1 hardware will still perform QIO transmission. It has been fixed in TRM from 07/12/2018.
This way I also discovered bugs in ESP-IDF driver. Some of them are fixed now.
In the past I complained about state of ESP-IDF drivers so I decided to write my own to blame only myself It works without FreeRTOS so I can use it on the second core when only the first core uses FreeRTOS. There are also a few other advantages and the biggest disadvantage is missing queue.Also, out of curiosity, is there a reason you're writing your own driver, foregoing the one in esp-idf?
This way I also discovered bugs in ESP-IDF driver. Some of them are fixed now.
Re: [SPI] how to stop using DMA
@michprev : are you willing to share your code of your spi driver? I am currently stuck with the problem that the spi slave driver from Espressif has the problem that in DMA mode for certain telegrams some of the received bytes are missing. So I am searching for another solution.
"Whoever believes to be someone has stopped becoming someone"
Sokrates
Sokrates
Re: [SPI] how to stop using DMA
Unfortunately I have written driver only for SPI master. As I am no longer working with ESP32 I do not plan to extend it also for SPI slave.
There is a hardware bug in SPI DMA https://github.com/espressif/esp-idf/bl ... #L382-L438, https://github.com/espressif/esp-idf/bl ... ave.c#L387. It may be related to your issue. AFAIK these issues are not decribed anywhere.
I am attaching my code for anyone who wants to use it.
There is a hardware bug in SPI DMA https://github.com/espressif/esp-idf/bl ... #L382-L438, https://github.com/espressif/esp-idf/bl ... ave.c#L387. It may be related to your issue. AFAIK these issues are not decribed anywhere.
I am attaching my code for anyone who wants to use it.
- Attachments
-
- spi_master.zip
- (7.49 KiB) Downloaded 738 times
Re: [SPI] how to stop using DMA
Thank you for providing your source code!
But for master mode now the problem seems to be fixed also in the esp-idf sources. For the slave mode the problem still exists and unfortunalely I urgently need a solution.
Currently I am working on a totally stupid solution:
I am trying to emulate an SPI slave interface completely by polling port pins via software. My masters clock frequency is "only" 1MHz. So I am on the limit with the sampling of the SPI input clock signal. In order to make it work I had to redefine the "gpio_get_level()" and "gpio_set_level()" functions to be much simpler.
Amuch better solution would be to have the SPI slave interface generate an interrupt after every received byte. But I don't know how to achieve that because the documentation of the chip is VERY poor.
But for master mode now the problem seems to be fixed also in the esp-idf sources. For the slave mode the problem still exists and unfortunalely I urgently need a solution.
Currently I am working on a totally stupid solution:
I am trying to emulate an SPI slave interface completely by polling port pins via software. My masters clock frequency is "only" 1MHz. So I am on the limit with the sampling of the SPI input clock signal. In order to make it work I had to redefine the "gpio_get_level()" and "gpio_set_level()" functions to be much simpler.
Amuch better solution would be to have the SPI slave interface generate an interrupt after every received byte. But I don't know how to achieve that because the documentation of the chip is VERY poor.
"Whoever believes to be someone has stopped becoming someone"
Sokrates
Sokrates
Re: [SPI] how to stop using DMA
Would you like to look at my totally stupid solution?
I have an SPI slave driver that I've written. It's a mess, but it works well enough to demonstrate some things. Maybe it will help you.
https://github.com/Manuvr/Digitabulum-F ... _esp32.cpp
I can confirm ESP_Sprite's comment. The driver does not use DMA under certain circumstances and it works really well.
Presently, I'm arguing with the peripheral (or DMA, I'm unsure) to not drop the trailing several bytes. My hardware aligns the transfer on 4-byte boundaries, but I can't get the trailing bytes back while using DMA. Without DMA, everything works fine.
Re: [SPI] how to stop using DMA
Thank you for providing the link to your code.
Are you able to read also more than 64 bytes (e.g. 113 bytes) with your driver without loosing some bytes? As far as I understood the esp-idf driver it is possible to read an arbitrary number of bytes between 1 and 64 bytes without DMA (just using the internal rx buffer) - but this does not help me.
If yes: how can I use your code? What are the API functions I need to call?
Are you able to read also more than 64 bytes (e.g. 113 bytes) with your driver without loosing some bytes? As far as I understood the esp-idf driver it is possible to read an arbitrary number of bytes between 1 and 64 bytes without DMA (just using the internal rx buffer) - but this does not help me.
If yes: how can I use your code? What are the API functions I need to call?
"Whoever believes to be someone has stopped becoming someone"
Sokrates
Sokrates
Re: [SPI] how to stop using DMA
No. I only eschew DMA if the transfer is 2-bytes long. My hardware has two classes of transaction (both of them full-duplex): 2-bytes in/2-bytes out (no DMA), and 4-bytes out, X bytes in (using DMA).
I can read back 113 bytes. I see (116 x 8 [Because: transfer alignment]) clock pulses and the correct levels on the other SPI pins that corrospond to a correct transfer. But the trailing bytes (110 to 113) get lost. I still haven't solved it. I'll take another stab at it this weekend.
I don't have it broken out as a stand-alone driver, so there is no API specific to the ESP32, and it would be really hard to rip it out and use it for hardware other than mine without basically re-writing it. Moreover, it doesn't completely work. I was mainly posting it so you could see how I selectively use DMA. Feel free to rip out and use anything you find tasty.
Who is online
Users browsing this forum: No registered users and 97 guests