[stm32] actuators_pwm: add TIM1,8,9 and 12

This commit is contained in:
hendrixgr
2013-09-11 22:34:09 +03:00
committed by Felix Ruess
parent dcd5fab03e
commit b8d3b4794d
@@ -23,6 +23,8 @@
* STM32 PWM servos handling.
*/
//VALID TIMERS ARE TIM1,2,3,4,5,8,9,12
#include "subsystems/actuators/actuators_pwm_arch.h"
#include "subsystems/actuators/actuators_pwm.h"
@@ -41,6 +43,7 @@ int32_t actuators_pwm_values[ACTUATORS_PWM_NB];
#endif
#define ONE_MHZ_CLK 1000000
/** Default servo update rate in Hz */
#ifndef SERVO_HZ
#define SERVO_HZ 40
@@ -62,19 +65,31 @@ int32_t actuators_pwm_values[ACTUATORS_PWM_NB];
#ifndef TIM5_SERVO_HZ
#define TIM5_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM9_SERVO_HZ
#define TIM9_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM12_SERVO_HZ
#define TIM12_SERVO_HZ SERVO_HZ
#endif
/** Set PWM channel configuration
*/
static inline void actuators_pwm_arch_channel_init(uint32_t timer_peripheral,
enum tim_oc_id oc_id) {
enum tim_oc_id oc_id) {
timer_disable_oc_output(timer_peripheral, oc_id);
timer_disable_oc_clear(timer_peripheral, oc_id);
//There is no such register in TIM9 and 12.
if (timer_peripheral != TIM9 && timer_peripheral != TIM12){
timer_disable_oc_clear(timer_peripheral, oc_id);
}
timer_enable_oc_preload(timer_peripheral, oc_id);
timer_set_oc_slow_mode(timer_peripheral, oc_id);
timer_set_oc_mode(timer_peripheral, oc_id, TIM_OCM_PWM1);
timer_set_oc_polarity_high(timer_peripheral, oc_id);
timer_enable_oc_output(timer_peripheral, oc_id);
// Used for TIM1 and TIM8, the function does nothing if other timer is specified.
timer_enable_break_main_output(timer_peripheral);
}
/** Set GPIO configuration
@@ -103,9 +118,22 @@ static inline void set_servo_timer(uint32_t timer, uint32_t period, uint8_t chan
* - Alignement edge.
* - Direction up.
*/
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
if (timer != TIM9 && timer != TIM12 ) {
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_prescaler(timer, (PCLK / ONE_MHZ_CLK) - 1); // 1uS
} else {
//There are no EDGE and DIR settings in TIM9 and TIM12
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
}
//TIM9, 1 and 8 use APB2 clock which runs at double speed (APB1 X2).
if (timer != TIM9 && timer != TIM1 && timer != TIM8) {
timer_set_prescaler(timer, (PCLK / ONE_MHZ_CLK) - 1); // 1uS
} else {
// 1uS, APB2 runs on double the frequency of APB1.
timer_set_prescaler(timer, ((PCLK / ONE_MHZ_CLK)*2) - 1);
}
timer_disable_preload(timer);
@@ -148,6 +176,7 @@ static inline void set_servo_timer(uint32_t timer, uint32_t period, uint8_t chan
/* Counter enable. */
timer_enable_counter(timer);
}
/** PWM arch init called by generic pwm driver
@@ -158,6 +187,7 @@ void actuators_pwm_arch_init(void) {
* Configure timer peripheral clocks
*-----------------------------------*/
#if PWM_USE_TIM1
// APB2 runs on double the frequency of APB1.
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
#endif
#if PWM_USE_TIM2
@@ -172,6 +202,17 @@ void actuators_pwm_arch_init(void) {
#if PWM_USE_TIM5
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM5EN);
#endif
#if PWM_USE_TIM8
// APB2 runs on double the frequency of APB1.
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM8EN);
#endif
#if PWM_USE_TIM9
// APB2 runs on double the frequency of APB1.
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM9EN);
#endif
#if PWM_USE_TIM12
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM12EN);
#endif
/*----------------
* Configure GPIO
@@ -211,6 +252,12 @@ void actuators_pwm_arch_init(void) {
#ifdef PWM_SERVO_9
set_servo_gpio(PWM_SERVO_9_GPIO, PWM_SERVO_9_PIN, PWM_SERVO_9_AF, PWM_SERVO_9_RCC_IOP);
#endif
#ifdef PWM_SERVO_10
set_servo_gpio(PWM_SERVO_10_GPIO, PWM_SERVO_10_PIN, PWM_SERVO_10_AF, PWM_SERVO_10_RCC_IOP);
#endif
#ifdef PWM_SERVO_11
set_servo_gpio(PWM_SERVO_11_GPIO, PWM_SERVO_11_PIN, PWM_SERVO_11_AF, PWM_SERVO_11_RCC_IOP);
#endif
#if PWM_USE_TIM1
@@ -233,6 +280,18 @@ void actuators_pwm_arch_init(void) {
set_servo_timer(TIM5, TIM5_SERVO_HZ, PWM_TIM5_CHAN_MASK);
#endif
#if PWM_USE_TIM8
set_servo_timer(TIM8, TIM8_SERVO_HZ, PWM_TIM8_CHAN_MASK);
#endif
#if PWM_USE_TIM9
set_servo_timer(TIM9, TIM9_SERVO_HZ, PWM_TIM9_CHAN_MASK);
#endif
#if PWM_USE_TIM12
set_servo_timer(TIM12, TIM12_SERVO_HZ, PWM_TIM12_CHAN_MASK);
#endif
}
/** Set pulse widths from actuator values, assumed to be in us
@@ -268,5 +327,11 @@ void actuators_pwm_commit(void) {
#ifdef PWM_SERVO_9
timer_set_oc_value(PWM_SERVO_9_TIMER, PWM_SERVO_9_OC, actuators_pwm_values[PWM_SERVO_9]);
#endif
#ifdef PWM_SERVO_10
timer_set_oc_value(PWM_SERVO_10_TIMER, PWM_SERVO_10_OC, actuators_pwm_values[PWM_SERVO_10]);
#endif
#ifdef PWM_SERVO_11
timer_set_oc_value(PWM_SERVO_11_TIMER, PWM_SERVO_11_OC, actuators_pwm_values[PWM_SERVO_11]);
#endif
}