Skip to main content
KDubo
Associate II
October 14, 2021
Solved

TouchGFX DSI display, not coming out of standby mode.

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.

This topic has been closed for replies.
KDubo
KDuboBest answer
Associate II
October 14, 2021

Solved - I had to add the following after display re-initialization:

  LCD_force_refresh();

  LCD_ReqTear();

4 replies

KDubo
KDuboAuthor
Associate II
October 14, 2021

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();
}

KDubo
KDuboAuthorBest answer
Associate II
October 14, 2021

Solved - I had to add the following after display re-initialization:

  LCD_force_refresh();

  LCD_ReqTear();

Romain DIELEMAN
ST Employee
October 14, 2021

Good to hear you made it work and thanks for sharing your code + fix :thumbs_up:

/Romain

ladislas
Associate II
December 6, 2022

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 :)