Implemented display backlight regulation for MD-UV380

replace/cd841b61c47ad62761410788f827b2275fce7cae
Silvano Seva 2020-10-24 15:20:06 +02:00 zatwierdzone przez Niccolò Izzo
rodzic 6e758fe92b
commit bdd5ea6c7b
2 zmienionych plików z 89 dodań i 3 usunięć

Wyświetl plik

@ -20,7 +20,7 @@
#ifndef HWCONFIG_H #ifndef HWCONFIG_H
#define HWCONFIG_H #define HWCONFIG_H
#include "stm32f4xx.h" #include <stm32f4xx.h>
/* Screen dimensions */ /* Screen dimensions */
#define SCREEN_WIDTH 160 #define SCREEN_WIDTH 160
@ -43,4 +43,26 @@
#define LCD_BKLIGHT GPIOD,8 #define LCD_BKLIGHT GPIOD,8
/*
* To enable pwm for display backlight dimming uncomment this directive.
*
* WARNING: backlight pwm is disabled by default because it generates a
* continuous tone in the speaker and headphones.
*
* This issue cannot be solved in any way because it derives from how the
* MD-UV380 mcu pins are used: to have a noiseless backlight pwm, the control
* pin has to be connected to a mcu pin having between its alternate functions
* an output compare channel of one of the timers. With this configuration, the
* pwm signal can completely generated in hardware and its frequency can be well
* above 22kHz, which is the upper limit for human ears.
*
* In the MD-UV380 radio, display backlight is connected to PD8, which is not
* connected to any of the available output compare channels. Thus, the pwm
* signal generation is managed inside the TIM11 ISR by toggling the backlight
* pin and its frequency has to be low (~250Hz) to not put too much overehad on
* the processor due to timer ISR triggering at an high rate.
*
* #define ENABLE_BKLIGHT_DIMMING
*/
#endif #endif

Wyświetl plik

@ -19,8 +19,30 @@
#include <platform.h> #include <platform.h>
#include <gpio.h> #include <gpio.h>
#include <os.h>
#include "hwconfig.h" #include "hwconfig.h"
#ifdef ENABLE_BKLIGHT_DIMMING
void TIM1_TRG_COM_TIM11_IRQHandler()
{
OSIntEnter();
if(TIM11->SR & TIM_SR_CC1IF)
{
gpio_clearPin(LCD_BKLIGHT); /* Clear pin on compare match */
}
if(TIM11->SR & TIM_SR_UIF)
{
gpio_setPin(LCD_BKLIGHT); /* Set pin on counter reload */
}
TIM11->SR = 0;
OSIntExit();
}
#endif
void platform_init() void platform_init()
{ {
/* Configure GPIOs */ /* Configure GPIOs */
@ -29,6 +51,33 @@ void platform_init()
gpio_setMode(LCD_BKLIGHT, OUTPUT); gpio_setMode(LCD_BKLIGHT, OUTPUT);
gpio_clearPin(LCD_BKLIGHT); gpio_clearPin(LCD_BKLIGHT);
#ifdef ENABLE_BKLIGHT_DIMMING
/*
* Configure TIM11 for backlight PWM: Fpwm = 256Hz, 8 bit of resolution
* APB2 freq. is 84MHz, then: PSC = 1281 to have Ftick = 65.52kHz
* With ARR = 256, Fpwm is 256Hz;
*/
RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
TIM11->ARR = 255;
TIM11->PSC = 1282;
TIM11->CNT = 0;
TIM11->CR1 |= TIM_CR1_ARPE;
TIM11->CCMR1 |= TIM_CCMR1_OC1M_2
| TIM_CCMR1_OC1M_1
| TIM_CCMR1_OC1PE;
TIM11->CCER |= TIM_CCER_CC1E;
TIM11->CCR1 = 0;
TIM11->EGR = TIM_EGR_UG; /* Update registers */
TIM11->SR = 0; /* Clear interrupt flags */
TIM11->DIER = TIM_DIER_CC1IE /* Interrupt on compare match */
| TIM_DIER_UIE; /* Interrupt on counter reload */
TIM11->CR1 |= TIM_CR1_CEN; /* Start timer */
NVIC_ClearPendingIRQ(TIM1_TRG_COM_TIM11_IRQn);
NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn,15);
NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
#endif
} }
void platform_terminate() void platform_terminate()
@ -39,7 +88,9 @@ void platform_terminate()
gpio_clearPin(GREEN_LED); gpio_clearPin(GREEN_LED);
gpio_clearPin(RED_LED); gpio_clearPin(RED_LED);
RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; #ifdef ENABLE_BKLIGHT_DIMMING
RCC->APB2ENR &= ~RCC_APB2ENR_TIM11EN;
#endif
} }
float platform_getVbat() float platform_getVbat()
@ -108,12 +159,25 @@ void platform_beepStop()
void platform_setBacklightLevel(uint8_t level) void platform_setBacklightLevel(uint8_t level)
{ {
if(level > 0) /*
* Little workaround for the following nasty behaviour: if CCR1 value is
* zero, a waveform with 99% duty cycle is generated. This is because we are
* emulating pwm with interrupts.
*/
if(level > 1)
{ {
#ifdef ENABLE_BKLIGHT_DIMMING
TIM11->CCR1 = level;
TIM11->CR1 |= TIM_CR1_CEN;
#else
gpio_setPin(LCD_BKLIGHT); gpio_setPin(LCD_BKLIGHT);
#endif
} }
else else
{ {
#ifdef ENABLE_BKLIGHT_DIMMING
TIM11->CR1 &= ~TIM_CR1_CEN;
#endif
gpio_clearPin(LCD_BKLIGHT); gpio_clearPin(LCD_BKLIGHT);
} }
} }