Skip to content
Snippets Groups Projects
Commit 47b02df1 authored by schneider's avatar schneider
Browse files

change(backlight): Keep PWM stable when changing PCLK

Timer frequency is now held close to a value which can be achieved both
with a 48 MHz PCLK (96 MHz system clock) and a 7.5 MHz PCLK (15 MHz
system clock).

If even lower PCLKs should be supported, the frequency of the timer has
to be changed as well.
parent 01dab506
No related branches found
No related tags found
1 merge request!478change(backlight): Keep PWM stable when changing PCLK
Pipeline #5239 passed
......@@ -311,6 +311,11 @@ int epic_disp_close()
}
}
void disp_update_backlight_clock(void)
{
LCD_UpdateBacklightClock();
}
void disp_forcelock()
{
TaskHandle_t task = xTaskGetCurrentTaskHandle();
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......@@ -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:
......
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment