2017-04-28 05:38 AM
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-dma2018-02-12 06:59 AM
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.