cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f105rc : SPI DMA Transmit problem for first transaction

Benjamin BOST
Associate
Posted on April 28, 2017 at 14:38

Hi all,

I'm working with an stm32f105rc which communicate with a radio chip (DW1000 but doesn't matter ^^ ).

The communication between the two chips is done thanks to an SPI link and it works well. I use the code generated by STM32CubeMx. So, each time I wanted to transmit datas to the chip, I used the HAL (version 1.4) funtion :

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);

Now, because I have my reasons, i need to use SPI DMA to transmit my datas. So, I've configured the SPi DMA like the STM32CubeMx code but I have a problem. The insterresting part is below :

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 

    HAL_Init();

 

 

    /* Configure the system clock */

 

    SystemClock_Config();

 

 

    /* Initialize all configured peripherals */

 

    MX_GPIO_Init();

 

    MX_DMA_Init();

 

    MX_SPI1_Init();

    uint8   buffer[4] ;

 

 

    buffer[0] =0x00;

 

    buffer[1] = 0x00;

 

    buffer[2] = 0x00;

 

    buffer[3] = 0x00;

      while(1){

           dma_spi_mutex = 1;

           HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,0);

           HAL_SPI_Transmit_DMA(&hspi1,buffer,4);

           while(dma_spi_mutex);

           HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,1);

         }

Here, we configure peripherals and then we send the same message in a loop thanks to HAL_SPI_Transmit_DMA.

 dma_spi_mutex is set to 0 in the SPI_DMATransmitCplt callback.

The problem is that the first HAL_SPI_Transmit_DMA(&hspi1,buffer,4) correctly goes in interupt dma handler for complete transfer but goes in the DMA Error callback. So the first transfer is not sent.

Now if I add a blocking transfer without DMA just before executing the same code, all DMA transfers are correct.

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 

    HAL_Init();

 

 

    /* Configure the system clock */

 

    SystemClock_Config();

 

 

    /* Initialize all configured peripherals */

 

    MX_GPIO_Init();

 

    MX_DMA_Init();

 

    MX_SPI1_Init();

    uint8   buffer[4] ;

 

 

    buffer[0] =0x00;

 

    buffer[1] = 0x00;

 

    buffer[2] = 0x00;

 

    buffer[3] = 0x00;

   

HAL_SPI_Transmit(&hspi1,buffer,1,100);

      while(1){

           dma_spi_mutex = 1;

           HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,0);

           HAL_SPI_Transmit_DMA(&hspi1,buffer,4);

           while(dma_spi_mutex);

           HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,1);

         }

Does anybody would have an explanation ?

Thank you for your answers .

#stm32-spi-dma
1 REPLY 1
kotekkc
Associate
Posted on February 12, 2018 at 15:59

I have same/similar issue with STM32L082 and HAL drivers v1.10.0

I need to call HAL_SPI_Transmit before calling HAL_SPI_Transmit_DMA.

Otherwise mcu will go into an infinite loop in SPI_DMATransmitCplt (line 2078) waiting for TXE flag, with this calltrace:

DMA1_Channel4_5_6_7_IRQHandler() -> HAL_DMA_IRQHandler() -> SPI_DMATransmitCplt() -> SPI_WaitOnFlagUntilTimeout()

If i call HAL_SPI_Transmit(&hspi2, '', 1, 1000), then the issue does not happen.