Skip to main content
Visitor II
May 29, 2024
Question

SPI DMA Receiving buffer is not filled

  • May 29, 2024
  • 0 replies
  • 612 views

Hello,

I'm trying to setup a SPI communication through DMA but I can't receive data.

I use a STM32H7 microcontroller as a single master to reach a single slave. I would like to transmit 1 byte, and receive 1 byte in return. To start the transfer, I call the HAL function :

HAL_SPI_TransmitReceive_DMA(&hspi1, au8BufferTx, au8BufferRx, 1);

au8BufferTx and au8BufferRx are both 129 bytes big, which should be more than enough to transmit/receive 1 byte.

The DMA1_Stream2_IRQHandler() (I use DMA1_Stream2 to transmit) is first called when the byte is transmitted, then DMA1_Stream5_IRQHandler() (I use DMA1_Stream5 to receive) when a byte is received. As I undretsand it, it means that DMA transfers are completed. Then HAL_SPI_TxRxCpltCallback() is called. Though, the content of au8BufferRx is never updated. Any idea on what is happening there ?

Thank you for helping

More info :

  • Before trying to setup DMA, I used SPI with IT. Everything worked as expected. That's not a hardware problem on my platform.
  • I checked MISO and MOSI signals with a scope, they are as expected. That makes me think that the microcontroller receive the correct answer on MISO signal.
  • SPI1 status when entering HAL_SPI_TxRxCpltCallback() function

illmanta_0-1716995266216.png

Configuration :

SPI1 :

 hspi1.Instance = SPI1;
 hspi1.Init.Mode = SPI_MODE_MASTER;
 hspi1.Init.Direction = SPI_DIRECTION_2LINES;
 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi1.Init.CRCPolynomial = 0x0;
 hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
 hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
 hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
 hspi1.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
 hspi1.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
 hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_08CYCLE;
 hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
 hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
 hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
 hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
 if (HAL_SPI_Init(&hspi1) != HAL_OK)
 {
 Error_Handler();
 }

DMA :

 /* SPI1 DMA Init */
 /* SPI1_TX Init */
 hdma_spi1_tx.Instance = DMA1_Stream2;
 hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
 hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_spi1_tx.Init.Mode = DMA_NORMAL;
 hdma_spi1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);

 /* SPI1_RX Init */
 hdma_spi1_rx.Instance = DMA1_Stream5;
 hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
 hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_spi1_rx.Init.Mode = DMA_NORMAL;
 hdma_spi1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);

 

    This topic has been closed for replies.