diff --git a/epicardium/drivers/display.c b/epicardium/drivers/display.c index 05b0eaec1d4a920a3e3f3dbfb3bf2054542371f7..7cf92c7a2394a52103b4d61bcb1418c868b03812 100644 --- a/epicardium/drivers/display.c +++ b/epicardium/drivers/display.c @@ -311,6 +311,11 @@ int epic_disp_close() } } +void disp_update_backlight_clock(void) +{ + LCD_UpdateBacklightClock(); +} + void disp_forcelock() { TaskHandle_t task = xTaskGetCurrentTaskHandle(); diff --git a/epicardium/drivers/drivers.h b/epicardium/drivers/drivers.h index 1f2f22fbbc7e3e15cc155f882c55eff748b371a0..047728b6ced9c8aa60623457c91879ede556bd6c 100644 --- a/epicardium/drivers/drivers.h +++ b/epicardium/drivers/drivers.h @@ -61,6 +61,7 @@ int pmic_read_amux(enum pmic_amux_signal sig, float *result); /* ---------- Display ------------------------------------------------------ */ /* Forces an unlock of the display. Only to be used in Epicardium */ void disp_forcelock(); +void disp_update_backlight_clock(void); /* ---------- BHI160 ------------------------------------------------------- */ #define BHI160_FIFO_SIZE 128 diff --git a/lib/gfx/GUI_DEV/DEV_Config.c b/lib/gfx/GUI_DEV/DEV_Config.c index 67c73a142d03249528cc03156dd6eb06b7f89c39..68a5e5f1022f55ff684a05efa1e21ce86ebd003e 100644 --- a/lib/gfx/GUI_DEV/DEV_Config.c +++ b/lib/gfx/GUI_DEV/DEV_Config.c @@ -70,7 +70,68 @@ void lcd_write(uint8_t *data, int size) #define PORT_PWM PORT_0 // port #define PIN_PWM PIN_28 // pin #define FREQ 1000 // (Hz) +#define TIMER_FREQ 6000000 // _Target_ timer frequncy (Hz) #define PWM_TIMER MXC_TMR4 // must change PORT_PWM and PIN_PWM if changed + +/* Find a prescaler which gives us at least TIMER_FREQ HZ base clock + * at the current PCLK setting. + * + * Maximum prescaler chosen is 128. + */ +static uint8_t timer_prescale_factor(void) +{ + uint32_t target_prescaler = PeripheralClock / TIMER_FREQ; + + if (target_prescaler == 0) { + printf("TIMER_FREQ to high for PeripheralClock\n"); + while (1) + ; + } + + uint8_t prescaler = 1; + for (int i = 0; i < 7; i++) { + uint8_t next_prescaler = prescaler << 1; + if (next_prescaler > target_prescaler) { + break; + } + prescaler = next_prescaler; + } + + return prescaler; +} + +/* Return the constant need for the timer prescaler register to + * reach a least TIMER_FREQ HZ base clock frequency at the + * current PCLK setting */ +static uint32_t timer_prescaler(void) +{ + switch (timer_prescale_factor()) { + case 1: + return MXC_S_TMR_CN_PRES_DIV1; + case 2: + return MXC_S_TMR_CN_PRES_DIV2; + case 4: + return MXC_S_TMR_CN_PRES_DIV4; + case 8: + return MXC_S_TMR_CN_PRES_DIV8; + case 16: + return MXC_S_TMR_CN_PRES_DIV16; + case 32: + return MXC_S_TMR_CN_PRES_DIV32; + case 64: + return MXC_S_TMR_CN_PRES_DIV64; + default: + return MXC_S_TMR_CN_PRES_DIV128; + } +} + +/* Update the timer prescaler to what ever PCLK currently requires */ +void DEV_Update_BL_Clock(void) +{ + PWM_TIMER->cn = + (PWM_TIMER->cn & ~(MXC_F_TMR_CN_PRES)) | timer_prescaler(); +} + void DEV_Set_BL(uint16_t _Value) { // Declare variables @@ -82,8 +143,9 @@ void DEV_Set_BL(uint16_t _Value) _Value = 100; } - unsigned int period_ticks = PeripheralClock / FREQ; - unsigned int duty_ticks = period_ticks * _Value / 100; + unsigned int period_ticks = + PeripheralClock / timer_prescale_factor() / FREQ; + unsigned int duty_ticks = period_ticks * _Value / 100; TMR_Disable(PWM_TIMER); @@ -95,7 +157,7 @@ void DEV_Set_BL(uint16_t _Value) gpio_pwm.pad = GPIO_PAD_PULL_DOWN; GPIO_Config(&gpio_pwm); - TMR_Init(PWM_TIMER, TMR_PRES_1, 0); + TMR_Init(PWM_TIMER, timer_prescaler(), 0); tmr.mode = TMR_MODE_PWM; tmr.cmp_cnt = period_ticks; diff --git a/lib/gfx/GUI_DEV/DEV_Config.h b/lib/gfx/GUI_DEV/DEV_Config.h index cbc4c5f655d5cb6a3d2fcfa5c46a2235bc0027ed..321b6d9c909b74ea20ea4e8be7663e2da62f6e69 100644 --- a/lib/gfx/GUI_DEV/DEV_Config.h +++ b/lib/gfx/GUI_DEV/DEV_Config.h @@ -74,6 +74,8 @@ void display_set_reset_pin(uint8_t state); //#define DEV_Set_BL(_Value) DEV_BL_PIN= _Value void DEV_Set_BL(uint16_t _Value); +void DEV_Update_BL(void); +void DEV_Update_BL_Clock(void); /*-----------------------------------------------------------------------------*/ #endif diff --git a/lib/gfx/LCD/LCD_Driver.c b/lib/gfx/LCD/LCD_Driver.c index 55c872a824ad9ef355bdb9eb4db7018c6d44eeaa..3ef962efad1c75258773dfdf5a421020e9f80541 100644 --- a/lib/gfx/LCD/LCD_Driver.c +++ b/lib/gfx/LCD/LCD_Driver.c @@ -56,6 +56,14 @@ void LCD_SetBacklight(UWORD Value) { DEV_Set_BL(Value); } +/******************************************************************************* +function: + Update backlight clock +*******************************************************************************/ +void LCD_UpdateBacklightClock(void) +{ + DEV_Update_BL_Clock(); +} /******************************************************************************* function: diff --git a/lib/gfx/LCD/LCD_Driver.h b/lib/gfx/LCD/LCD_Driver.h index 49358115beea4ac4a7f8ec30b2b827149c6dfdad..ad6f29f248a24da12fae393d491c1ff4378a8722 100644 --- a/lib/gfx/LCD/LCD_Driver.h +++ b/lib/gfx/LCD/LCD_Driver.h @@ -46,6 +46,7 @@ void LCD_SetUWORD(UWORD x, UWORD y, UWORD Color); void LCD_Init(void); void LCD_SetBacklight(UWORD Value); +void LCD_UpdateBacklightClock(void); void LCD_Clear(UWORD Color); void LCD_ClearWindow(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD UWORD); uint8_t *LCD_Framebuffer(void);