cancel
Showing results for 
Search instead for 
Did you mean: 

How to set LCD brightness in STM32U5G9J-DK2 board

Louie88
Senior

I have a new STM32U5G9J-DK2 board. I have to port an application running on STM32H747I-DiSCO board.

I have a big problem with setting brightness in the new board. In STM32H747I-DiSCO app I used:

extern "C"
{
	void LCD_SetBrightness(int value);
}

The LCD_SetBrightness() function is implemented in TouchGFXHAL.cpp file for the H7 processor. The same thing does not work with U5 processor because the TouchGFXHAL.cpp file does not contain the LCD_SetBrightness() function.

So, the question is how I can set the LCD brightness in STM32U5G9J-DK2 board.

I tried using the brightness control implemented in Board Support Package but calling BSP_LCD_SetBrightness(0, 50)  (50% brightness) causes Hard_Fault() interrupt... Nice!

Can somebody help? Thanks,

Louis

 

1 ACCEPTED SOLUTION

Accepted Solutions
Louie88
Senior

Hi Andrew,

Finally I solved the issue. Here is a possible solution if anybody else would run into the same issue...

I checked the schematic, and I found that PE6 GPIO pin controls the backlight input of the LCD Module:

LCD Brightness Control.pngLCD Brightness Control PE6.png

The PE6 GPIO can be programmed as PWM output of TIMER3's CHANNEL 4. So, all I had to do is to setup TIMER3 CHANNEL 4 in PWM mode and set the pulse width between 0% and 100% to turn off and on the backlight of the LCD Module. Configuring Timer 3 can be done in STM32CubeMX app.

To control the brightness call the setBrightness(brightnessValue) from (say) Model.cpp:

/**
 * @Brief Sets PWM value in Timer3 between 1 and 100% to control brightness of LCD module
 * @PAram value The brightness between 0 and 100 (percentage)
 */
void Model::setBrightness(uint32_t value)
{
	// If TIM3.CC4 = TIM3.ARR then LCD brightness = 100%
	// If TIM3.CC4 = TIM3.ARR / 2 then LCD brightness = 50%
	// If TIM3.CC4 = 0 then LCD brightness is turned off
	int width = ((hlcd_tim.Instance->ARR + 1) * value / 100) - 1;
	if (width < 0)
		width = 0;
	else if (width > (int)hlcd_tim.Instance->ARR)
		width = hlcd_tim.Instance->ARR;
	hlcd_tim.Instance->CCR4 = (uint32_t)width;
}

This works very well, and it is a quite simple solution, I think.

Louis

 

View solution in original post

6 REPLIES 6

On debugging Hard Faults:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/tac-p/708193/highlight/true#M51

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Hi Andrew,

Thanks, but I am lucky, exactly know what cause the HW fault interrupt.

int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness)
{
  int32_t ret = BSP_ERROR_NONE;

  if (Instance >= LCD_INSTANCES_NBR)
  {
    ret = BSP_ERROR_WRONG_PARAM;
  }
  else
  {
    __HAL_TIM_SET_COMPARE(&hlcd_tim, LCD_TIMx_CHANNEL, 2U * Brightness);
    Lcd_Ctx[Instance].Brightness = Brightness;
  }

  return ret;
}

The BSP_LCD_SetBrightness() is implemented in stm32u5g9j_discovery_lcd.c. The problem is that hlcd_tim.Instance = 0x0, which means the handle for brightness timer is not initialized this row:

in __HAL_TIM_SET_COMPARE(&hlcd_tim, LCD_TIMx_CHANNEL, 2U * Brightness);

Okay, but why?

Thanks,

Louis

 

So you need to initialise a brightness timer.

Looks like the BSP is doing that with a hardware timer...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Hi Andrew,

Yes, with Timer 3. The BSP_LCD_Init() initializes Timer 3. But I cannot call BSP_LCD_Init() because TouchGFX already initializes the LCD. Calling BSP_LCD_Init() while TouchGFX is used blows up the display.

There must be a TouchGFX compatible brigthess cntrol function somewhere in the code but it is a challenge to find that.

I thought that somebody alraedy solved this problem.

This is very weird, like the STM32U5G9J-DK2 board does not have SD Card socket. Watch out when ordering this DK board...

Louis

Louie88
Senior

Hi Andrew,

Finally I solved the issue. Here is a possible solution if anybody else would run into the same issue...

I checked the schematic, and I found that PE6 GPIO pin controls the backlight input of the LCD Module:

LCD Brightness Control.pngLCD Brightness Control PE6.png

The PE6 GPIO can be programmed as PWM output of TIMER3's CHANNEL 4. So, all I had to do is to setup TIMER3 CHANNEL 4 in PWM mode and set the pulse width between 0% and 100% to turn off and on the backlight of the LCD Module. Configuring Timer 3 can be done in STM32CubeMX app.

To control the brightness call the setBrightness(brightnessValue) from (say) Model.cpp:

/**
 * @Brief Sets PWM value in Timer3 between 1 and 100% to control brightness of LCD module
 * @PAram value The brightness between 0 and 100 (percentage)
 */
void Model::setBrightness(uint32_t value)
{
	// If TIM3.CC4 = TIM3.ARR then LCD brightness = 100%
	// If TIM3.CC4 = TIM3.ARR / 2 then LCD brightness = 50%
	// If TIM3.CC4 = 0 then LCD brightness is turned off
	int width = ((hlcd_tim.Instance->ARR + 1) * value / 100) - 1;
	if (width < 0)
		width = 0;
	else if (width > (int)hlcd_tim.Instance->ARR)
		width = hlcd_tim.Instance->ARR;
	hlcd_tim.Instance->CCR4 = (uint32_t)width;
}

This works very well, and it is a quite simple solution, I think.

Louis

 


@Louie88 wrote:

Finally I solved the issue. Here is a possible solution if anybody else would run into the same issue...


Great!

To help people to find it, please mark that as the solution:

https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.