31 #include "generated/airframe.h"
33 #include <libopencm3/stm32/rcc.h>
34 #include <libopencm3/stm32/gpio.h>
35 #include <libopencm3/stm32/timer.h>
36 #include <libopencm3/cm3/nvic.h>
44 #define ONE_MHZ_CLK 1000000
45 #ifdef NVIC_TIM_IRQ_PRIO
46 #define PWM_INPUT_IRQ_PRIO NVIC_TIM_IRQ_PRIO
48 #define PWM_INPUT_IRQ_PRIO 2
54 timer_set_mode(tim, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
55 timer_set_period(tim, 0xFFFF);
57 timer_set_prescaler(tim, (timer_clk / (ticks_per_usec *
ONE_MHZ_CLK)) - 1);
58 timer_enable_counter(tim);
77 #if USE_PWM_INPUT_TIM1
78 rcc_periph_clock_enable(RCC_TIM1);
81 #if USE_PWM_INPUT_TIM2
82 rcc_periph_clock_enable(RCC_TIM2);
85 #if USE_PWM_INPUT_TIM3
86 rcc_periph_clock_enable(RCC_TIM3);
89 #if USE_PWM_INPUT_TIM4
90 rcc_periph_clock_enable(RCC_TIM4);
93 #if USE_PWM_INPUT_TIM5
94 rcc_periph_clock_enable(RCC_TIM5);
97 #if USE_PWM_INPUT_TIM8
98 rcc_periph_clock_enable(RCC_TIM8);
101 #if USE_PWM_INPUT_TIM9
102 rcc_periph_clock_enable(RCC_TIM9);
106 #ifdef USE_PWM_INPUT1
115 #if USE_PWM_INPUT1 == PWM_PULSE_TYPE_ACTIVE_LOW
118 #elif USE_PWM_INPUT1 == PWM_PULSE_TYPE_ACTIVE_HIGH
131 #ifdef PWM_INPUT1_IRQ2
144 #ifdef USE_PWM_INPUT2
153 #if USE_PWM_INPUT2 == PWM_PULSE_TYPE_ACTIVE_LOW
156 #elif USE_PWM_INPUT2 == PWM_PULSE_TYPE_ACTIVE_HIGH
169 #ifdef PWM_INPUT2_IRQ2
171 nvic_enable_irq(PWM_INPUT2_IRQ2);
185 #if USE_PWM_INPUT_TIM1
188 void tim1_up_isr(
void)
190 #elif defined(STM32F4)
191 void tim1_up_tim10_isr(
void) {
193 if ((TIM1_SR & TIM_SR_UIF) != 0) {
194 timer_clear_flag(TIM1, TIM_SR_UIF);
199 void tim1_cc_isr(
void) {
201 timer_clear_flag(TIM1, TIM1_CC_IF_PERIOD);
206 timer_clear_flag(TIM1, TIM1_CC_IF_DUTY);
214 #if USE_PWM_INPUT_TIM2
216 void tim2_isr(
void) {
217 if ((TIM2_SR & TIM2_CC_IF_PERIOD) != 0) {
218 timer_clear_flag(TIM2, TIM2_CC_IF_PERIOD);
222 if ((TIM2_SR & TIM2_CC_IF_DUTY) != 0) {
223 timer_clear_flag(TIM2, TIM2_CC_IF_DUTY);
227 if ((TIM2_SR & TIM_SR_UIF) != 0) {
228 timer_clear_flag(TIM2, TIM_SR_UIF);
235 #if USE_PWM_INPUT_TIM3
237 void tim3_isr(
void) {
238 if ((TIM3_SR & TIM3_CC_IF_PERIOD) != 0) {
239 timer_clear_flag(TIM3, TIM3_CC_IF_PERIOD);
243 if ((TIM3_SR & TIM3_CC_IF_DUTY) != 0) {
244 timer_clear_flag(TIM3, TIM3_CC_IF_DUTY);
248 if ((TIM3_SR & TIM_SR_UIF) != 0) {
249 timer_clear_flag(TIM3, TIM_SR_UIF);
256 #if USE_PWM_INPUT_TIM4
258 void tim4_isr(
void) {
259 if ((TIM4_SR & TIM4_CC_IF_PERIOD) != 0) {
260 timer_clear_flag(TIM4, TIM4_CC_IF_PERIOD);
264 if ((TIM4_SR & TIM4_CC_IF_DUTY) != 0) {
265 timer_clear_flag(TIM4, TIM4_CC_IF_DUTY);
269 if ((TIM4_SR & TIM_SR_UIF) != 0) {
270 timer_clear_flag(TIM4, TIM_SR_UIF);
277 #if USE_PWM_INPUT_TIM5
279 void tim5_isr(
void) {
280 if ((TIM5_SR & TIM5_CC_IF_PERIOD) != 0) {
281 timer_clear_flag(TIM5, TIM5_CC_IF_PERIOD);
285 if ((TIM5_SR & TIM5_CC_IF_DUTY) != 0) {
286 timer_clear_flag(TIM5, TIM5_CC_IF_DUTY);
290 if ((TIM5_SR & TIM_SR_UIF) != 0) {
291 timer_clear_flag(TIM5, TIM_SR_UIF);
298 #if USE_PWM_INPUT_TIM8
301 void tim8_up_isr(
void)
303 #elif defined(STM32F4)
304 void tim8_up_tim13_isr(
void) {
306 if ((TIM8_SR & TIM_SR_UIF) != 0) {
307 timer_clear_flag(TIM8, TIM_SR_UIF);
312 void tim8_cc_isr(
void) {
313 if ((TIM8_SR & TIM8_CC_IF_PERIOD) != 0) {
314 timer_clear_flag(TIM8, TIM8_CC_IF_PERIOD);
318 if ((TIM8_SR & TIM8_CC_IF_DUTY) != 0) {
319 timer_clear_flag(TIM8, TIM8_CC_IF_DUTY);
327 #if USE_PWM_INPUT_TIM9
330 void tim1_brk_tim9_isr(
void) {
332 timer_clear_flag(TIM9, TIM9_CC_IF_PERIOD);
337 timer_clear_flag(TIM9, TIM9_CC_IF_DUTY);
341 if ((TIM9_SR & TIM_SR_UIF) != 0) {
342 timer_clear_flag(TIM9, TIM_SR_UIF);
void gpio_setup_pin_af(ioportid_t port, uint16_t pin, uint8_t af, bool is_output)
Setup a gpio for input or output with alternate function.
#define PWM_INPUT1_GPIO_PIN
Some architecture independent helper functions for GPIOs.
#define PWM_INPUT2_GPIO_AF
uint32_t timer_get_frequency(uint32_t timer_peripheral)
Get Timer clock frequency (before prescaling) Only valid if using the internal clock for the timer...
#define PWM_INPUT1_TIMER_INPUT
#define PWM_INPUT2_CHANNEL_DUTY
#define TIM1_PWM_INPUT_IDX
#define PWM_INPUT1_GPIO_PORT
Architecture independent timing functions.
#define PWM_INPUT1_GPIO_AF
#define PWM_INPUT2_TIMER_INPUT
#define PWM_INPUT1_CHANNEL_DUTY
#define PWM_INPUT2_CHANNEL_PERIOD
#define PWM_INPUT2_SLAVE_TRIG
#define PWM_INPUT1_SLAVE_TRIG
#define PWM_INPUT2_GPIO_PORT
#define PWM_INPUT2_GPIO_PIN
#define TIM9_PWM_INPUT_IDX
#define TIM1_CC_IF_PERIOD
#define TIM9_CC_IF_PERIOD
#define PWM_INPUT1_CHANNEL_PERIOD