2021-10-13 05:33 PM
Hello @Romain DIELEMAN , @Martin KJELDSEN, I see that you have a lot of replies on the TouchGFX so I hope it's ok that I address you directly. I am running a low-power application with a DSI display and TouchGFX 13 (will update to latest eventually). The problem that I have is that I cannot bring the display out of power off mode without deleting and re-creating the TouchGFX task. My ideal approach would be to simply stop the tick (seem like the suggestion for this is to stop LTDC interrupt via __HAL_LTDC_DISABLE(&hltdc); / __HAL_LTDC_ENABLE(&hltdc). I've also tried touchgfx::HAL::getInstance()->disableInterrupts(); / touchgfx::HAL::getInstance()->enableInterrupts();. But it seems like whenever the interrupts are stopped, I am unable to get the tick running again - DSI_IRQHandler stoppes triggering.
My display power-off consists simply of issuing required DSI commands, then pulling power to the supply. Upon power-on I can tell that the display is active, but is not being refreshed by the application. If I delete and recreate the TouchGFX task in RTOS, this is resolved, but I believe there should be a way to kick start the application without needing to re-init the task. I suppose the main question is, how to restart Vsync / DSI interrupts after they've been disabled. Any thoughts on this would be very much appreciated.
Solved! Go to Solution.
2021-10-13 06:28 PM
Solved - I had to add the following after display re-initialization:
LCD_force_refresh();
LCD_ReqTear();
2021-10-13 05:40 PM
Code that is currently used to suspend / resume display operation:
void GRAPHICS_Suspend(void)
{
if(gui_state & GUI_STATE_INITALIZED)
{
if(gui_state & (GUI_STATE_ACTIVE | GUI_STATE_IDLE))
{
gui_state = (GUI_STATE_INITALIZED | GUI_STATE_SUSPENDED);
//issue CTP and display sleep commands and power off:
display_suspend();
/* Stop and then deInitialize the Touch Screen Controller */
BSP_TS_ITClear();
BSP_TS_DeInit();
// Disable DSI interrupts to stop screen refreshing
touchgfx::HAL::getInstance()->disableInterrupts();
__HAL_LTDC_DISABLE(&hltdc);
//disable touch interrupt
gpio_disable_interrupt(DISPLAY_INT_N_Pin);
//display_suspend();
// Delete GUI task
// vTaskDelete(m_gui_task);
// m_gui_task = NULL;
Log(DISPLAY, "Graphics suspended");
RESET_LOW_POWER_INHIBIT(LPIF_DISP_ACTIVE);
}
else
{
Log(DISPLAY, "Graphics already suspended");
}
}
else
{
Log(DISPLAY, "Graphics not initialized");
}
}
void GRAPHICS_Resume(void)
{
if(gui_state & GUI_STATE_INITALIZED)
{
// Make sure GFX are not suspended and OSPI is in memory mapped mode
if(!(gui_state & GUI_STATE_ACTIVE) && ospi_mem_mapped_enable(true))
{
if(gui_state & GUI_STATE_IDLE)
{
display_exit_idle();
}
else if(gui_state & GUI_STATE_SUSPENDED)
{
//set sleep inhibit flag
SET_LOW_POWER_INHIBIT(LPIF_DISP_ACTIVE);
// Set touch screen interrupt callback
gpio_enable_interrupt(DISPLAY_INT_N_Pin);
// Re-enable DSI interrupts to resume screen refresh
touchgfx::HAL::getInstance()->enableInterrupts();
__HAL_LTDC_ENABLE(&hltdc);
display_resume();
// Create GUI task
// if (pdPASS != xTaskCreate(gui_task,
// "GUI",
// GUI_STACK_SIZE,
// NULL,
// GUI_PRIORITY,
// &m_gui_task))
// {
// Error_Handler(GUI_ERROR);
// }
// Force display refresh in case where display is uninitialized and then reinitialized
// STM32HAL_DSI::forceRefresh();
Log(DISPLAY, "Graphics resumed");
}
gui_state = (GUI_STATE_ACTIVE | GUI_STATE_INITALIZED);
reset_gui_timer();
}
else
{
Log(DISPLAY, "Graphics already active");
}
}
else
{
Log(DISPLAY, "Graphics not initialized");
}
}
void display_resume(void)
{
uint8_t ScanLineParams[2];
uint16_t scanline = (GFXMMU_LCD_SIZE - 10);
LCD_PowerOn();
//switch to command bank 07h, set mfg config
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x07);
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x15, 0x04);
//switch to command bank 00h (user)
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x00);
// HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, DSI_SET_TEAR_ON, 0x00);
//Default settings changed for TouchGFX
// Set tear off
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, DSI_SET_TEAR_OFF, 0x00); // 0x34 -> 0x00
/* Set DSI mode to internal timing added vs ORIGINAL for Command mode */
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xC2, 0x00);
//End Default settings changed for TouchGFX
//Set column address
uint8_t InitParam1[4] = { 0x00, 0x0C, 0x01, 0xD1 };
HAL_DSI_LongWrite(&hdsi, 0, DSI_DCS_LONG_PKT_WRITE, 4, DSI_SET_COLUMN_ADDRESS, InitParam1);
//Set row address
uint8_t InitParam2[4] = { 0x00, 0x00, 0x01, 0xC5 };
HAL_DSI_LongWrite(&hdsi, 0, DSI_DCS_LONG_PKT_WRITE, 4, DSI_SET_PAGE_ADDRESS, InitParam2);
//Set display brightness to max - 0xFF
HAL_DSI_ShortWrite(&hdsi, 0, DSI_GEN_SHORT_PKT_WRITE_P2, 0x51, 0xFF);
//Exit sleep mode
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, DSI_EXIT_SLEEP_MODE, 0x00);
HAL_Delay(50);
//Turn Display On
if (HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, DSI_SET_DISPLAY_ON, 0x00) != HAL_OK)
{
Error_Handler(GUI_ERROR);
}
ScanLineParams[0] = scanline >> 8;
ScanLineParams[1] = scanline & 0x00FF;
HAL_DSI_LongWrite(&hdsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, DSI_SET_TEAR_SCANLINE, ScanLineParams);
//re-init the CTP
int nb_tries = 5;
/* Initialize the Touch Screen Controller */
while (nb_tries > 0)
{
if (BSP_TS_Init(GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT) == TS_OK)
{
/* Enable TS interrupt */
if (BSP_TS_ITConfig() != TS_OK)
{
Error_Handler(GUI_ERROR);
}
break;
}
nb_tries--;
}
if (nb_tries <= 0)
{
Error_Handler(GUI_ERROR);
}
}
void display_suspend()
{
//turn off all pixels
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x22, 0x00);
//turn off display
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, DSI_SET_DISPLAY_OFF, 0x00);
//enter sleep mode
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, DSI_ENTER_SLEEP_MODE, 0x00);
//turn off display power
LCD_PowerOff();
}
2021-10-13 06:28 PM
Solved - I had to add the following after display re-initialization:
LCD_force_refresh();
LCD_ReqTear();
2021-10-14 04:57 AM
Good to hear you made it work and thanks for sharing your code + fix :thumbs_up:
/Romain
2022-12-06 02:36 PM
Dear @KDubo
It seems that I'm facing a very similar issue! See https://community.st.com/s/feed/0D53W00001yzBQ8SAM
We are using the STM32F79 -- which MCU are you using?
We are not using TouchGFX, so I don't know what LCD_force_refresh(); and LCD_ReqTear(); does, could you share the code please?
Also what's the difference in your code between display suspend/resume and graphics suspend/resume?
In our case we are only displaying images or playing video, which works great. Our issue is really focused on going into STOP MODE and waking up with a working system.
Any help would be greatly appreciated :)