Electronics > Beginners
STM32F4 SPI interrupts stop firing with FreeRTOS
MisterPatate:
Hello everybody ! :)
I'm trying to make an SPI communication between a F410 MCU and a RPi using SPI. I post below the code that currently works (without FreeRTOS usage):
main.c
--- Code: ---volatile int tx_done = 0;
volatile int rx_done = 0;
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
tx_done = 1;
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
rx_done = 1;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI5_Init();
MX_USART2_UART_Init();
const uint8_t BUF_SIZE = 16 * sizeof(uint8_t);
uint8_t buf[16];
// For UART debug
uint8_t dbg_buffer[64];
while (1) {
memset(buf, 0, BUF_SIZE);
HAL_StatusTypeDef ret = HAL_SPI_Receive_IT(&hspi5, (uint8_t*)&buf, BUF_SIZE);
while (rx_done == 0) {};
rx_done = 0;
sprintf((char*) dbg_buffer, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d]\r\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
buf[7], buf[8], buf[9], buf[10], buf[11], buf[12],
buf[13], buf[14], buf[15]);
HAL_UART_Transmit(&huart2, dbg_buffer, strlen((char const*) dbg_buffer), 50);
HAL_SPI_Transmit_IT(&hspi5, (uint8_t*) &buf, BUF_SIZE);
while (tx_done == 0) {};
tx_done = 0;
}
}
--- End code ---
stm32f4xx_it.c
--- Code: ---/**
* @brief This function handles TIM1 trigger and commutation interrupts and TIM11 global interrupt.
*/
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim11);
}
/**
* @brief This function handles SPI5 global interrupt.
*/
void SPI5_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi5);
}
--- End code ---
spi.c
--- Code: ---/* SPI5 init function */
void MX_SPI5_Init(void)
{
hspi5.Instance = SPI5;
hspi5.Init.Mode = SPI_MODE_SLAVE;
hspi5.Init.Direction = SPI_DIRECTION_2LINES;
hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi5.Init.NSS = SPI_NSS_HARD_INPUT;
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi5.Init.CRCPolynomial = 15;
if (HAL_SPI_Init(&hspi5) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
[...]
HAL_NVIC_SetPriority(SPI5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI5_IRQn);
}
--- End code ---
This is working fine with my test code on the other (raspberry pi) side, sending a SPI frame every second, waiting 100ms and reading the answer from the F410.
Now, when I activate FreeRTOS (I used CubeMX), I move the while(1) loop content to a task, and creates it with
--- Code: ---BaseType_t task1 = xTaskCreate(task1, "task1", 512, NULL, tskIDLE_PRIORITY, &xHandle);
--- End code ---
and osKernelStart(). I also use the TIM11 as Timebase Source (under SYS tab on CubeMX as advised by the software itself)
Then I have the following behavior: If I place breakpoints inside both Tx/Rx SPI interrupt, I found that a couple (3-4 ?) of them are fired, then never again. If I stop my code I see I'm stucked in the
--- Code: ---while (rx_done == 0) {};
--- End code ---
loop, confirming that I don't get SPI RX interrupts anymore whereas there is still frame coming on the SPI bus...
To dig a little into that theory, I made another test with this in my task:
--- Code: --- while(1) {
memset(buf, 0, 16);
HAL_StatusTypeDef ret = HAL_SPI_Receive_IT(&hspi5, (uint8_t*)&buf, 16);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
// Wait for RX interrupt, task is suspended to give processing time to (incoming) others tasks
vTaskSuspend(NULL);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}
--- End code ---
and in my Rx interrupt, I simply call
--- Code: ---xTaskResumeFromISR(task1Handle);
--- End code ---
With this code, the first packet sent is read correctly by the STM32F4, and task print it on USART2 and suspend itself again. From then, (checked with a breakpoint inside), the Rx interrupt is never called again, so the task resume inside neither, and my code is frozen...
It really looks like there is a messing between FreeRTOS and STM32 HAL SPI/interrupt handling ?
Any help will be gladly accepted !
MadScientist:
Is the smt32 Hal ( cubemx ) compatible with freeRTOS ? , I didn’t think it was
Dave
MisterPatate:
It is, I configurated FreeRTOS within the CubeMX app.
https://www.freertos.org/FreeRTOS-Plus/BSP_Solutions/ST/STM32Cube.html
AndyC_772:
It's always worth looking at the hardware registers for the peripherals involved. See how they're really set up, what's enabled and what isn't, and whether there are any error flags set which will prevent normal operation until they're cleared.
For example, if a UART Rx interrupt is never called, this could be because this interrupt is disabled in the NVIC, or the UART receive IE bit isn't set, or interrupts are globally disabled, or reception is disabled due to (say) a framing error.
Reading the hardware registers directly and comparing them against the descriptions in the Reference Manual is the only definitive way to tell. From there, you'll have a way to work backward and see exactly where an undesirable register change was made, and why.
MisterPatate:
Does those registers available in hspi struct ? I must use the HAL here, so just asking
Navigation
[0] Message Index
[#] Next page
Go to full version