2021-02-16 04:39 AM
Hi,
I have an application created with TouchGFX 4.13 and STM32CubeIDE 1.4 on an STM32F750Z8. It was not running very well from erxternal RAM so I decided to change to the STM32F767ZI with enough internal falsh to store the application. Also I changed to TouchGFX v4.16 and STM32CubeIDE 1.5.1. The board and configuration stayed almost the same but now the TouchGFX lib stops in DM_Interface::addToQueue after the first VSync. It looks like it tries to take a semapthore in touchgfx::OSWrappers::tryTakeFrameBufferSemaphore and afterwards calls TouchGFXGeneratedHAL::disableInterrupts. From that point I don't get any further ltdc line events any more, even if I remove the call to NVIC_DisableIRQ(LTDC_IRQn).
For curiosity I linked the programm against the old TouchGFX(v4.13). I know it will not really work with the generated files from TouchGFX Studio but at leats it didn't stop working at this point.
I also debugged the init code and ltdc, dma2d, gpios and the os are initialized correctly. Also the frame_buffer_sem and the vsync_queue are created. I haven't found any take or release semaphore calls outside of the lib.
What could be the reason, the lib is not able to get the semapthore, and why is it stopping the erverything else. Is there a handling to be done, if this happens?.
I appreciate any help, thank you.
Best regards
2021-02-16 10:43 PM
Perhaps to make it a bit more clear here is the code I added to the TouchGFXGeneratedHAL.cpp:
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
registerEventListener(*(Application::getInstance()));
setFrameBufferStartAddresses((void*)0x61000000, (void*)0x61040000, (void*)0x61080000);
}
void TouchGFXGeneratedHAL::configureInterrupts()
{
NVIC_SetPriority(DMA2D_IRQn, 9);
NVIC_SetPriority(LTDC_IRQn, 9);
}
void TouchGFXGeneratedHAL::enableInterrupts()
{
NVIC_EnableIRQ(DMA2D_IRQn);
NVIC_EnableIRQ(LTDC_IRQn);
}
void TouchGFXGeneratedHAL::disableInterrupts()
{
NVIC_DisableIRQ(DMA2D_IRQn);
NVIC_DisableIRQ(LTDC_IRQn);
}
void TouchGFXGeneratedHAL::enableLCDControllerInterrupt()
{
lcd_int_active_line = (LTDC->BPCR & 0x7FF) - 1;
lcd_int_porch_line = (LTDC->AWCR & 0x7FF) - 1;
/* Sets the Line Interrupt position */
LTDC->LIPCR = lcd_int_active_line;
/* Line Interrupt Enable */
LTDC->IER |= LTDC_IER_LIE;
}
uint16_t* TouchGFXGeneratedHAL::getTFTFrameBuffer() const
{
return (uint16_t*)LTDC_Layer1->CFBAR;
}
void TouchGFXGeneratedHAL::setTFTFrameBuffer(uint16_t* adr)
{
LTDC_Layer1->CFBAR = (uint32_t)adr;
/* Reload immediate */
LTDC->SRCR = (uint32_t)LTDC_SRCR_IMR;
}
void HAL_LTDC_LineEventCallback(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();
}
}
HAL_LTDC_LineEventCallback is called from the HAL_LTDC_IRQHandler, which is called from LTDC_IRQHandler. But I only hit this function once. After leaving the ISR TouchGFXGeneratedHAL::disableInterrupts is called fromDMA_Interface::addToQueue . The call stack doesn't give me information from where this function is called but my guess is, it is done by one of the tick handlers. Even if I comment out the NVIC_DisableIRQ calls inside the TouchGFXGeneratedHAL::disableInterrupts function I don't get any further LTDC interrupts.