STM32F042-Drivers-Pub/tim2.c

195 lines
4.0 KiB
C
Raw Normal View History

2024-05-02 10:18:04 +00:00
/*
* 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