2025-04-07 4:53 AM
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
Solved! Go to Solution.
2025-04-08 1:44 AM
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:
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
2025-04-07 5:08 AM
On debugging Hard Faults:
2025-04-07 5:54 AM
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
2025-04-07 6:27 AM
So you need to initialise a brightness timer.
Looks like the BSP is doing that with a hardware timer...
2025-04-07 7:04 AM
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
2025-04-08 1:44 AM
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:
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
2025-04-08 1:59 AM
@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