[SPI] how to stop using DMA

michprev
Posts: 92
Joined: Fri Aug 04, 2017 8:57 pm

[SPI] how to stop using DMA

Postby michprev » Wed Dec 12, 2018 10:37 pm

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?

ESP_Sprite
Posts: 8926
Joined: Thu Nov 26, 2015 4:08 am

Re: [SPI] how to stop using DMA

Postby ESP_Sprite » Thu Dec 13, 2018 4:32 am

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?

michprev
Posts: 92
Joined: Fri Aug 04, 2017 8:57 pm

Re: [SPI] how to stop using DMA

Postby michprev » Thu Dec 13, 2018 5:07 pm

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 :D 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.

squonk11
Posts: 69
Joined: Wed Mar 01, 2017 6:53 pm
Location: Germany

Re: [SPI] how to stop using DMA

Postby squonk11 » Fri Jan 11, 2019 2:44 pm

@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

michprev
Posts: 92
Joined: Fri Aug 04, 2017 8:57 pm

Re: [SPI] how to stop using DMA

Postby michprev » Fri Jan 11, 2019 7:12 pm

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.
Attachments
spi_master.zip
(7.49 KiB) Downloaded 543 times

squonk11
Posts: 69
Joined: Wed Mar 01, 2017 6:53 pm
Location: Germany

Re: [SPI] how to stop using DMA

Postby squonk11 » Fri Jan 11, 2019 9:44 pm

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.
"Whoever believes to be someone has stopped becoming someone"
Sokrates

jspark311
Posts: 7
Joined: Tue Feb 21, 2017 9:40 am

Re: [SPI] how to stop using DMA

Postby jspark311 » Wed Jan 23, 2019 12:46 am

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.

squonk11
Posts: 69
Joined: Wed Mar 01, 2017 6:53 pm
Location: Germany

Re: [SPI] how to stop using DMA

Postby squonk11 » Thu Jan 24, 2019 5:09 pm

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?
"Whoever believes to be someone has stopped becoming someone"
Sokrates

jspark311
Posts: 7
Joined: Tue Feb 21, 2017 9:40 am

Re: [SPI] how to stop using DMA

Postby jspark311 » Thu Jan 24, 2019 7:01 pm

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.

Who is online

Users browsing this forum: runeruiter and 94 guests