diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index c10d0159..3c8c8c2c 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -533,8 +533,8 @@ /* Note: CC2S bits are writable only when the channel is OFF (CC2E = 0 in * TIMx_CCER). */ #define TIM_CCMR1_CC1S_OUT (0x0 << 0) -#define TIM_CCMR1_CC1S_IN_TI2 (0x1 << 0) -#define TIM_CCMR1_CC1S_IN_TI1 (0x2 << 0) +#define TIM_CCMR1_CC1S_IN_TI2 (0x2 << 0) +#define TIM_CCMR1_CC1S_IN_TI1 (0x1 << 0) #define TIM_CCMR1_CC1S_IN_TRC (0x3 << 0) #define TIM_CCMR1_CC1S_MASK (0x3 << 0) @@ -851,14 +851,66 @@ enum tim_oc_mode { TIM_OCM_PWM2, }; +/* Input Capture channel designators */ +enum tim_ic_id { + TIM_IC1, + TIM_IC2, + TIM_IC3, + TIM_IC4, +}; + +/* Input Capture input filter */ +enum tim_ic_filter { + TIM_IC_OFF, + TIM_IC_CK_INT_N_2, + TIM_IC_CK_INT_N_4, + TIM_IC_CK_INT_N_8, + TIM_IC_DTF_DIV_2_N_6, + TIM_IC_DTF_DIV_2_N_8, + TIM_IC_DTF_DIV_4_N_6, + TIM_IC_DTF_DIV_4_N_8, + TIM_IC_DTF_DIV_8_N_6, + TIM_IC_DTF_DIV_8_N_8, + TIM_IC_DTF_DIV_16_N_5, + TIM_IC_DTF_DIV_16_N_6, + TIM_IC_DTF_DIV_16_N_8, + TIM_IC_DTF_DIV_32_N_5, + TIM_IC_DTF_DIV_32_N_6, + TIM_IC_DTF_DIV_32_N_8, +}; + +/* Input Capture input prescaler */ +enum tim_ic_psc { + TIM_IC_PSC_OFF, + TIM_IC_PSC_2, + TIM_IC_PSC_4, + TIM_IC_PSC_8, +}; + +/* Input Capture input prescaler */ +enum tim_ic_input { + TIM_IC_OUT = 0, + TIM_IC_IN_TI1 = 1, + TIM_IC_IN_TI2 = 2, + TIM_IC_IN_TRC = 3, + TIM_IC_IN_TI3 = 5, + TIM_IC_IN_TI4 = 6, +}; + +/* Input Capture input prescaler */ +enum tim_ic_pol { + TIM_IC_RISING, + TIM_IC_FALLING, +}; + /* --- TIM functions ------------------------------------------------------- */ void timer_reset(u32 timer_peripheral); void timer_enable_irq(u32 timer_peripheral, u32 irq); void timer_disable_irq(u32 timer_peripheral, u32 irq); bool timer_get_flag(u32 timer_peripheral, u32 flag); void timer_clear_flag(u32 timer_peripheral, u32 flag); -void timer_set_mode(u32 timer_peripheral, u8 clock_div, - u8 alignment, u8 direction); +void timer_set_mode(u32 timer_peripheral, u32 clock_div, + u32 alignment, u32 direction); void timer_set_clock_division(u32 timer_peripheral, u32 clock_div); void timer_enable_preload(u32 timer_peripheral); void timer_disable_preload(u32 timer_peripheral); @@ -918,4 +970,17 @@ void timer_set_deadtime(u32 timer_peripheral, u32 deadtime); void timer_generate_event(u32 timer_peripheral, u32 event); u32 timer_get_counter(u32 timer_peripheral); +void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt); +void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc); +void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in); +void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol); +void timer_ic_enable(u32 timer, enum tim_ic_id ic); +void timer_ic_disable(u32 timer, enum tim_ic_id ic); + +void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt); +void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc); +void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol); +void timer_slave_set_mode(u32 timer, u8 mode); +void timer_slave_set_trigger(u32 timer, u8 trigger); + #endif diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c index 8c32670e..cf5b4113 100644 --- a/lib/stm32/f1/timer.c +++ b/lib/stm32/f1/timer.c @@ -118,8 +118,8 @@ void timer_clear_flag(u32 timer_peripheral, u32 flag) TIM_SR(timer_peripheral) &= ~flag; } -void timer_set_mode(u32 timer_peripheral, u8 clock_div, - u8 alignment, u8 direction) +void timer_set_mode(u32 timer_peripheral, u32 clock_div, + u32 alignment, u32 direction) { u32 cr1; @@ -914,3 +914,128 @@ u32 timer_get_counter(u32 timer_peripheral) { return TIM_CNT(timer_peripheral); } + +void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt) +{ + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1F_MASK; + TIM_CCMR1(timer) |= flt << 4; + break; + case TIM_IC2: + TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2F_MASK; + TIM_CCMR1(timer) |= flt << 12; + break; + case TIM_IC3: + TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3F_MASK; + TIM_CCMR2(timer) |= flt << 4; + break; + case TIM_IC4: + TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4F_MASK; + TIM_CCMR2(timer) |= flt << 12; + break; + } +} + +void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc) +{ + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1PSC_MASK; + TIM_CCMR1(timer) |= psc << 2; + break; + case TIM_IC2: + TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2PSC_MASK; + TIM_CCMR1(timer) |= psc << 10; + break; + case TIM_IC3: + TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3PSC_MASK; + TIM_CCMR2(timer) |= psc << 4; + break; + case TIM_IC4: + TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4PSC_MASK; + TIM_CCMR2(timer) |= psc << 10; + break; + } +} + +void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) +{ + in &= 3; + + if (((ic == TIM_IC2) || (ic == TIM_IC4)) && + ((in == TIM_IC_IN_TI1) || (in = TIM_IC_IN_TI2))) { + /* Input select bits are flipped for these combinations */ + in ^= 3; + } + + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer) |= in; + break; + case TIM_IC2: + TIM_CCMR1(timer) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer) |= in << 8; + break; + case TIM_IC3: + TIM_CCMR2(timer) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR2(timer) |= in; + break; + case TIM_IC4: + TIM_CCMR2(timer) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR2(timer) |= in << 8; + break; + } +} + +void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) +{ + if (pol) + TIM_CCER(timer) |= (0x2 << (ic * 4)); + else + TIM_CCER(timer) &= ~(0x2 << (ic * 4)); +} + +void timer_ic_enable(u32 timer, enum tim_ic_id ic) +{ + TIM_CCER(timer) |= (0x1 << (ic * 4)); +} + +void timer_ic_disable(u32 timer, enum tim_ic_id ic) +{ + TIM_CCER(timer) &= ~(0x1 << (ic * 4)); +} + +void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt) +{ + TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK; + TIM_SMCR(timer) |= flt << 8; +} + +void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc) +{ + TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK; + TIM_SMCR(timer) |= psc << 12; +} + +void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) +{ + if (pol) + TIM_SMCR(timer) |= TIM_SMCR_ETP; + else + TIM_SMCR(timer) &= ~TIM_SMCR_ETP; +} + +void timer_slave_set_mode(u32 timer, u8 mode) +{ + TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK; + TIM_SMCR(timer) |= mode; +} + +void timer_slave_set_trigger(u32 timer, u8 trigger) +{ + TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK; + TIM_SMCR(timer) |= trigger; +} + diff --git a/lib/stm32/f2/timer.c b/lib/stm32/f2/timer.c index 3cd5e919..659f8a99 100644 --- a/lib/stm32/f2/timer.c +++ b/lib/stm32/f2/timer.c @@ -119,8 +119,8 @@ void timer_clear_flag(u32 timer_peripheral, u32 flag) TIM_SR(timer_peripheral) &= ~flag; } -void timer_set_mode(u32 timer_peripheral, u8 clock_div, - u8 alignment, u8 direction) +void timer_set_mode(u32 timer_peripheral, u32 clock_div, + u32 alignment, u32 direction) { u32 cr1; diff --git a/lib/stm32/f4/timer.c b/lib/stm32/f4/timer.c index bb7b0e7e..6d5ab9df 100644 --- a/lib/stm32/f4/timer.c +++ b/lib/stm32/f4/timer.c @@ -119,8 +119,8 @@ void timer_clear_flag(u32 timer_peripheral, u32 flag) TIM_SR(timer_peripheral) &= ~flag; } -void timer_set_mode(u32 timer_peripheral, u8 clock_div, - u8 alignment, u8 direction) +void timer_set_mode(u32 timer_peripheral, u32 clock_div, + u32 alignment, u32 direction) { u32 cr1;