27 static void _twr_pwm_tim2_configure(uint32_t resolution_us, uint32_t period_cycles)
30 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
36 TIM2->CR1 &= ~TIM_CR1_CEN;
40 TIM2->PSC = resolution_us * 32 - 1;
41 TIM2->ARR = period_cycles - 1;
44 TIM2->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
45 TIM2->CCER |= TIM_CCER_CC1E;
47 TIM2->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
48 TIM2->CCER |= TIM_CCER_CC2E;
50 TIM2->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
51 TIM2->CCER |= TIM_CCER_CC3E;
53 TIM2->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2;
54 TIM2->CCER |= TIM_CCER_CC4E;
56 TIM2->CR1 |= TIM_CR1_CEN;
59 static void _twr_pwm_tim3_configure(uint32_t resolution_us, uint32_t period_cycles)
62 RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
68 TIM3->CR1 &= ~TIM_CR1_CEN;
71 TIM3->PSC = resolution_us * 32 - 1;
72 TIM3->ARR = period_cycles - 1;
75 TIM3->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
76 TIM3->CCER |= TIM_CCER_CC1E;
81 TIM3->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
82 TIM3->CCER |= TIM_CCER_CC3E;
84 TIM3->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2;
85 TIM3->CCER |= TIM_CCER_CC4E;
87 TIM3->CR1 |= TIM_CR1_CEN;
90 static void _twr_pwm_tim21_configure(uint32_t resolution_us, uint32_t period_cycles)
93 RCC->APB2ENR |= RCC_APB2ENR_TIM21EN;
99 TIM21->CR1 &= ~TIM_CR1_CEN;
102 TIM21->PSC = resolution_us * 32 - 1;
103 TIM21->ARR = period_cycles - 1;
106 TIM21->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
107 TIM21->CCER |= TIM_CCER_CC1E;
109 TIM21->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
110 TIM21->CCER |= TIM_CCER_CC2E;
112 TIM21->CR1 |= TIM_CR1_CEN;
119 case TWR_PWM_TIM2_P0_P1_P2_P3:
121 _twr_pwm_tim2_configure(resolution_us, period_cycles);
124 case TWR_PWM_TIM3_P6_P7_P8:
126 _twr_pwm_tim3_configure(resolution_us, period_cycles);
129 case TWR_PWM_TIM21_P12_P14:
131 _twr_pwm_tim21_configure(resolution_us, period_cycles);
143 static bool tim2_initialized =
false;
144 static bool tim3_initialized =
false;
145 static bool tim21_initialized =
false;
146 static bool pll_enabled =
false;
150 twr_system_pll_enable();
154 if (!tim2_initialized && (channel == TWR_PWM_P0 || channel == TWR_PWM_P1 || channel == TWR_PWM_P2 || channel == TWR_PWM_P3))
158 tim2_initialized =
true;
161 if (!tim3_initialized && (channel == TWR_PWM_P6 || channel == TWR_PWM_P7 || channel == TWR_PWM_P8))
164 tim3_initialized =
true;
167 if (!tim21_initialized && (channel == TWR_PWM_P12 || channel == TWR_PWM_P14))
170 tim21_initialized =
true;
178 if (channel == TWR_PWM_P12 || channel == TWR_PWM_P14)
199 TIM2->CCR1 = pwm_value;
204 TIM2->CCR2 = pwm_value;
209 TIM2->CCR3 = pwm_value;
214 TIM2->CCR4 = pwm_value;
219 TIM3->CCR4 = pwm_value;
224 TIM3->CCR1 = pwm_value;
229 TIM3->CCR3 = pwm_value;
234 TIM21->CCR2 = pwm_value;
239 TIM21->CCR1 = pwm_value;
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
twr_gpio_channel_t
GPIO channels.
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
@ TWR_GPIO_MODE_ALTERNATE_2
GPIO channel operates in alternate mode AF2.
@ TWR_GPIO_MODE_ALTERNATE_6
GPIO channel operates in alternate mode AF6.
@ TWR_GPIO_MODE_ANALOG
GPIO channel operates in analog mode.
void twr_pwm_enable(twr_pwm_channel_t channel)
Enable PWM output on GPIO pin.
void twr_pwm_set(twr_pwm_channel_t channel, uint16_t pwm_value)
Set PWM value for GPIO pin.
void twr_pwm_tim_configure(twr_pwm_tim_t tim, uint32_t resolution_us, uint32_t period_cycles)
Reconfigure TIM3.
void twr_pwm_init(twr_pwm_channel_t channel)
Initialize PWM timers based on GPIO pin.
twr_pwm_channel_t
PWM channels.
void twr_pwm_disable(twr_pwm_channel_t channel)
Disable PWM output on GPIO pin.