195 lines
4.0 KiB
C
195 lines
4.0 KiB
C
|
/*
|
||
|
* tim2.c
|
||
|
*
|
||
|
* Created on: Dec 30, 2023
|
||
|
* Author: Francesco Gritti
|
||
|
*
|
||
|
* This file contains implementation of booth timer 2 input capture and PWM
|
||
|
* generation features. only one of the two features can be enabled by
|
||
|
* defining the macros "tim2_pwm" or "tim2_ic".
|
||
|
*
|
||
|
* GPIOs connected to the input/output channels of the timer should be
|
||
|
* defined in main.h and they are initialized into the TIM2_init function
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "main.h"
|
||
|
#include "mcu.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef tim2_adc_timebase
|
||
|
|
||
|
|
||
|
|
||
|
void TIM2_init (void) {
|
||
|
|
||
|
RCC_TIM2_CLK_ENABLE();
|
||
|
|
||
|
|
||
|
TIM2->CR1 = 0x0000;
|
||
|
TIM2->CR2 = (0b010 << TIM_CR2_MMS_Pos);
|
||
|
TIM2->DIER = 0x0000; // disable all interrupt requests
|
||
|
|
||
|
TIM2->PSC = TIM2_PSC;
|
||
|
TIM2->ARR = TIM2_PERIOD;
|
||
|
|
||
|
|
||
|
TIM2->CR1 |= TIM_CR1_CEN;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef tim2_pwm
|
||
|
|
||
|
void TIM2_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||
|
TIM2->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE;
|
||
|
|
||
|
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||
|
TIM_PWM_SET_CH1_POLARITY_ACTIVE_HIGH (TIM2);
|
||
|
else
|
||
|
TIM_PWM_SET_CH1_POLARITY_ACTIVE_LOW (TIM2);
|
||
|
|
||
|
TIM2->CCR1 = value;
|
||
|
TIM_CH1_FORCE_INACTIVE(TIM2);
|
||
|
TIM_CH1_ENABLE(TIM2);
|
||
|
}
|
||
|
|
||
|
void TIM2_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||
|
TIM2->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC2M_Pos) | TIM_CCMR1_OC2PE;
|
||
|
|
||
|
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||
|
TIM_PWM_SET_CH2_POLARITY_ACTIVE_HIGH (TIM2);
|
||
|
else
|
||
|
TIM_PWM_SET_CH2_POLARITY_ACTIVE_LOW (TIM2);
|
||
|
|
||
|
TIM2->CCR2 = value;
|
||
|
TIM_CH2_FORCE_INACTIVE(TIM2);
|
||
|
TIM_CH2_ENABLE(TIM2);
|
||
|
}
|
||
|
|
||
|
void TIM2_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||
|
TIM2->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC3M_Pos) | TIM_CCMR2_OC3PE;
|
||
|
|
||
|
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||
|
TIM_PWM_SET_CH3_POLARITY_ACTIVE_HIGH (TIM2);
|
||
|
else
|
||
|
TIM_PWM_SET_CH3_POLARITY_ACTIVE_LOW (TIM2);
|
||
|
|
||
|
TIM2->CCR3 = value;
|
||
|
TIM_CH3_ENABLE(TIM2);
|
||
|
}
|
||
|
|
||
|
void TIM2_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||
|
TIM2->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC4M_Pos) | TIM_CCMR2_OC4PE;
|
||
|
|
||
|
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||
|
TIM_PWM_SET_CH4_POLARITY_ACTIVE_HIGH (TIM2);
|
||
|
else
|
||
|
TIM_PWM_SET_CH4_POLARITY_ACTIVE_LOW (TIM2);
|
||
|
|
||
|
TIM2->CCR4 = value;
|
||
|
TIM_CH4_ENABLE(TIM2);
|
||
|
}
|
||
|
|
||
|
void TIM2_pwm_init (void) {
|
||
|
|
||
|
RCC_TIM2_CLK_ENABLE ();
|
||
|
|
||
|
TIM2->CR1 = 0x0000;
|
||
|
TIM2->CR2 = 0x0000;
|
||
|
TIM2->SMCR = 0x0000;
|
||
|
TIM2->DIER = 0x0000;
|
||
|
|
||
|
// disable all channels
|
||
|
TIM2->CCER = 0x0000;
|
||
|
|
||
|
// force CH1 and CH2 inactive, enable compare PRELOAD
|
||
|
TIM2->CCMR1 = 0x0000;
|
||
|
TIM2->CCMR2 = 0x0000;
|
||
|
// reset counter
|
||
|
TIM2->CNT = 0x0000;
|
||
|
//set PRESCALER
|
||
|
TIM2->PSC = TIM2_PSC;
|
||
|
// set PERIOD
|
||
|
TIM2->ARR = TIM2_PERIOD;
|
||
|
|
||
|
// reset all PWM periods
|
||
|
TIM2->CCR1 = 0x0000;
|
||
|
TIM2->CCR2 = 0x0000;
|
||
|
TIM2->CCR3 = 0x0000;
|
||
|
TIM2->CCR4 = 0x0000;
|
||
|
|
||
|
TIM_COUNTER_ENABLE (TIM2);
|
||
|
}
|
||
|
|
||
|
/*GPIO_AF_PP (TIM2_PWM_CH1);
|
||
|
GPIO_AF_PP (TIM2_PWM_CH2);
|
||
|
GPIO_AF_PP (TIM2_PWM_CH3);
|
||
|
GPIO_AF_PP (TIM2_PWM_CH4);
|
||
|
|
||
|
GPIO_SET_AFRL (TIM2_PWM_CH1, GPIO_AF_TIM2);
|
||
|
GPIO_SET_AFRL (TIM2_PWM_CH2, GPIO_AF_TIM2);
|
||
|
GPIO_SET_AFRL (TIM2_PWM_CH3, GPIO_AF_TIM2);
|
||
|
GPIO_SET_AFRL (TIM2_PWM_CH4, GPIO_AF_TIM2);*/
|
||
|
|
||
|
|
||
|
|
||
|
#elif defined(tim2_ic)
|
||
|
|
||
|
void TIM2_init(void) {
|
||
|
|
||
|
RCC_TIM2_CLK_ENABLE();
|
||
|
RCC_GPIOA_CLK_ENABLE();
|
||
|
|
||
|
|
||
|
/* =============== configure GPIO ================*/
|
||
|
|
||
|
GPIO_AF_PP (TIM2_IN_CH2);
|
||
|
GPIO_SET_AFRL (TIM2_IN_CH2, 0x02);
|
||
|
|
||
|
|
||
|
/* ====== configure timer capture channels ======*/
|
||
|
|
||
|
// configure channel 2 as input capture with filter 3
|
||
|
TIM2->CCMR1 = (3 << TIM_CCMR1_IC2F_Pos) | (0b01 << TIM_CCMR1_CC2S_Pos);
|
||
|
// capture on falling edge only, enable channel
|
||
|
TIM2->CCER = TIM_CCER_CC2P | TIM_CCER_CC2E;
|
||
|
|
||
|
/* Configure base timer */
|
||
|
|
||
|
// enable interrupt on timer update and on channel2 input capture
|
||
|
TIM2->DIER = TIM_DIER_UIE | TIM_DIER_CC2IE;
|
||
|
|
||
|
TIM2->PSC = TIM2_PSC; // 54;
|
||
|
TIM2->ARR = TIM2_PERIOD; // 65535;
|
||
|
|
||
|
// request UEV event only on underflow/overflow and enable timer
|
||
|
TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
|
||
|
|
||
|
// set highest priority since the handler is a non blocking function
|
||
|
NVIC_SetPriority(TIM2_IRQn, 0);
|
||
|
NVIC_EnableIRQ(TIM2_IRQn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
__attribute__ ((weak)) void TIM2_IRQHandler (void) {
|
||
|
|
||
|
// clear IT flag
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|