cancel
Showing results for 
Search instead for 
Did you mean: 

Flushing/resetting DMA state

mrx23
Associate III

So DMA can read/write from 16bit SPI DR, to 32bit memory variable, in circular mode,

I need to reinit stream, but DMA TX ends up off by one 16bit in destination array,

so how can I partially reinit DMA to beginning or array/or even addresses?

Without fully reinitializing DMA, since that takes too much time with HAL..

S4M0AR  and S3M0AR always point to beginning of arrays, so they don't move around.

FIFO is not enabled. So what can cause the shift?

__HAL_DMA_DISABLE + __HAL_DMA_ENABLE doesn't seem to fix this shift.

 

Using F401 with HAL.

2 REPLIES 2
TDK
Guru

Disabling DMA, resetting memory pointers (M0AR register) and data length (NDTR register), and re-enabling it will synchronize it for the next bytes that come in.

But if it's in circular mode it should never becomes de-synced in the first place. May want to look into why that's happening instead, if you don't already know.

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

I'm still trying to debug it, eventhough I disable I2S and DMA it still clocks out I2S data!

__HAL_DMA_DISABLE(&hdma_spi2_rx);
__HAL_DMA_DISABLE(&hdma_i2s2_ext_tx);
__HAL_I2S_DISABLE(&hi2s2);

Register for stream 3/4 CR.EN shows 0.

so no matter what I set in registers it will be ineffective!

 

M0AR never changes so it's valid.

I tried to reload NDTR after disabling DMA doesn't seem to solve it.

I've got it into a weird state, it skips every 8bit (not 16bit) and it's pretty consistent.

 

I use it with slave I2S, so error is expected. Works great before the error, but after error got this in DMA TX buffer:

mrx23_0-1706981012333.png

but as you can see it consistently drops every 8bit, that's why I think some offset got stuck internally.

Which I cannot reset easily.

This is my TX DMA stream before error, and after error+reinit, they are the same so DMA should behave the same way

mrx23_0-1706987610884.png

Sure brute forcing brings it back to life, but it takes ton of time to reinit:

 

__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
__HAL_RCC_SPI2_CLK_ENABLE();

__HAL_RCC_DMA1_FORCE_RESET();
__HAL_RCC_DMA1_RELEASE_RESET();
__HAL_RCC_DMA1_CLK_ENABLE();

 

 

Alternative, HAL_I2S_DMAStop times out with "Wait until TXE flag is set"