Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMA-driven SPI silently fails to transfer if data is in DCache #954

Closed
bugadani opened this issue Nov 17, 2023 · 4 comments · Fixed by #1670
Closed

DMA-driven SPI silently fails to transfer if data is in DCache #954

bugadani opened this issue Nov 17, 2023 · 4 comments · Fixed by #1670
Assignees
Labels
bug Something isn't working peripheral:dma DMA Peripheral peripheral:spi SPI peripheral
Milestone

Comments

@bugadani
Copy link
Contributor

bugadani commented Nov 17, 2023

The epd-waveshare driver (or at least this fork) tends to send 1-4 bytes (I presume constant command bytes) out of data from DCache. The ESP32-S3 TRM states that accessing DCache is possible, but with restrictions:

Any transmit and receive channels of GDMA can access 0x3C000000 ~ 0x3DFFFFFF in external RAM. GDMA
can send data only in burst mode. The number of data bytes to transfer in one burst is defined as block size.
Block size can be 16 bytes, 32 bytes or 64 bytes, configured via GDMA_IN_EXT_MEM_BK_SIZE_CHn for
transmit channels and GDMA_OUT_EXT_MEM_BK_SIZE_CHn for receive channels.

The epd-waveshare driver obviously doesn't meet the block size limit, and it doesn't matter if the application configures DMA for burst operation or not. The result is the same: nothing visible happens on the display.

IMO the driver should detect this situation and return an error or panic. As a workaround, the FlashSafeDma wrapper works in this situation.

A log excerpt with addesses and lengths from the driver's write method:

INFO - data address: 3c04187c 1 <-- DCache
INFO - data address: 3fcad0bf 1
INFO - data address: 3c041874 4 <-- DCache
INFO - data address: 3fcad0bf 1
INFO - data address: 3c04187d 1 <-- DCache
INFO - data address: 3fcad0bf 1
INFO - data address: 3c04187e 2 <-- DCache
@MabezDev
Copy link
Member

MabezDev commented Nov 17, 2023

I went looking for how esp-idf handles it. It seems its possible to tell synchronize the buffer in cache with the DMA peripheral. They call esp-cache_msync in the driver before starting the transaction. The definition lives here: https://github.com/espressif/esp-idf/blob/c8243465e45489835d645bf217a6929fd0c01b7f/components/esp_mm/esp_cache.c#L29-L90.

@MabezDev
Copy link
Member

Huh, last time I went looking into how the cache works it was all ROM code and zero docs. Now there is a esp_mm component: https://github.com/espressif/esp-idf/tree/c8243465e45489835d645bf217a6929fd0c01b7f/components/esp_mm with some docs as to how it actually works. Maybe we should try and port some of this into esp-hal.

@bugadani
Copy link
Contributor Author

I'm not sure the added complexity is worth it for us at this point. The implementation would still just return an error for unaligned data address and/or size, which we can just as easily do for all data living in DCache. Though I'm not entirely sure how simple it is to align data in the cache, it seems more restrictive than telling the user that they should use the FlashSafeDma wrapper.

@bjoernQ
Copy link
Contributor

bjoernQ commented Mar 11, 2024

Somewhat related #1235

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working peripheral:dma DMA Peripheral peripheral:spi SPI peripheral
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants