cancel
Showing results for 
Search instead for 
Did you mean: 

touchgfx::HAL::getInstance()->taskEntry() stucks on a infinite loop

Fernando Cola
Associate II

Hello, i'm trying to bring up a custom board using STM324F29BI and I'm having problems on on the Touchgfx task.

I used CubeMX to generate a base code for my board and everything seems fine on the BSP part.

For some reason, when I try to use touchgfx::HAL::getInstance()->taskEntry(), the code gets stuck on Default_Handler.

I did tried to increase the stack size for the TouchGFX task but I get the same result.

Any ideas where should I look?

Thanks!

9 REPLIES 9
hansd56
Senior II

Hi Fernando, what is your display size. I have the same problem using a STM32F46 and an 800x480 display.

Yes I'm using an 800x480 display. Did you reduced the resolution and got any leads? I will try on my board.​

U​sing 800×480 resolution I'm able to change to set the content displayed on the scream by disabling any Touchgfx calls and writing directly on the framebuffer memory. So this indicate to me that the display and FMC are properly working. Now if I enable the Touchgfx the system goes to a Defaul Handler interrupt.

Fernando Cola
Associate II

Update

I did found that I wasn't enabling LTDC and DMA interrupts during HAL_LTDC_MspInit and HAL_DMA2D_MspInit. I enabled them but I keep having the same problem of running on a Infinite Loop.

I notice now that my program is going to default handler after GPIO::init() under GRAPHICS_HW_Init. Checking the ISR of LTDC I noticed that I'm having FIFO underrun Interrupt flag.

0690X000008jC28QAE.png

I found this article: https://touchgfx.zendesk.com/hc/en-us/articles/205676691-Debugging-Pixel-Error-Issues that refers to a similar error. I've tried to reduce the LTDC clock by a factor of 4 and my code progress a little and stops again on a infinite loop but now the ISR indicates an Line Interrupt Flag.

0690X000008jC2rQAE.png

Any ideas on how to progress from here?

Thank you

hansd56
Senior II

I have a 480x272 which I am going to try in due course. TouchGFX enables all interrupts at startup. Also be aware that TouchGFX keeps 3 buffers. Please let me know when you have found a solution.

Fernando Cola
Associate II

Update 2

Debugging the code, I found that the generated HAL_LTDC_LineEvenCallback was never called by LTDC Interrupt.

extern "C" void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc)
{
    if (LTDC->LIPCR == lcd_int_active_line)
    {
        //entering active area
        HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_porch_line);
        HAL::getInstance()->vSync();
        OSWrappers::signalVSync();
        // Swap frame buffers immediately instead of waiting for the task to be scheduled in.
        // Note: task will also swap when it wakes up, but that operation is guarded and will not have
        // any effect if already swapped.
        HAL::getInstance()->swapFrameBuffers();
        GPIO::set(GPIO::VSYNC_FREQ);
    }
    else
    {
        //exiting active area
        HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_active_line);
        GPIO::clear(GPIO::VSYNC_FREQ);
        HAL::getInstance()->frontPorchEntered();
    }
}

So add manually the following Handler:

extern "C" void LTDC_IRQHandler(void)
{
    if (LTDC->ISR & 1)
    {
        LTDC->ICR = 1;
 
    if (LTDC->LIPCR == lcd_int_active_line)
    {
        //entering active area
        HAL_LTDC_ProgramLineEvent(&hltdc, lcd_int_porch_line);
        HAL::getInstance()->vSync();
        OSWrappers::signalVSync();
        // Swap frame buffers immediately instead of waiting for the task to be scheduled in.
        // Note: task will also swap when it wakes up, but that operation is guarded and will not have
        // any effect if already swapped.
        HAL::getInstance()->swapFrameBuffers();
        GPIO::set(GPIO::VSYNC_FREQ);
    }
    else
    {
        //exiting active area
        HAL_LTDC_ProgramLineEvent(&hltdc, lcd_int_active_line);
        GPIO::clear(GPIO::VSYNC_FREQ);
        HAL::getInstance()->frontPorchEntered();
    }
}

Now the when I start the debugging session I get to see the handler being called. But when I let the program run the it stops again in the Default_Handler:

.section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler
/**********************************************

eng23
Senior

Hi @Fernando Cola​ ,

Did you find a solution for this?

I'm in the same situation, I get HardFault_Handler() when executing GRAPHICS_MainTask().

I've checked the interrupts for LTDC and DMA and they are corrects. The display shows the very first screen properly, but imediately after CPU runs to HardFault_Handler().

Any tip for this?

Regards.

Hi, I did found that the Interrupt Handler for LTDC was not beeing called.

I to change the following code:

extern "C" void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc)
{
    if (LTDC->LIPCR == lcd_int_active_line)
    {
        //entering active area
        HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_porch_line);
        HAL::getInstance()->vSync();
        OSWrappers::signalVSync();
        // Swap frame buffers immediately instead of waiting for the task to be scheduled in.
        // Note: task will also swap when it wakes up, but that operation is guarded and will not have
        // any effect if already swapped.
        HAL::getInstance()->swapFrameBuffers();
        GPIO::set(GPIO::VSYNC_FREQ);
    }
    else
    {
        //exiting active area
        HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_active_line);
        GPIO::clear(GPIO::VSYNC_FREQ);
        HAL::getInstance()->frontPorchEntered();
    }
}

to:

extern "C" void LTDC_IRQHandler(void)
{
    if (LTDC->ISR & 1)
    {
        LTDC->ICR = 1;
 
    if (LTDC->LIPCR == lcd_int_active_line)
    {
        //entering active area
        HAL_LTDC_ProgramLineEvent(&hltdc, lcd_int_porch_line);
        HAL::getInstance()->vSync();
        OSWrappers::signalVSync();
        // Swap frame buffers immediately instead of waiting for the task to be scheduled in.
        // Note: task will also swap when it wakes up, but that operation is guarded and will not have
        // any effect if already swapped.
        HAL::getInstance()->swapFrameBuffers();
        GPIO::set(GPIO::VSYNC_FREQ);
    }
    else
    {
        //exiting active area
        HAL_LTDC_ProgramLineEvent(&hltdc, lcd_int_active_line);
        GPIO::clear(GPIO::VSYNC_FREQ);
        HAL::getInstance()->frontPorchEntered();
    }
    }
}

See if it works!

Best Regards

If you're hitting the default handler there's something in the startup script (.s) that isn't mapping correctly to an interrupt handler. Double check your entries and see if you're actually calling the LTDC interrupt handler from the right spot in the interrupt vector table.

/Martin

eng23
Senior

Hi,

Thanks for supporting!

I could verify that the HardFault_Handler is generated when I enable I2C peripheral for touchscreen. If I comment touchscreen init the LCD works fine.

There is something bad in I2C interrupts that I'm looking for.

Thanks!

Regards.