Page 1 of 1
[SPI] how to stop using DMA
Posted: Wed Dec 12, 2018 10:37 pm
by michprev
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?
Re: [SPI] how to stop using DMA
Posted: Thu Dec 13, 2018 4:32 am
by ESP_Sprite
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?
Re: [SPI] how to stop using DMA
Posted: Thu Dec 13, 2018 5:07 pm
by michprev
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.
Also, out of curiosity, is there a reason you're writing your own driver, foregoing the one in esp-idf?
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.
This way I also discovered bugs in ESP-IDF driver. Some of them are fixed now.
Re: [SPI] how to stop using DMA
Posted: Fri Jan 11, 2019 2:44 pm
by squonk11
@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.
Re: [SPI] how to stop using DMA
Posted: Fri Jan 11, 2019 7:12 pm
by michprev
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.
Re: [SPI] how to stop using DMA
Posted: Fri Jan 11, 2019 9:44 pm
by squonk11
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.
Re: [SPI] how to stop using DMA
Posted: Wed Jan 23, 2019 12:46 am
by jspark311
squonk11 wrote: ↑Fri Jan 11, 2019 9:44 pm
Currently I am working on a totally stupid solution:
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
Posted: Thu Jan 24, 2019 5:09 pm
by squonk11
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?
Re: [SPI] how to stop using DMA
Posted: Thu Jan 24, 2019 7:01 pm
by jspark311
squonk11 wrote: ↑Thu Jan 24, 2019 5:09 pm
Are you able to read also more than 64 bytes (e.g. 113 bytes) with your driver without loosing some bytes?
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.
squonk11 wrote: ↑Thu Jan 24, 2019 5:09 pm
how can I use your code? What are the API functions I need to call?
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.