Indu
Indu

Reputation: 123

STM32H7 SPI DMA transfer, always in busy transfer state, HAL_SPI_STATE_BUSY_TX

I am trying to transfer the data in SPI using DMA, where as my Hal status is HAL_SPI_STATUS_BUSY_TX. The required status is HAL_SPI_STATE_READY. I want to send some bulk data and command(single byte) through SPI. Is it possible to switch between DMA and non DMA mode respectively. As shown in the image, it loops in the while. enter image description here

hdma1_tx.Instance                 = DMA1_Stream7;
hdma1_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
hdma1_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
hdma1_tx.Init.MemBurst            = DMA_MBURST_INC4;
hdma1_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
hdma1_tx.Init.Request             = DMA_REQUEST_SPI1_TX;
hdma1_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
hdma1_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
hdma1_tx.Init.MemInc              = DMA_MINC_ENABLE;
hdma1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma1_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
hdma1_tx.Init.Mode                = DMA_NORMAL;
hdma1_tx.Init.Priority            = DMA_PRIORITY_LOW;

if(HAL_DMA_Init(&hdma1_tx) != HAL_OK)
{
  // Error
}

/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmatx, hdma1_tx); 

/* Configure the DMA handler for Transmission process */
hdma_rx.Instance                 = DMA1_Stream1;
hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
hdma_rx.Init.Request             = DMA_REQUEST_SPI1_RX;
hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode                = DMA_NORMAL;
hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;

HAL_DMA_Init(&hdma_rx);

/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmarx, hdma_rx);

/*##-4- Configure the NVIC for DMA #########################################*/ 
/* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn); 

HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);

HAL_STATUS must be HAL_SPI_STATE_READY.

My data length is loaded in NDTR. enter image description here

After SPI enabled NDTR = 0x00

enter image description here

Upvotes: 6

Views: 5071

Answers (2)

Indu
Indu

Reputation: 123

I changed the TX DMA stream from DAM1_Stream7 to DMA1_Stream2, It got solved. Do not know root cause why not working at stream7.

Upvotes: 2

Hossam Alzomor
Hossam Alzomor

Reputation: 181

One reasone which could cause such problem is that the Variable which stores data to be sent is placed in the wrong RAM reigon, review you map file and modify linker script

you can find more here https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

Upvotes: 1

Related Questions