cancel
Showing results for 
Search instead for 
Did you mean: 

STM32h7 SPI DMA communication issues + FIFO Error (FEIF)

Heiko_SM
Visitor

When using DMA to do a SPI transmit, I found a strange behavior. The problem is, that the communication to the DAC works for a few seconds, depending on the used frequency. After the few seconds only 1 byte instead of 3 bytes are sent and the NSS Pin (Hardware regulated) stays low. You can even see these two data items to transfer in S1NDTR (NDT). I used the approximately same code with Software NSS without any problem.

I also get a DMA FIFO Error (FEIF) directly after starting the DMA stream, even when using DMA circular mode. Not every time but over 50% of the times when the communication is working I get the FEIF. When the communication is not working anymore, I do not get the FEIF anymore.

 

I found these factors influencing the error:

- Using DMA normal mode/ circular mode -> no difference

- Enabling DMA FIFO -> no difference

- Increase frequency of sending values to the DAC: communication breaks very fast

- Decrease frequency of sending values to the DAC: communication does not break

- Changing Priorities -> no difference

 

 

This is my SPI configuration:

/* SPI1 parameter configuration*/

SPI_InitStruct.TransferDirection = LL_SPI_SIMPLEX_TX;

SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;

SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;

SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;

SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;

SPI_InitStruct.NSS = LL_SPI_NSS_HARD_OUTPUT;

SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;

SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;

SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;

SPI_InitStruct.CRCPoly = 0x0;

LL_SPI_Init(SPI1, &SPI_InitStruct);

LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);

LL_SPI_DisableNSSPulseMgt(SPI1);

 

 

This is my corresponding DMA config:

167: Dma.SPI1_TX.1.Direction=DMA_MEMORY_TO_PERIPH
168: Dma.SPI1_TX.1.EventEnable=DISABLE
169: Dma.SPI1_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
170: Dma.SPI1_TX.1.Instance=DMA2_Stream1
171: Dma.SPI1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
172: Dma.SPI1_TX.1.MemInc=DMA_MINC_ENABLE
173: Dma.SPI1_TX.1.Mode=DMA_CIRCULAR
174: Dma.SPI1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
175: Dma.SPI1_TX.1.PeriphInc=DMA_PINC_DISABLE
176: Dma.SPI1_TX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
177: Dma.SPI1_TX.1.Priority=DMA_PRIORITY_HIGH
178: Dma.SPI1_TX.1.RequestNumber=1
179: Dma.SPI1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
180: Dma.SPI1_TX.1.SignalID=NONE
181: Dma.SPI1_TX.1.SyncEnable=DISABLE
182: Dma.SPI1_TX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
183: Dma.SPI1_TX.1.SyncRequestNumber=1
184: Dma.SPI1_TX.1.SyncSignalID=NONE

 

 

This is the code I am using for sending the values to the DAC (shortened it to just the important parts):

dma_buffer_dac1[0] = (COMMAND_SOFTWARE_RESET >> 16);

dma_buffer_dac1[1] = 0;

dma_buffer_dac1[2] = 0 ;

LL_SPI_StartMasterTransfer(DACX->spi); // sets CSTART bit of SPI

LL_DMA_EnableStream(DACX->xdma_tx); // sets EN bit of DMA

while (DACX1_DMA_TX_CHECK_TC_ACTIVE == 0) {} // wait until DMA transfer complete

//Reset transmission flags

LL_DMA_ClearFlag_TC1(DACX1_DMA);

LL_DMA_ClearFlag_HT1(DACX1_DMA);

LL_DMA_ClearFlag_FE1(DACX1_DMA);

while (!LL_SPI_IsActiveFlag_EOT(DACX1.spi){} // wait for SPI End of Transfer

LL_SPI_ClearFlag_EOT(DACX1.spi);

 

 

Can anyone help my why the communication breaks?

I am not sure if the FEIF is the problem here, but I am also interested why the FEIF error is showing up?

1 REPLY 1
TDK
Guru

Here are the possibilities:

TDK_0-1739282416570.png

 

What else is going on in your program that is using the DMA, particular at same/higher priority levels?

What are the values of the DMA registers when the error occurs?

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