2024-05-23 05:11 AM
Hi,
I have defined a function, that when called, from the main.c while loop works fine. When the same function is called from an interrupt it fails to work.
In debug mode I can see that the interrupt function (void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) is called. My function is then called, but it no longer works as it did when called from the main while loop.
The context is the function, defined above, asks a LCD TFT display to do something. The LCD is controlled via SPI. DMA is enabled.
Is it the case that the interrupt would only "fire" once the SPI has finished its work? If it interrupts the current SPI communication would this be the problem?
I note also that I can alter global variables fine in the said function.
Any suggestions welcome.
Thanks in advance
2024-05-23 05:16 AM
sorry I forgot to add, Im using an STM32F373 MCU.
2024-05-23 06:18 AM
Hello @TombrownBottom
Try to set the interrupt priorities of DMA higher than the EXTI.
One common approach to handling such situations is to use a flag within the Callback to indicate that an event has occurred, and then in the main loop, check the flag and call the function:
volatile bool lcdUpdateRequired = false;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == YOUR_PIN)
{
lcdUpdateRequired = true;
}
}
int main(void)
{ // Initialization code...
while (1)
{ // Main loop code...
if (lcdUpdateRequired)
{ lcdUpdateRequired = false;
UpdateLCD(); // Function that communicates with the LCD
}
}
}
2024-05-23 06:31 AM
Thanks for your help.
See Pic.
When you say set the interrupt priorities of DMA higher than the EXTI do you mean as defined in the picture above?
I have changed the value in the priority field from low to very high. This has not resolved the issue.
2024-05-23 06:50 AM
The alternative to set a boolean and test for it in the main loop works. Thanks.
In the interest of minimising code and making it more "readable" im still interested to find out why my first approach does not work.
2024-05-23 07:00 AM
Would you provide a minimum example to replicate this issue?
2024-05-23 07:17 AM - edited 2024-05-23 07:19 AM
> In the interest of minimising code and making it more "readable" im still interested to find out why my first approach does not work.
My guess: the function you called is using some SysTick stuff, which in case of wrongly set interrupt priorities kills it.
SysTick needs the highest priority / higher than the interrupt in use, then it might work.
But it's bad design to overload an ISR anyway. Always get out of an ISR fast!
2024-05-23 07:20 AM
If you are trying to run time-consuming codes within the interrupt, it is normal for errors to occur.
Your function should specifically not contain any delays and should not take more than a few lines. Long codes may conflict with other interrupts and cause errors.
2024-05-23 09:03 AM
Here is my code:
The interrupt:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)// interrupt routine works!
{
if(GPIO_Pin == GPIO_PIN_0)
{
update();
}
else if (GPIO_Pin == GPIO_PIN_7)
{
interrupt2 = true;
}
else
{
__NOP();
}
}
The update function:
void update(void)
{
itoa(number, text, 10);//function to convert the int into a string (3rd argument 10 = base 10)
ILI9341_DrawText(text, FONT4, 4 + pitchX, 2, YELLOW, BLACK);
ILI9341_DrawText(text, FONT4, 4 + pitchX, 47, YELLOW, BLACK);
}
When I run this in debug mode, all the arguments for the ILI9341_DrawText function are present as expected