cancel
Showing results for 
Search instead for 
Did you mean: 

Re-enabling TX DMA of SPI cause wrong transmit unit (STM32F407ZET6)

thisdp
Associate II

I am working on STM32F407ZET6 with DMA+SPI in slave mode. Trying to reset DMA Counter when NSS is high to avoid shifted data transmit.

TX and RX DMA are working on Circular mode.

This is my tx data

 

typedef struct {
  uint8_t InputState[4];
  uint8_t reserved1[4];
  uint8_t reserved2[4];
  uint8_t reserved3[4];
} SyncDataTX;

 

 Inside init function, i did

 

*((uint32_t*)(txData.InputState)) = 0x11121314;
*((uint32_t*)(txData.reserved1)) = 0x15161718;
*((uint32_t*)(txData.reserved2)) = 0x19202122;
*((uint32_t*)(txData.reserved3)) = 0x23242526;
HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)&txData, (uint8_t *)&rxData, sizeof(txData));

 

Inside interrupt function, i did

 

__HAL_DMA_DISABLE(&hdma_spi1_rx);
__HAL_DMA_DISABLE(&hdma_spi1_tx);
__HAL_DMA_SET_COUNTER(&hdma_spi1_rx,sizeof(SyncDataTX));
__HAL_DMA_SET_COUNTER(&hdma_spi1_tx,sizeof(SyncDataTX));
__HAL_DMA_ENABLE(&hdma_spi1_rx);
__HAL_DMA_ENABLE(&hdma_spi1_tx);

 

In the first transaction, I get this, which is correct data:

 

11121314
15161718
19202122
23242526

 

In the second transaction, I get this:

 

12131414
16171811
20212215
24252619

 

From the third transaction, I start to getting this:

 

12131423
16171811
20212215
24252619

 

 

This happens even only:

__HAL_DMA_DISABLE(&hdma_spi1_tx);
__HAL_DMA_ENABLE(&hdma_spi1_tx);

 

:thinking_face:I didn't encounter such problem in STM32H750

11 REPLIES 11
thisdp
Associate II

this makes sense. I will try your solution.

But I'm still confused that why the problem is still there even only do this

 __HAL_DMA_DISABLE(&hdma_spi1_tx);
__HAL_DMA_ENABLE(&hdma_spi1_tx);

 

thisdp
Associate II

I was thinking that DMA starts to transfer data to DR only when NSS is low :thinking_face: which was wrong.

It seems that DMA starts to transfer data to DR when DR is empty

Actually there's no need to stop and restart SPI. My solution is overwriting the first byte in DR, and let DMA transfer the remaining bytes ( startPointer+1 to totalLength-1 )

 

 

	__HAL_DMA_DISABLE(&hdma_spi1_tx);
	__HAL_DMA_SET_COUNTER(&hdma_spi1_tx,SyncSize-1);
	(&hspi1)->Instance->DR = *((uint8_t*)((&hspi1)->pTxBuffPtr));
	(&hdma_spi1_tx)->Instance->M0AR = (uint32_t)((&hspi1)->pTxBuffPtr+1);
	__HAL_DMA_ENABLE(&hdma_spi1_tx);

 

 

Thanks for help. :D