STM32F042-Drivers-Pub/tim3.c
Francesco Gritti fe64f5342d initial commit
2024-05-02 12:18:04 +02:00

284 lines
5.9 KiB
C

/*
* tim3.c
*
* Created on: Dec 30, 2023
* Author: Francesco Gritti
*/
#include "main.h"
#include "mcu.h"
#include "gpio.h"
#ifdef tim3_adc_timebase
void TIM3_init (void) {
RCC_TIM3_CLK_ENABLE();
TIM3->CR1 = 0x0000;
TIM3->CR2 = (0b010 << TIM_CR2_MMS_Pos);
TIM3->DIER = 0x0000; // disable all interrupt requests
TIM3->PSC = 24-1;
TIM3->ARR = 1000 -1;
TIM3->CR1 |= TIM_CR1_CEN;
}
#endif
#ifdef tim3_pwm
void TIM3_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
TIM3->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE;
if (activeState == TIM_OC_ACTIVE_HIGH)
TIM_PWM_SET_CH1_POLARITY_ACTIVE_HIGH (TIM3);
else
TIM_PWM_SET_CH1_POLARITY_ACTIVE_LOW (TIM3);
TIM3->CCR1 = value;
TIM_CH1_FORCE_INACTIVE(TIM3);
TIM_CH1_ENABLE(TIM3);
}
void TIM3_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
TIM3->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC2M_Pos) | TIM_CCMR1_OC2PE;
if (activeState == TIM_OC_ACTIVE_HIGH)
TIM_PWM_SET_CH2_POLARITY_ACTIVE_HIGH (TIM3);
else
TIM_PWM_SET_CH2_POLARITY_ACTIVE_LOW (TIM3);
TIM3->CCR2 = value;
TIM_CH2_FORCE_INACTIVE(TIM3);
TIM_CH2_ENABLE(TIM3);
}
void TIM3_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
TIM3->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC3M_Pos) | TIM_CCMR2_OC3PE;
if (activeState == TIM_OC_ACTIVE_HIGH)
TIM_PWM_SET_CH3_POLARITY_ACTIVE_HIGH (TIM3);
else
TIM_PWM_SET_CH3_POLARITY_ACTIVE_LOW (TIM3);
TIM3->CCR3 = value;
TIM_CH3_ENABLE(TIM3);
}
void TIM3_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
TIM3->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC4M_Pos) | TIM_CCMR2_OC4PE;
if (activeState == TIM_OC_ACTIVE_HIGH)
TIM_PWM_SET_CH4_POLARITY_ACTIVE_HIGH (TIM3);
else
TIM_PWM_SET_CH4_POLARITY_ACTIVE_LOW (TIM3);
TIM3->CCR4 = value;
TIM_CH4_ENABLE(TIM3);
}
void TIM3_pwm_init (void) {
RCC_TIM3_CLK_ENABLE ();
TIM3->CR1 = 0x0000;
TIM3->CR2 = 0x0000;
TIM3->SMCR = 0x0000;
TIM3->DIER = 0x0000;
// disable all channels
TIM3->CCER = 0x0000;
// enable ch3 and ch4, force them inactive
TIM3->CCMR1 = 0x0000;
TIM3->CCMR2 = 0x0000;
// reset counter
TIM3->CNT = 0x0000;
//set PRESCALER
TIM3->PSC = TIM3_PSC;
// set PERIOD
TIM3->ARR = TIM3_PERIOD;
// reset all PWM periods
TIM3->CCR1 = 0x0000;
TIM3->CCR2 = 0x0000;
TIM3->CCR3 = 0x0000;
TIM3->CCR4 = 0x0000;
TIM_COUNTER_ENABLE (TIM3);
}
#elif defined(tim3_ic)
void TIM3_ic_config_ch1 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
// disable channel
TIM3->CCER &= ~TIM_CCER_CC1E;
TIM3->CCMR1 = ((filterValue & 0x0f) << TIM_CCMR1_IC1F_Pos) | (0b01 << TIM_CCMR1_CC1S_Pos);
// clear edge selection bit => default rising edge
TIM3->CCER &= ~(TIM_CCER_CC1NP | TIM_CCER_CC1P);
switch (activeState) {
case TIM_IC_ACTIVE_RISING:
break;
case TIM_IC_ACTIVE_FALLING:
TIM3->CCER |= TIM_CCER_CC1P;
break;
case TIM_IC_ACTIVE_BOTH:
TIM3->CCER |= (TIM_CCER_CC1NP | TIM_CCER_CC1P);
break;
}
// enable interrupt on channel compare
TIM3->DIER |= TIM_DIER_CC1IE;
// enable the channel
TIM3->CCER |= TIM_CCER_CC1E;
}
void TIM3_ic_config_ch2 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
// disable channel
TIM3->CCER &= ~TIM_CCER_CC2E;
TIM3->CCMR1 = ((filterValue & 0x0f) << TIM_CCMR1_IC2F_Pos) | (0b01 << TIM_CCMR1_CC2S_Pos);
// clear edge selection bit => default rising edge
TIM3->CCER &= ~(TIM_CCER_CC2NP | TIM_CCER_CC2P);
switch (activeState) {
case TIM_IC_ACTIVE_RISING:
break;
case TIM_IC_ACTIVE_FALLING:
TIM3->CCER |= TIM_CCER_CC2P;
break;
case TIM_IC_ACTIVE_BOTH:
TIM3->CCER |= (TIM_CCER_CC2NP | TIM_CCER_CC2P);
break;
}
// enable interrupt on channel compare
TIM3->DIER |= TIM_DIER_CC2IE;
// enable the channel
TIM3->CCER |= TIM_CCER_CC2E;
}
void TIM3_ic_config_ch3 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
// disable channel
TIM3->CCER &= ~TIM_CCER_CC3E;
TIM3->CCMR2 = ((filterValue & 0x0f) << TIM_CCMR2_IC3F_Pos) | (0b01 << TIM_CCMR2_CC3S_Pos);
// clear edge selection bit => default rising edge
TIM3->CCER &= ~(TIM_CCER_CC3NP | TIM_CCER_CC3P);
switch (activeState) {
case TIM_IC_ACTIVE_RISING:
break;
case TIM_IC_ACTIVE_FALLING:
TIM3->CCER |= TIM_CCER_CC3P;
break;
case TIM_IC_ACTIVE_BOTH:
TIM3->CCER |= (TIM_CCER_CC3NP | TIM_CCER_CC3P);
break;
}
// enable interrupt on channel compare
TIM3->DIER |= TIM_DIER_CC3IE;
// enable the channel
TIM3->CCER |= TIM_CCER_CC3E;
}
void TIM3_ic_config_ch4 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
// disable channel
TIM3->CCER &= ~TIM_CCER_CC3E;
TIM3->CCMR2 = ((filterValue & 0x0f) << TIM_CCMR2_IC4F_Pos) | (0b01 << TIM_CCMR2_CC4S_Pos);
// clear edge selection bit => default rising edge
TIM3->CCER &= ~(TIM_CCER_CC4NP | TIM_CCER_CC4P);
switch (activeState) {
case TIM_IC_ACTIVE_RISING:
break;
case TIM_IC_ACTIVE_FALLING:
TIM3->CCER |= TIM_CCER_CC4P;
break;
case TIM_IC_ACTIVE_BOTH:
TIM3->CCER |= (TIM_CCER_CC4NP | TIM_CCER_CC4P);
break;
}
// enable interrupt on channel compare
TIM3->DIER |= TIM_DIER_CC4IE;
// enable the channel
TIM3->CCER |= TIM_CCER_CC4E;
}
void TIM3_ic_init(void) {
RCC_TIM3_CLK_ENABLE();
TIM3->CCMR1 = 0x00000000;
TIM3->CCMR2 = 0x00000000;
/* Configure base timer */
// enable interrupt on timer update
TIM3->DIER = TIM_DIER_UIE;
TIM3->PSC = TIM3_PSC;
TIM3->ARR = TIM3_PERIOD;
// request UEV event only on underflow/overflow and enable timer
TIM3->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
// set highest priority since the handler is a non blocking function
NVIC_SetPriority(TIM3_IRQn, 0);
NVIC_EnableIRQ(TIM3_IRQn);
}
__attribute__ ((weak)) void TIM3_IRQHandler (void) {
// clear IT flag
if ((TIM3->SR & TIM_SR_CC1IF) != 0)
TIM3->SR &= ~TIM_SR_CC1IF;
if ((TIM3->SR & TIM_SR_CC2IF) != 0)
TIM3->SR &= ~TIM_SR_CC2IF;
if ((TIM3->SR & TIM_SR_CC3IF) != 0)
TIM3->SR &= ~TIM_SR_CC3IF;
if ((TIM3->SR & TIM_SR_CC4IF) != 0)
TIM3->SR &= ~TIM_SR_CC4IF;
if ((TIM3->SR & TIM_SR_UIF) != 0)
TIM3->SR &= ~TIM_SR_UIF;
}
#endif