cancel
Showing results for 
Search instead for 
Did you mean: 

SDMMC: How to recover from a TXUNDERR error, and live to write again

Chris Rice
Associate III

Hello, we have written a kind of database module based on an SDcard, usign the SDMMC peripheral of our STM32F7, and the accompanying HAL code (which is somewhat adapted at this point).

Our software has other things going on too, and we occasionally observe an SDMMC TXUNDERR interrupt which causes a write to fail and our software to fault. I've been told in other very helpful posts that this is because SDMMC is unforgiving in terms of timing, so primarily we have been trying to cease other interrupts from firing while a write is happening, and that has helped somewhat. But what we would ideally like to do on a TXUNDERR, is to retry the write instead of faulting.

Currently it seems like the SDMMC becomes sort-of unresponsive after a TXUNDERR, and our write retries aren't working.

The datasheet says "In case of TXUNDERR, and DMA is used to fill SDMMC FIFO, user software should disable DMA stream and then write DMAEN to zero", but we aren't using DMA.

The great Clive said in a previous response "Likely going to need to reset peripheral and cycle card through escape sequence, and initialization phases."

I've tried iterations of both of these and so far no luck, so I think I could use a litte more detail from someone who has accomplished this. I'm probably failing because the "initializaton phases" seem extensive and I'm not sure which I need to re-do. Here's our init sequence, based on HAL code:

Initialization

* enable SDMMC and DMA clocks, GPIO clocks (note: even though DMA is not used, I think, HAL code inits DMA)

* configure GPIO

* enable interrupts in NVIC

* configure DMA registers

* configure SDMMC2 registers (CLKCR, POWER)

Power on (after a small delay while hardware powers up)

* Send CMD0 to card

* Send CMD8 to card to verify operating condition

* Send CMD55 and CMD41 to get card info

* Send CMD9 to get card class and more info (?)

* Enable widebus

* Set SDMMC.CLKCR again (don't know why, just following the HAL working pattern)

Hopefully we dont need to redo *all* of this. What is the specific escape sequence, and re-initialization steps, we need to do in order to perform another write in the wake of a TXUNDERR error?  Obviously I am slightly out of my depth, but learning, so the more specific the better.

Thank you!

2 REPLIES 2
TDK
Guru

Your post says TXOVERR in many places. Did you mean RXOVERR or TXUNDERR?

For RXOVERR, the simplest solution might be to just modify the HAL routines to be a little faster on reading data, and disable interrupts while they're being run. Unroll the loop, read/store a uint32_t at a time instead of just a byte. Buffers need to be word-aligned for this.

If you feel a post has answered your question, please click "Accept as Solution".
Chris Rice
Associate III

Shoot, thank you. I meant TXUNDERR.