Paparazzi UAS  v5.0.5_stable-7-g4b8bbb7
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
actuators_pwm_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 The Paparazzi Team
3  *
4  * This file is part of Paparazzi.
5  *
6  * Paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
26 #include "subsystems/actuators/actuators_pwm_arch.h"
28 
29 #include <libopencm3/stm32/gpio.h>
30 #include <libopencm3/stm32/rcc.h>
31 #include <libopencm3/stm32/timer.h>
32 
34 
35 #if defined(STM32F1)
36 //#define PCLK 72000000
37 #define PCLK AHB_CLK
38 #elif defined(STM32F4)
39 //#define PCLK 84000000
40 #define PCLK AHB_CLK/2
41 #endif
42 
43 #define ONE_MHZ_CLK 1000000
44 
45 #ifndef SERVO_HZ
46 #define SERVO_HZ 40
47 #endif
48 
49 // Update rate can be adapted for each timer
50 #ifndef TIM1_SERVO_HZ
51 #define TIM1_SERVO_HZ SERVO_HZ
52 #endif
53 #ifndef TIM2_SERVO_HZ
54 #define TIM2_SERVO_HZ SERVO_HZ
55 #endif
56 #ifndef TIM3_SERVO_HZ
57 #define TIM3_SERVO_HZ SERVO_HZ
58 #endif
59 #ifndef TIM4_SERVO_HZ
60 #define TIM4_SERVO_HZ SERVO_HZ
61 #endif
62 #ifndef TIM5_SERVO_HZ
63 #define TIM5_SERVO_HZ SERVO_HZ
64 #endif
65 
68 static inline void actuators_pwm_arch_channel_init(u32 timer_peripheral,
69  enum tim_oc_id oc_id) {
70 
71  timer_disable_oc_output(timer_peripheral, oc_id);
72  timer_disable_oc_clear(timer_peripheral, oc_id);
73  timer_enable_oc_preload(timer_peripheral, oc_id);
74  timer_set_oc_slow_mode(timer_peripheral, oc_id);
75  timer_set_oc_mode(timer_peripheral, oc_id, TIM_OCM_PWM1);
76  timer_set_oc_polarity_high(timer_peripheral, oc_id);
77  timer_enable_oc_output(timer_peripheral, oc_id);
78 }
79 
82 #if defined(STM32F4)
83 static inline void set_servo_gpio(u32 gpioport, u16 pin, u8 af_num, u32 en) {
84  rcc_peripheral_enable_clock(&RCC_AHB1ENR, en);
85  gpio_mode_setup(gpioport, GPIO_MODE_AF, GPIO_PUPD_NONE, pin);
86  gpio_set_af(gpioport, af_num, pin);
87 }
88 #elif defined(STM32F1)
89 static inline void set_servo_gpio(u32 gpioport, u16 pin, u8 none, u32 en) {
90  rcc_peripheral_enable_clock(&RCC_APB2ENR, en | RCC_APB2ENR_AFIOEN);
91  gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
92  GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, pin);
93 }
94 #endif
95 
98 static inline void set_servo_timer(u32 timer, u32 period, u8 channels_mask) {
99  timer_reset(timer);
100 
101  /* Timer global mode:
102  * - No divider.
103  * - Alignement edge.
104  * - Direction up.
105  */
106  timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
107 
108  timer_set_prescaler(timer, (PCLK / ONE_MHZ_CLK) - 1); // 1uS
109 
110  timer_disable_preload(timer);
111 
112  timer_continuous_mode(timer);
113 
114  timer_set_period(timer, (ONE_MHZ_CLK / period) - 1);
115 
116  /* Disable outputs and configure channel if needed. */
117  if (bit_is_set(channels_mask, 0)) {
118  actuators_pwm_arch_channel_init(timer, TIM_OC1);
119  }
120  if (bit_is_set(channels_mask, 1)) {
121  actuators_pwm_arch_channel_init(timer, TIM_OC2);
122  }
123  if (bit_is_set(channels_mask, 2)) {
124  actuators_pwm_arch_channel_init(timer, TIM_OC3);
125  }
126  if (bit_is_set(channels_mask, 3)) {
127  actuators_pwm_arch_channel_init(timer, TIM_OC4);
128  }
129 
130  /*
131  * Set initial output compare values.
132  * Note: Maybe we should preload the compare registers with some sensible
133  * values before we enable the timer?
134  */
135  //timer_set_oc_value(timer, TIM_OC1, 1000);
136  //timer_set_oc_value(timer, TIM_OC2, 1000);
137  //timer_set_oc_value(timer, TIM_OC3, 1000);
138  //timer_set_oc_value(timer, TIM_OC4, 1000);
139 
140  /* -- Enable timer -- */
141  /*
142  * ARR reload enable.
143  * Note: In our case it does not matter much if we do preload or not. As it
144  * is unlikely we will want to change the frequency of the timer during
145  * runtime anyways.
146  */
147  timer_enable_preload(timer);
148 
149  /* Counter enable. */
150  timer_enable_counter(timer);
151 }
152 
156 
157  /*-----------------------------------
158  * Configure timer peripheral clocks
159  *-----------------------------------*/
160 #if PWM_USE_TIM1
161  rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
162 #endif
163 #if PWM_USE_TIM2
164  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN);
165 #endif
166 #if PWM_USE_TIM3
167  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM3EN);
168 #endif
169 #if PWM_USE_TIM4
170  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM4EN);
171 #endif
172 #if PWM_USE_TIM5
173  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM5EN);
174 #endif
175 
176  /*----------------
177  * Configure GPIO
178  *----------------*/
179 #ifdef PWM_SERVO_0
181 #endif
182 #ifdef PWM_SERVO_1
184 #endif
185 #ifdef PWM_SERVO_2
187 #endif
188 #ifdef PWM_SERVO_3
190 #endif
191 #ifdef PWM_SERVO_4
193 #endif
194 #ifdef PWM_SERVO_5
196 #endif
197 #ifdef PWM_SERVO_6
199 #endif
200 #ifdef PWM_SERVO_7
202 #endif
203 #ifdef PWM_SERVO_8
205 #endif
206 #if defined(STM32F1) && PWM_USE_TIM3
207  /* TIM3 GPIO for PWM1..4 */
208  AFIO_MAPR |= AFIO_MAPR_TIM3_REMAP_FULL_REMAP;
209 #endif
210 
211 #if PWM_USE_TIM1
212  set_servo_timer(TIM1, TIM1_SERVO_HZ, PWM_TIM1_CHAN_MASK);
213 #endif
214 
215 #if PWM_USE_TIM2
217 #endif
218 
219 #if PWM_USE_TIM3
221 #endif
222 
223 #if PWM_USE_TIM4
225 #endif
226 
227 #if PWM_USE_TIM5
229 #endif
230 
231 }
232 
236 #ifdef PWM_SERVO_0
238 #endif
239 #ifdef PWM_SERVO_1
241 #endif
242 #ifdef PWM_SERVO_2
244 #endif
245 #ifdef PWM_SERVO_3
247 #endif
248 #ifdef PWM_SERVO_4
250 #endif
251 #ifdef PWM_SERVO_5
253 #endif
254 #ifdef PWM_SERVO_6
256 #endif
257 #ifdef PWM_SERVO_7
259 #endif
260 #ifdef PWM_SERVO_8
262 #endif
263 
264 }
static void actuators_pwm_arch_channel_init(u32 timer_peripheral, enum tim_oc_id oc_id)
Set PWM channel configuration.
#define PWM_SERVO_0_OC
Definition: apogee_0.99.h:196
#define PWM_SERVO_6_OC
Definition: krooz_sd.h:318
#define PWM_SERVO_0_PIN
Definition: apogee_0.99.h:194
#define PWM_SERVO_5_OC
Definition: apogee_0.99.h:261
#define PWM_SERVO_6_RCC_IOP
Definition: krooz_sd.h:314
#define PWM_SERVO_7_AF
Definition: krooz_sd.h:330
#define PWM_SERVO_2_OC
Definition: apogee_0.99.h:222
#define PWM_SERVO_0
Definition: apogee_0.99.h:190
#define PWM_SERVO_4_AF
Definition: apogee_0.99.h:247
#define PWM_SERVO_3_OC
Definition: apogee_0.99.h:235
#define PWM_SERVO_8_TIMER
Definition: krooz_sd.h:339
#define PWM_SERVO_8_GPIO
Definition: krooz_sd.h:341
#define PWM_TIM3_CHAN_MASK
Definition: apogee_0.99.h:270
#define PWM_SERVO_1_GPIO
Definition: apogee_0.99.h:206
#define PWM_SERVO_1_OC
Definition: apogee_0.99.h:209
#define PWM_SERVO_4_OC
Definition: apogee_0.99.h:248
#define PWM_SERVO_3_AF
Definition: apogee_0.99.h:234
#define TIM5_SERVO_HZ
void actuators_pwm_commit(void)
Set pulse widths from actuator values, assumed to be in us.
#define PCLK
Definition: booz_1.0.h:18
#define PWM_SERVO_2_GPIO
Definition: apogee_0.99.h:219
#define PWM_SERVO_4_RCC_IOP
Definition: apogee_0.99.h:244
#define PWM_SERVO_4
Definition: apogee_0.99.h:242
#define PWM_SERVO_8_PIN
Definition: krooz_sd.h:342
#define ONE_MHZ_CLK
#define PWM_SERVO_5_RCC_IOP
Definition: apogee_0.99.h:257
#define PWM_SERVO_2
Definition: apogee_0.99.h:216
#define PWM_SERVO_7_TIMER
Definition: krooz_sd.h:326
#define PWM_SERVO_6_TIMER
Definition: krooz_sd.h:313
#define PWM_SERVO_3_PIN
Definition: apogee_0.99.h:233
#define PWM_SERVO_7_RCC_IOP
Definition: krooz_sd.h:327
#define TIM2_SERVO_HZ
#define PWM_TIM2_CHAN_MASK
Definition: apogee_0.99.h:269
#define TIM3_SERVO_HZ
#define PWM_TIM4_CHAN_MASK
Definition: krooz_sd.h:378
#define PWM_SERVO_8_AF
Definition: krooz_sd.h:343
#define PWM_SERVO_1_AF
Definition: apogee_0.99.h:208
#define PWM_SERVO_1
Definition: apogee_0.99.h:203
#define PWM_SERVO_2_AF
Definition: apogee_0.99.h:221
int32_t actuators_pwm_values[ACTUATORS_PWM_NB]
#define PWM_SERVO_8
Definition: krooz_sd.h:338
#define PWM_SERVO_3_GPIO
Definition: apogee_0.99.h:232
#define PWM_SERVO_0_GPIO
Definition: apogee_0.99.h:193
#define PWM_SERVO_6_PIN
Definition: krooz_sd.h:316
#define TIM1_SERVO_HZ
#define PWM_SERVO_1_TIMER
Definition: apogee_0.99.h:204
#define TIM4_SERVO_HZ
#define PWM_SERVO_7_GPIO
Definition: krooz_sd.h:328
#define PWM_SERVO_3_TIMER
Definition: apogee_0.99.h:230
#define PWM_SERVO_6
Definition: krooz_sd.h:312
#define PWM_SERVO_3_RCC_IOP
Definition: apogee_0.99.h:231
#define PWM_SERVO_1_PIN
Definition: apogee_0.99.h:207
#define PWM_SERVO_7_OC
Definition: krooz_sd.h:331
#define PWM_TIM5_CHAN_MASK
Definition: krooz_sd.h:379
#define PWM_SERVO_8_RCC_IOP
Definition: krooz_sd.h:340
#define PWM_SERVO_0_TIMER
Definition: apogee_0.99.h:191
#define PWM_SERVO_5
Definition: apogee_0.99.h:255
#define PWM_SERVO_7_PIN
Definition: krooz_sd.h:329
#define PWM_SERVO_6_AF
Definition: krooz_sd.h:317
#define PWM_SERVO_5_GPIO
Definition: apogee_0.99.h:258
#define ACTUATORS_PWM_NB
#define PWM_SERVO_1_RCC_IOP
Definition: apogee_0.99.h:205
signed long int32_t
Definition: types.h:19
#define PWM_SERVO_2_TIMER
Definition: apogee_0.99.h:217
#define PWM_SERVO_3
Definition: lisa_l_1.0.h:212
#define PWM_SERVO_0_AF
Definition: apogee_0.99.h:195
#define PWM_SERVO_4_PIN
Definition: apogee_0.99.h:246
#define PWM_SERVO_8_OC
Definition: krooz_sd.h:344
#define PWM_SERVO_2_PIN
Definition: apogee_0.99.h:220
#define PWM_SERVO_5_AF
Definition: apogee_0.99.h:260
#define PWM_SERVO_0_RCC_IOP
Definition: apogee_0.99.h:192
#define PWM_SERVO_4_GPIO
Definition: apogee_0.99.h:245
static void set_servo_timer(u32 timer, u32 period, u8 channels_mask)
Set GPIO configuration.
#define PWM_SERVO_7
Definition: krooz_sd.h:325
#define PWM_SERVO_4_TIMER
Definition: apogee_0.99.h:243
#define PWM_SERVO_6_GPIO
Definition: krooz_sd.h:315
void actuators_pwm_arch_init(void)
Arch dependent init file.
#define PWM_SERVO_5_PIN
Definition: apogee_0.99.h:259
#define PWM_SERVO_5_TIMER
Definition: apogee_0.99.h:256
#define PWM_SERVO_2_RCC_IOP
Definition: apogee_0.99.h:218