|
|
|
@ -29,7 +29,7 @@ void backlight_pwm_init(void) {
|
|
|
|
|
|
|
|
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
|
|
|
|
|
|
// LCD_PWM/PA7 (backlight control)
|
|
|
|
|
// LCD_PWM (backlight control)
|
|
|
|
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
|
|
|
|
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
|
|
|
|
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
|
|
@ -37,34 +37,113 @@ void backlight_pwm_init(void) {
|
|
|
|
|
GPIO_InitStructure.Pin = BACKLIGHT_PWM_PIN;
|
|
|
|
|
HAL_GPIO_Init(BACKLIGHT_PWM_PORT, &GPIO_InitStructure);
|
|
|
|
|
|
|
|
|
|
// enable PWM timer
|
|
|
|
|
TIM_HandleTypeDef TIM_Handle;
|
|
|
|
|
TIM_Handle.Instance = BACKLIGHT_PWM_TIM;
|
|
|
|
|
TIM_Handle.Init.Period = LED_PWM_TIM_PERIOD - 1;
|
|
|
|
|
// TIM1/APB2 source frequency equals to SystemCoreClock in our configuration,
|
|
|
|
|
// we want 1 MHz
|
|
|
|
|
TIM_Handle.Init.Prescaler = LED_PWM_PRESCALER;
|
|
|
|
|
TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
|
|
|
|
TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
|
|
|
|
TIM_Handle.Init.RepetitionCounter = 0;
|
|
|
|
|
HAL_TIM_PWM_Init(&TIM_Handle);
|
|
|
|
|
uint32_t tmpcr1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Select the Counter Mode */
|
|
|
|
|
tmpcr1 |= TIM_COUNTERMODE_UP;
|
|
|
|
|
|
|
|
|
|
/* Set the clock division */
|
|
|
|
|
tmpcr1 |= (uint32_t)TIM_CLOCKDIVISION_DIV1;
|
|
|
|
|
|
|
|
|
|
/* Set the auto-reload preload */
|
|
|
|
|
#ifdef STM32U5
|
|
|
|
|
tmpcr1 |= TIM_AUTORELOAD_PRELOAD_DISABLE;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
BACKLIGHT_PWM_TIM->CR1 = tmpcr1;
|
|
|
|
|
|
|
|
|
|
/* Set the Autoreload value */
|
|
|
|
|
BACKLIGHT_PWM_TIM->ARR = (uint32_t)LED_PWM_TIM_PERIOD - 1;
|
|
|
|
|
|
|
|
|
|
/* Set the Prescaler value */
|
|
|
|
|
BACKLIGHT_PWM_TIM->PSC = LED_PWM_PRESCALER;
|
|
|
|
|
|
|
|
|
|
/* Set the Repetition Counter value */
|
|
|
|
|
BACKLIGHT_PWM_TIM->RCR = 0;
|
|
|
|
|
|
|
|
|
|
/* Generate an update event to reload the Prescaler
|
|
|
|
|
and the repetition counter (only for advanced timer) value immediately */
|
|
|
|
|
BACKLIGHT_PWM_TIM->EGR = TIM_EGR_UG;
|
|
|
|
|
|
|
|
|
|
pwm_period = LED_PWM_TIM_PERIOD;
|
|
|
|
|
|
|
|
|
|
TIM_OC_InitTypeDef TIM_OC_InitStructure;
|
|
|
|
|
TIM_OC_InitStructure.Pulse = 0;
|
|
|
|
|
TIM_OC_InitStructure.OCMode = BACKLIGHT_PWM_TIM_OCMODE;
|
|
|
|
|
TIM_OC_InitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
|
|
|
|
|
TIM_OC_InitStructure.OCFastMode = TIM_OCFAST_DISABLE;
|
|
|
|
|
TIM_OC_InitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
|
|
|
|
TIM_OC_InitStructure.OCIdleState = TIM_OCIDLESTATE_SET;
|
|
|
|
|
TIM_OC_InitStructure.OCNIdleState = TIM_OCNIDLESTATE_SET;
|
|
|
|
|
HAL_TIM_PWM_ConfigChannel(&TIM_Handle, &TIM_OC_InitStructure,
|
|
|
|
|
BACKLIGHT_PWM_TIM_CHANNEL);
|
|
|
|
|
/* Set the Preload enable bit for channel1 */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCMR1 |= TIM_CCMR1_OC1PE;
|
|
|
|
|
|
|
|
|
|
/* Configure the Output Fast mode */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCMR1 &= ~TIM_CCMR1_OC1FE;
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCMR1 |= TIM_OCFAST_DISABLE;
|
|
|
|
|
|
|
|
|
|
uint32_t tmpccmrx;
|
|
|
|
|
uint32_t tmpccer;
|
|
|
|
|
uint32_t tmpcr2;
|
|
|
|
|
|
|
|
|
|
/* Get the TIMx CCER register value */
|
|
|
|
|
tmpccer = BACKLIGHT_PWM_TIM->CCER;
|
|
|
|
|
|
|
|
|
|
/* Disable the Channel 1: Reset the CC1E Bit */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCER &= ~TIM_CCER_CC1E;
|
|
|
|
|
tmpccer |= TIM_CCER_CC1E;
|
|
|
|
|
|
|
|
|
|
/* Get the TIMx CR2 register value */
|
|
|
|
|
tmpcr2 = BACKLIGHT_PWM_TIM->CR2;
|
|
|
|
|
|
|
|
|
|
/* Get the TIMx CCMR1 register value */
|
|
|
|
|
tmpccmrx = BACKLIGHT_PWM_TIM->CCMR1;
|
|
|
|
|
|
|
|
|
|
/* Reset the Output Compare Mode Bits */
|
|
|
|
|
tmpccmrx &= ~TIM_CCMR1_OC1M;
|
|
|
|
|
tmpccmrx &= ~TIM_CCMR1_CC1S;
|
|
|
|
|
/* Select the Output Compare Mode */
|
|
|
|
|
tmpccmrx |= BACKLIGHT_PWM_TIM_OCMODE;
|
|
|
|
|
|
|
|
|
|
/* Reset the Output Polarity level */
|
|
|
|
|
tmpccer &= ~TIM_CCER_CC1P;
|
|
|
|
|
/* Set the Output Compare Polarity */
|
|
|
|
|
tmpccer |= TIM_OCPOLARITY_HIGH;
|
|
|
|
|
|
|
|
|
|
if (IS_TIM_CCXN_INSTANCE(BACKLIGHT_PWM_TIM, TIM_CHANNEL_1)) {
|
|
|
|
|
/* Check parameters */
|
|
|
|
|
assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
|
|
|
|
|
|
|
|
|
|
/* Reset the Output N Polarity level */
|
|
|
|
|
tmpccer &= ~TIM_CCER_CC1NP;
|
|
|
|
|
/* Set the Output N Polarity */
|
|
|
|
|
tmpccer |= TIM_OCNPOLARITY_HIGH;
|
|
|
|
|
/* Set the Output N State */
|
|
|
|
|
tmpccer |= TIM_CCER_CC1NE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IS_TIM_BREAK_INSTANCE(BACKLIGHT_PWM_TIM)) {
|
|
|
|
|
/* Check parameters */
|
|
|
|
|
assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
|
|
|
|
|
assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
|
|
|
|
|
|
|
|
|
|
/* Reset the Output Compare and Output Compare N IDLE State */
|
|
|
|
|
tmpcr2 &= ~TIM_CR2_OIS1;
|
|
|
|
|
tmpcr2 &= ~TIM_CR2_OIS1N;
|
|
|
|
|
/* Set the Output Idle state */
|
|
|
|
|
tmpcr2 |= TIM_OCIDLESTATE_SET;
|
|
|
|
|
/* Set the Output N Idle state */
|
|
|
|
|
tmpcr2 |= TIM_OCNIDLESTATE_SET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write to TIMx CR2 */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CR2 = tmpcr2;
|
|
|
|
|
|
|
|
|
|
/* Write to TIMx CCMR1 */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCMR1 = tmpccmrx;
|
|
|
|
|
|
|
|
|
|
/* Set the Capture Compare Register value */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCR1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Write to TIMx CCER */
|
|
|
|
|
BACKLIGHT_PWM_TIM->CCER = tmpccer;
|
|
|
|
|
|
|
|
|
|
backlight_pwm_set(0);
|
|
|
|
|
|
|
|
|
|
HAL_TIM_PWM_Start(&TIM_Handle, BACKLIGHT_PWM_TIM_CHANNEL);
|
|
|
|
|
HAL_TIMEx_PWMN_Start(&TIM_Handle, BACKLIGHT_PWM_TIM_CHANNEL);
|
|
|
|
|
BACKLIGHT_PWM_TIM->BDTR |= TIM_BDTR_MOE;
|
|
|
|
|
BACKLIGHT_PWM_TIM->CR1 |= TIM_CR1_CEN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void backlight_pwm_reinit(void) {
|
|
|
|
|