cancel
Showing results for 
Search instead for 
Did you mean: 

How to improve the speed of SPI-DMA operation. Basically I want to avoid waiting in while() after transfer of data.

JohnsAby
Associate II

I have a working code for SPI with DMA support added. Now I want to improve the speed of operation.

I am using an STM32F427 controller.

#define SPIx_Mode               SPI_MODE_MASTER
#define SPIx_Direction          SPI_DIRECTION_1LINE
#define SPIx_DataSize           SPI_DATASIZE_16BIT
#define SPIx_ClkPolarity        SPI_POLARITY_HIGH
#define SPIx_ClkPhase           SPI_PHASE_1EDGE
#define SPIx_Nss                SPI_NSS_SOFT
#define SPIx_BaudRatePrescaler  SPI_BAUDRATEPRESCALER_4
#define SPIx_FirstBit           SPI_FIRSTBIT_MSB
#define SPIx_TiMode             SPI_TIMODE_DISABLE
#define SPIx_CrcCalc            SPI_CRCCALCULATION_DISABLE
#define SPIx_CrcPolynomial      0

/* DMA configuration  */
  hdma_tx.Instance                 = SPIx_TX_DMA_STREAM;
  hdma_tx.Init.Channel             = SPIx_TX_DMA_CHANNEL;
  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
  hdma_tx.Init.Mode                = DMA_NORMAL;
  hdma_tx.Init.Priority            = DMA_PRIORITY_HIGH;
  hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
  hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;

Current working code

/* SPI Transmit function, which is a wrapper for SPI transfer using DMA */
void spi2_dataTransfer(uInt16 *TxBuffer, uInt8 size)
{
  HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, size);
  while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
  HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
}

above mentioned code is working fine, but the while condition is causing some delay.

I want to avoid it.

So, I use below code.

/* SPI Transmit function, which is a wrapper for SPI transfer using DMA */
void spi2_dataTransfer(uInt16 *TxBuffer, uInt8 size)
{
  HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, size);
  // while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
  // HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
}
 
// After successful transfer NSS is put high from HAL_SPI_TxCpltCallback.
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *SPIx_handle)
{
 HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
}

But this is not working. why ? please help

Edit : Issue resolved, above code is working. Unable to delete the post

1 REPLY 1
HDaji.1
Senior

Hi, May I know how much faster the callback way is than while loop?

I thought while loop is faster than callback.

I am using LL API to do SPI-DMA transmission. In my case, 2 or 3 bytes Tx or Rx takes about 10 micro-sec.

My MCU is F411, 100M clock. For SPI to Tx/Rx 3 bytes, under 10M speed, the delay should be around 1 micro-sec.