cancel
Showing results for 
Search instead for 
Did you mean: 

Partial framebuffer screen block Update problem on a custom board with SPI LCD and no TE pin

hqMicro
Associate

Hi Community!

I worked with TouchGFX for last few years but this is my first attempt with partial faramebuffer strategy.

The MCU is STM32G0B1CBT, TouchGFX 4.24.1 and The LCD is 240x320 with ili9341 driver

Screenshot 2025-01-15 155823.jpg

I'm simulating the TE pin in systick to make the engine working. not sure if i'm doing it right

 

if (frame_tick_ms > 0) {
		  frame_tick_ms--;
		  if (frame_tick_ms == 0) {
			  v_sync = v_sync ? false : true;
			  if (v_sync) {
				frame_tick_ms = 85;
				VSYNC_Rising_Callback();
			  }
			  else {
				frame_tick_ms = 5;
				VSYNC_Falling_Callback();
			  }
		  }
	  }

 

 

I tryed to follow the G071 example code. The LCD is up and working and i'm able to fill it with color before the GUI starts. But after that i'm facing this on my display and can't figure out where is the problem.

photo_2025-01-15_15-45-34 - Copy.jpg

 

 

 

 

 

 

 

 

It's looks like the framework doesn't sending the whole blocks and after a few lines it's stops till next transmition.

Thanks in advance!

4 REPLIES 4
GaetanGodart
ST Employee

Hello @hqMicro ,

 

Can you try without the TE pin implementation?
I mean, is it possible for you to check that the partial framebuffer works and only after that you will implement the tearing effect?

Can you explain what "v_sync = v_sync ? false : true;" is doing? To me it looks like it is just toggling the value so it is like "v_sync = !v_sync;" which is probably not what you want.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Hello @GaetanGodart and thanks for your attention,

 


Can you try without the TE pin implementation?

 For this i disabled the parameter in CubeMX 

Screenshot 2025-01-17 142704.jpg

then in systick timer

if (frame_tick_ms++ > 80) {
    frame_tick_ms = 0;
    touchgfxSignalVSync();
}

 I'm getting same result.

 


Can you explain what "v_sync = v_sync ? false : true;" is doing? To me it looks like it is just toggling the value so it is like "v_sync = !v_sync;" which is probably not what you want.


That i see now is a confusing naming. it's just a variable that i used to simulate TE Rising and Falling interrupt callbacks. The whole usage is like this:

volatile int frame_tick_ms = 85;
volatile bool v_sync;
void VSYNC_Rising_Callback();
void VSYNC_Falling_Callback();
/* USER CODE END 4 */

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM6 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM6) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  if (htim->Instance == TIM6) {
     
   if (frame_tick_ms > 0) {
     frame_tick_ms--;
     if (frame_tick_ms == 0) {
        v_sync = v_sync ? false : true;
        if (v_sync) {
            frame_tick_ms = 85;
            VSYNC_Rising_Callback();
        }
        else {
            frame_tick_ms = 5;
            VSYNC_Falling_Callback();
        }
    }
  }
  /* USER CODE END Callback 1 */
}

and the Callback names are just renaming the EXTI callback functions:

//void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
//{
//  UNUSED(GPIO_Pin);
void VSYNC_Rising_Callback() {
...
}

//void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
//{
//  UNUSED(GPIO_Pin);
void VSYNC_Falling_Callback() {
...
}

 

After some trial and errors , i found out that the framebuffer blocks are filled with data by framework and i'm able to send them to display by modifying the following function like this:

void Display_Bitmap(const uint16_t *bitmap, uint16_t posx, uint16_t posy, uint16_t sizex, uint16_t sizey)
{
  uint8_t rem = posy % 80;
	if (rem == 0)
	{
		sizey += 140;
	}
	else {
		if (posy == 120) {
			sizey += 60;
		}
	}

  IsTransmittingBlock_ = 1;
  __HAL_SPI_ENABLE(&hspi1); // Enables SPI peripheral
...
}

by this i have to invalidate the whole screen every time for any changes and the last block of old framebuffer data will be visible very shortly. Please find the atteched video 

 

Thank you @cb.7 .Actually, I found that link at first but realized that the TouchGFX Demo also implemented all those parts with better performance in mind, so I decided to go with the demo one. Maybe there is something that i missed or something that needs to be fixed :)