[pwm_input] add a few timers and a second pwm_input for apogee

This commit is contained in:
Gautier Hattenberger
2015-10-16 21:38:29 +02:00
parent a891741745
commit 72776c6474
8 changed files with 151 additions and 17 deletions
+1 -1
View File
@@ -33,7 +33,7 @@
<makefile target="ap">
<file name="aoa_pwm.c" />
<define name="AOA_PWM_CHANNEL" value="$(AOA_PWM_CHANNEL)" cond="ifdef AOA_PWM_CHANNEL" />
<define name="PWM_INPUT_TICKS_PER_USEC" value="1" />
<define name="$(AOA_PWM_CHANNEL)_TICKS_PER_USEC" value="1" />
<define name="USE_$(AOA_PWM_CHANNEL)" value="PWM_PULSE_TYPE_ACTIVE_LOW" />
</makefile>
</module>
+2 -2
View File
@@ -71,8 +71,8 @@ MS_SPI_DEV_LOWER=$(shell echo $(MS_SPI_DEV) | tr A-Z a-z)
<define name="USE_SPI_SLAVE$(MS_EEPROM_SLAVE_IDX)" cond="ifdef MS_EEPROM_SLAVE_IDX"/>
<define name="MS_SPI_DEV" value="$(MS_SPI_DEV_LOWER)"/>
<define name="MS_HUMIDITY_PWM_INPUT" value="$(MS_HUMIDITY_PWM_INPUT)" cond="ifdef MS_HUMIDITY_PWM_INPUT"/>
<define name="PWM_INPUT_TICKS_PER_USEC" value="42" cond="ifdef MS_HUMIDITY_PWM_INPUT"/> <!-- set timer clock to 42 MHz -->
<define name="USE_$(MS_HUMIDITY_PWM_INPUT)" value="PWM_PULSE_TYPE_ACTIVE_LOW" cond="ifdef MS_MS_HUMIDITY_PWM_INPUT"/>
<define name="$(MS_HUMIDITY_PWM_INPUT)_TICKS_PER_USEC" value="42" cond="ifdef MS_HUMIDITY_PWM_INPUT"/> <!-- set timer clock to 42 MHz -->
<define name="USE_$(MS_HUMIDITY_PWM_INPUT)" value="PWM_PULSE_TYPE_ACTIVE_LOW" cond="ifdef MS_HUMIDITY_PWM_INPUT"/>
</makefile>
</module>
@@ -25,7 +25,7 @@
*
* handling of smt32 PWM input using a timer with capture.
*/
#include "mcu_periph/pwm_input_arch.h"
#include "mcu_periph/pwm_input.h"
#include BOARD_CONFIG
#include "generated/airframe.h"
@@ -48,13 +48,18 @@
#define PWM_INPUT_IRQ_PRIO 2
#endif
static inline void pwm_input_set_timer(uint32_t tim)
static const uint32_t pwm_input_ticks_per_usec[] = {
PWM_INPUT1_TICKS_PER_USEC,
PWM_INPUT2_TICKS_PER_USEC
};
static inline void pwm_input_set_timer(uint32_t tim, uint32_t ticks_per_usec)
{
timer_reset(tim);
timer_set_mode(tim, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_period(tim, 0xFFFF);
uint32_t timer_clk = timer_get_frequency(tim);
timer_set_prescaler(tim, (timer_clk / (PWM_INPUT_TICKS_PER_USEC * ONE_MHZ_CLK)) - 1);
timer_set_prescaler(tim, (timer_clk / (ticks_per_usec * ONE_MHZ_CLK)) - 1);
timer_enable_counter(tim);
}
@@ -76,15 +81,27 @@ void pwm_input_init(void)
*/
#if USE_PWM_INPUT_TIM1
rcc_periph_clock_enable(RCC_TIM1);
pwm_input_set_timer(TIM1);
pwm_input_set_timer(TIM1, PWM_INPUT_TIM1_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM2
rcc_periph_clock_enable(RCC_TIM2);
pwm_input_set_timer(TIM2);
pwm_input_set_timer(TIM2, PWM_INPUT_TIM2_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM3
rcc_periph_clock_enable(RCC_TIM3);
pwm_input_set_timer(TIM3);
pwm_input_set_timer(TIM3, PWM_INPUT_TIM3_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM5
rcc_periph_clock_enable(RCC_TIM5);
pwm_input_set_timer(TIM5, PWM_INPUT_TIM5_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM8
rcc_periph_clock_enable(RCC_TIM8);
pwm_input_set_timer(TIM8, PWM_INPUT_TIM8_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM9
rcc_periph_clock_enable(RCC_TIM9);
pwm_input_set_timer(TIM9, PWM_INPUT_TIM9_TICKS_PER_USEC);
#endif
#ifdef USE_PWM_INPUT1
@@ -165,6 +182,14 @@ void pwm_input_init(void)
}
uint32_t get_pwm_input_duty_in_usec(uint32_t channel) {
return pwm_input_duty_tics[channel] / pwm_input_ticks_per_usec[channel];
}
uint32_t get_pwm_input_period_in_usec(uint32_t channel) {
return pwm_input_period_tics[channel] / pwm_input_ticks_per_usec[channel];
}
#if USE_PWM_INPUT_TIM1
#if defined(STM32F1)
@@ -235,3 +260,76 @@ void tim3_isr(void) {
}
#endif
#if USE_PWM_INPUT_TIM5
void tim5_isr(void) {
if ((TIM5_SR & TIM5_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM5, TIM5_CC_IF_PERIOD);
pwm_input_period_tics[TIM5_PWM_INPUT_IDX] = TIM5_CCR_PERIOD;
pwm_input_period_valid[TIM5_PWM_INPUT_IDX] = TRUE;
}
if ((TIM5_SR & TIM5_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM5, TIM5_CC_IF_DUTY);
pwm_input_duty_tics[TIM5_PWM_INPUT_IDX] = TIM5_CCR_DUTY;
pwm_input_duty_valid[TIM5_PWM_INPUT_IDX] = TRUE;
}
if ((TIM5_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM5, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
#if USE_PWM_INPUT_TIM8
#if defined(STM32F1)
void tim8_up_isr(void)
{
#elif defined(STM32F4)
void tim8_up_tim13_isr(void) {
#endif
if ((TIM8_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM8, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
void tim8_cc_isr(void) {
if ((TIM8_SR & TIM8_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM8, TIM8_CC_IF_PERIOD);
pwm_input_period_tics[TIM8_PWM_INPUT_IDX] = TIM8_CCR_PERIOD;
pwm_input_period_valid[TIM8_PWM_INPUT_IDX] = TRUE;
}
if ((TIM8_SR & TIM8_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM8, TIM8_CC_IF_DUTY);
pwm_input_duty_tics[TIM8_PWM_INPUT_IDX] = TIM8_CCR_DUTY;
pwm_input_duty_valid[TIM8_PWM_INPUT_IDX] = TRUE;
}
}
#endif
#if USE_PWM_INPUT_TIM9
// TIM1 break interrupt (which we don't care here) and TIM9 global interrupt
void tim1_brk_tim9_isr(void) {
if ((TIM9_SR & TIM9_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM9, TIM9_CC_IF_PERIOD);
pwm_input_period_tics[TIM9_PWM_INPUT_IDX] = TIM9_CCR_PERIOD;
pwm_input_period_valid[TIM9_PWM_INPUT_IDX] = TRUE;
}
if ((TIM9_SR & TIM9_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM9, TIM9_CC_IF_DUTY);
pwm_input_duty_tics[TIM9_PWM_INPUT_IDX] = TIM9_CCR_DUTY;
pwm_input_duty_valid[TIM9_PWM_INPUT_IDX] = TRUE;
}
if ((TIM9_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM9, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
@@ -49,15 +49,13 @@ enum pwm_input_channels {
* TIM1 -> 2 * APB2 = 2 * 84MHz = 168MHz
* TIM2 -> 2 * APB1 = 2 * 42MHz = 84MHz
*/
#ifndef PWM_INPUT_TICKS_PER_USEC
#define PWM_INPUT_TICKS_PER_USEC 6
#ifndef PWM_INPUT1_TICKS_PER_USEC
#define PWM_INPUT1_TICKS_PER_USEC 6
#endif
#define PWM_INPUT_TICKS_OF_USEC(_v) ((_v)*PWM_INPUT_TICKS_PER_USEC)
#define PWM_INPUT_SIGNED_TICKS_OF_USEC(_v) (int32_t)((_v)*PWM_INPUT_TICKS_PER_USEC)
#define USEC_OF_PWM_INPUT_TICKS(_v) ((_v)/PWM_INPUT_TICKS_PER_USEC)
#include "mcu_periph/pwm_input.h"
#ifndef PWM_INPUT2_TICKS_PER_USEC
#define PWM_INPUT2_TICKS_PER_USEC 6
#endif
#endif /* PWM_INPUT_ARCH_H */
+33
View File
@@ -355,7 +355,11 @@
/*
* PWM input
*/
// PWM_INPUT1 on TIM1
#define PWM_INPUT1_TIMER TIM1
#ifdef PWM_INPUT1_TICKS_PER_USEC
#define PWM_INPUT_TIM1_TICKS_PER_USEC PWM_INPUT1_TICKS_PER_USEC
#endif
#define PWM_INPUT1_CHANNEL_PERIOD TIM_IC1
#define PWM_INPUT1_CHANNEL_DUTY TIM_IC2
#define PWM_INPUT1_TIMER_INPUT TIM_IC_IN_TI1
@@ -374,6 +378,35 @@
#define PWM_INPUT1_GPIO_PIN GPIO8
#define PWM_INPUT1_GPIO_AF GPIO_AF1
// PWM_INPUT2 on TIM9
#define PWM_INPUT2_TIMER TIM9
#ifdef PWM_INPUT2_TICKS_PER_USEC
#define PWM_INPUT_TIM9_TICKS_PER_USEC PWM_INPUT2_TICKS_PER_USEC
#endif
#define PWM_INPUT2_CHANNEL_PERIOD TIM_IC1
#define PWM_INPUT2_CHANNEL_DUTY TIM_IC2
#define PWM_INPUT2_TIMER_INPUT TIM_IC_IN_TI1
#define PWM_INPUT2_SLAVE_TRIG TIM_SMCR_TS_IT1FP1
#define PWM_INPUT2_IRQ NVIC_TIM1_BRK_TIM9_IRQ
#define PWM_INPUT2_CC_IE (TIM_DIER_CC3IE | TIM_DIER_CC4IE)
#ifdef USE_PWM_INPUT2
#define USE_PWM_INPUT_TIM9 TRUE
#else
#define USE_PWM_INPUT_TIM9 FALSE
#endif
#define TIM9_PWM_INPUT_IDX 1
#define TIM9_CC_IF_PERIOD TIM_SR_CC1IF
#define TIM9_CC_IF_DUTY TIM_SR_CC2IF
#define TIM9_CCR_PERIOD TIM9_CCR1
#define TIM9_CCR_DUTY TIM9_CCR2
// Servo 1 (aka PA2) is used: not compatible with PWM1 (and should be disabled)
#if (USE_PWM1 && USE_PWM_INPUT2)
#error "PW1 and PWM_INPUT2 are not compatible"
#endif
#define PWM_INPUT2_GPIO_PORT GPIOA
#define PWM_INPUT2_GPIO_PIN GPIO2
#define PWM_INPUT2_GPIO_AF GPIO_AF3
/*
* Spektrum
*/
+3
View File
@@ -30,3 +30,6 @@ volatile uint32_t pwm_input_duty_tics[PWM_INPUT_NB];
volatile uint8_t pwm_input_duty_valid[PWM_INPUT_NB];
volatile uint32_t pwm_input_period_tics[PWM_INPUT_NB];
volatile uint8_t pwm_input_period_valid[PWM_INPUT_NB];
__attribute__((weak)) uint32_t get_pwm_input_duty_in_usec(uint32_t channel __attribute__((unused))) { return 0; }
__attribute__((weak)) uint32_t get_pwm_input_period_in_usec(uint32_t channel __attribute__((unused))) { return 0; }
+2
View File
@@ -41,6 +41,8 @@ extern volatile uint32_t pwm_input_period_tics[PWM_INPUT_NB];
extern volatile uint8_t pwm_input_period_valid[PWM_INPUT_NB];
extern void pwm_input_init(void);
extern uint32_t get_pwm_input_duty_in_usec(uint32_t channel);
extern uint32_t get_pwm_input_period_in_usec(uint32_t channel);
#endif /* USE_PWM_INPUT */
+1 -1
View File
@@ -113,7 +113,7 @@ void aoa_pwm_update(void) {
static float prev_aoa = 0.0f;
// raw duty cycle in usec
uint32_t duty_raw = pwm_input_duty_tics[AOA_PWM_CHANNEL] / PWM_INPUT_TICKS_PER_USEC;
uint32_t duty_raw = get_pwm_input_duty_in_usec(AOA_PWM_CHANNEL);
// remove some offset if needed
aoa_pwm.raw = duty_raw - AOA_PWM_OFFSET;