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

TouchGFX DSI display, not coming out of standby mode.

  • October 14, 2021
  • 3 replies
  • 2816 views

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.
Best answer by KDubo

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

  LCD_force_refresh();

  LCD_ReqTear();

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