cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F107VC SPI Interrupt mode does not call HAL_SPI_TxRxCpltCallback

Davide Dalfra
Associate III

Dear all

I have generated a test project via CubeMX, for STM32F107VC MCU for sending data as a MASTER SPI to a slave device (another STM32 device) by using Interrupt mode.

They system is running FreeRTOS 10 (tick on systick) and HAL (tick on TIM7).

TIM7 IRQ Priority is configured twice, first when called HAL_INIT (prio = 0) and later on after the SystemClock_Config is called (prio=16, the lowest).

When i start the transaction by calling HAL_SPI_TransmitReceive_IT i got only few transaction sent out and after those the HAL report the peripheral is still sending but in fact it's not.

By having a look at the SPI2 registers, TXE flag is raised high but the HAL_SPI_TxRxCpltCallback or HAL_SPI_ErrorCallback are never called.

If i run SPI2 in DMA mode, no issue are found (but i can't use DMA as the same DMA resource need to be used on a usart).

If i run SPI2 in Polling mode on a single task, no issue are found too.

This is how the SPI2 has been configured:

void MX_SPI2_Init(void)
{
 
  hspi2.Instance = SPI_VIS_INTERFACE;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(spiHandle->Instance==SPI_VIS_INTERFACE)
  {
 
    __HAL_RCC_SPI2_CLK_ENABLE();
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**SPI2 GPIO Configuration
    PB13     ------> SPI2_SCK
    PB14     ------> SPI2_MISO
    PB15     ------> SPI2_MOSI
    */
    
    GPIO_InitStruct.Pin = SPI_VIS_CLK_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(SPI_VIS_CLK_PORT, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin = SPI_VIS_MOSI_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(SPI_VIS_MOSI_PORT, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = SPI_VIS_MISO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(SPI_VIS_MISO_PORT, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin = SPI_VIS_CS_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(SPI_VIS_CS_PORT, &GPIO_InitStruct);
 
    HAL_NVIC_SetPriority(SPI2_IRQn,9,0);
    HAL_NVIC_EnableIRQ(SPI2_IRQn);
 
  }
}

MCU Core is running at 36MHz, and the SPI is clocking out at about 500KHz.

When transaction runs smooth, by debugging inside HAL i can see that after the HAL_SPI_ENABLE_IT all the SPI_IT_TXE, SPI_IT_RXNE, SPI_IT_ERR are enabled correctly.

When the first fails occur, HAL struct of SPI2 state is HAL_SPI_STATE_BUSY , but the most interesting thing is that the TXEIE is no longer enabled and i suspect this is the reason why the callback is not called anymore.

Is there any reason why the TXEIE remains set to 0, and not re-enabled?

P.s.: if i reduce the SPI speed by half, also in Interrupt mode the SPI can run smoothly.

For the images on Logic(Saleae):

 GPIO_13 is toggling each time it enters into the SPI2 isr.

Channel 4 is the clock, Channel 5 is MOSI and channel 6 is the CS.

The transaction is made by 429 byte.

4 REPLIES 4
Ons KOOLI
Senior III

Hi Davide Dalfra,

Can you please share your .ioc file ?

Best Regards,

Ons.

TDK
Guru

Set a hardware watchpoint on the TXEIE register and see what is changing it back.

If you feel a post has answered your question, please click "Accept as Solution".
 

Hi Davide,

Can you please explain how you use the code. Which code you download into your Master board, and which one you download into your Slave board?

Best Regards,

Ons.