Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ppm_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 
36 
37 #include BOARD_CONFIG
38 
39 #include <libopencm3/stm32/rcc.h>
40 #include <libopencm3/stm32/gpio.h>
41 #include <libopencm3/stm32/timer.h>
42 #include <libopencm3/cm3/nvic.h>
43 
44 #include "mcu_periph/sys_time.h"
45 #include "mcu_periph/gpio.h"
46 
47 // for timer_get_frequency
48 #include "mcu_arch.h"
49 
50 #define ONE_MHZ_CLK 1000000
51 #ifdef NVIC_TIM_IRQ_PRIO
52 #define PPM_IRQ_PRIO NVIC_TIM_IRQ_PRIO
53 #else
54 #define PPM_IRQ_PRIO 2
55 #endif
56 
57 
62 
63 
64 #if USE_PPM_TIM2
65 
66 PRINT_CONFIG_MSG("Using TIM2 for PPM input.")
67 #define PPM_TIMER TIM2
68 #define RCC_TIM_PPM RCC_TIM2
69 
70 #elif USE_PPM_TIM3
71 
72 PRINT_CONFIG_MSG("Using TIM3 for PPM input.")
73 #define PPM_TIMER TIM3
74 #define RCC_TIM_PPM RCC_TIM3
75 
76 #elif USE_PPM_TIM4
77 
78 PRINT_CONFIG_MSG("Using TIM4 for PPM input.")
79 #define PPM_TIMER TIM4
80 #define RCC_TIM_PPM RCC_TIM4
81 
82 #elif USE_PPM_TIM5
83 
84 PRINT_CONFIG_MSG("Using TIM5 for PPM input.")
85 #define PPM_TIMER TIM5
86 #define RCC_TIM_PPM RCC_TIM5
87 
88 #elif USE_PPM_TIM1
89 
90 PRINT_CONFIG_MSG("Using TIM1 for PPM input.")
91 #define PPM_TIMER TIM1
92 #define RCC_TIM_PPM RCC_TIM1
93 
94 #elif USE_PPM_TIM8
95 
96 PRINT_CONFIG_MSG("Using TIM8 for PPM input.")
97 #define PPM_TIMER TIM8
98 #define RCC_TIM_PPM RCC_TIM8
99 
100 #else
101 #error Unknown PPM input timer configuration.
102 #endif
103 
104 void ppm_arch_init ( void ) {
105 
106  /* timer clock enable */
107  rcc_periph_clock_enable(RCC_TIM_PPM);
108 
109  /* GPIO configuration as input capture for timer */
111 
112  /* Time Base configuration */
113  timer_reset(PPM_TIMER);
114  timer_set_mode(PPM_TIMER, TIM_CR1_CKD_CK_INT,
115  TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
116  timer_set_period(PPM_TIMER, 0xFFFF);
117  uint32_t timer_clk = timer_get_frequency(PPM_TIMER);
118  timer_set_prescaler(PPM_TIMER, (timer_clk / (RC_PPM_TICKS_PER_USEC*ONE_MHZ_CLK)) - 1);
119 
120  /* TIM configuration: Input Capture mode ---------------------
121  The Rising edge is used as active edge
122  ------------------------------------------------------------ */
123 #if defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_POSITIVE
124  timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_RISING);
125 #elif defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_NEGATIVE
126  timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_FALLING);
127 #else
128 #error "Unknown PPM_PULSE_TYPE"
129 #endif
130  timer_ic_set_input(PPM_TIMER, PPM_CHANNEL, PPM_TIMER_INPUT);
131  timer_ic_set_prescaler(PPM_TIMER, PPM_CHANNEL, TIM_IC_PSC_OFF);
132  timer_ic_set_filter(PPM_TIMER, PPM_CHANNEL, TIM_IC_OFF);
133 
134  /* Enable timer Interrupt(s). */
135  nvic_set_priority(PPM_IRQ, PPM_IRQ_PRIO);
136  nvic_enable_irq(PPM_IRQ);
137 
138 #ifdef PPM_IRQ2
139  nvic_set_priority(PPM_IRQ2, PPM_IRQ_PRIO);
140  nvic_enable_irq(PPM_IRQ2);
141 #endif
142 
143  /* Enable the Capture/Compare and Update interrupt requests. */
144  timer_enable_irq(PPM_TIMER, (PPM_CC_IE | TIM_DIER_UIE));
145 
146  /* Enable capture channel. */
147  timer_ic_enable(PPM_TIMER, PPM_CHANNEL);
148 
149  /* TIM enable counter */
150  timer_enable_counter(PPM_TIMER);
151 
154  timer_rollover_cnt = 0;
155 
156 }
157 
158 #if USE_PPM_TIM2
159 
160 void tim2_isr(void) {
161 
162  if((TIM2_SR & PPM_CC_IF) != 0) {
163  timer_clear_flag(TIM2, PPM_CC_IF);
164 
165  uint32_t now = timer_get_counter(TIM2) + timer_rollover_cnt;
166  DecodePpmFrame(now);
167  }
168  else if((TIM2_SR & TIM_SR_UIF) != 0) {
169  timer_rollover_cnt+=(1<<16);
170  timer_clear_flag(TIM2, TIM_SR_UIF);
171  }
172 
173 }
174 
175 
176 #elif USE_PPM_TIM3
177 
178 void tim3_isr(void) {
179 
180  if((TIM3_SR & PPM_CC_IF) != 0) {
181  timer_clear_flag(TIM3, PPM_CC_IF);
182 
183  uint32_t now = timer_get_counter(TIM3) + timer_rollover_cnt;
184  DecodePpmFrame(now);
185  }
186  else if((TIM3_SR & TIM_SR_UIF) != 0) {
187  timer_rollover_cnt+=(1<<16);
188  timer_clear_flag(TIM3, TIM_SR_UIF);
189  }
190 
191 }
192 
193 #elif USE_PPM_TIM4
194 
195 void tim4_isr(void) {
196 
197  if((TIM4_SR & PPM_CC_IF) != 0) {
198  timer_clear_flag(TIM4, PPM_CC_IF);
199 
200  uint32_t now = timer_get_counter(TIM4) + timer_rollover_cnt;
201  DecodePpmFrame(now);
202  }
203  else if((TIM4_SR & TIM_SR_UIF) != 0) {
204  timer_rollover_cnt+=(1<<16);
205  timer_clear_flag(TIM4, TIM_SR_UIF);
206  }
207 
208 }
209 
210 #elif USE_PPM_TIM5
211 
212 void tim5_isr(void) {
213 
214  if((TIM5_SR & PPM_CC_IF) != 0) {
215  timer_clear_flag(TIM5, PPM_CC_IF);
216 
217  uint32_t now = timer_get_counter(TIM5) + timer_rollover_cnt;
218  DecodePpmFrame(now);
219  }
220  else if((TIM5_SR & TIM_SR_UIF) != 0) {
221  timer_rollover_cnt+=(1<<16);
222  timer_clear_flag(TIM5, TIM_SR_UIF);
223  }
224 
225 }
226 
227 
228 #elif USE_PPM_TIM1
229 
230 #if defined(STM32F1)
231 void tim1_up_isr(void) {
232 #elif defined(STM32F4)
233 void tim1_up_tim10_isr(void) {
234 #endif
235  if((TIM1_SR & TIM_SR_UIF) != 0) {
236  timer_rollover_cnt+=(1<<16);
237  timer_clear_flag(TIM1, TIM_SR_UIF);
238  }
239 }
240 
241 void tim1_cc_isr(void) {
242  if((TIM1_SR & PPM_CC_IF) != 0) {
243  timer_clear_flag(TIM1, PPM_CC_IF);
244 
245  uint32_t now = timer_get_counter(TIM1) + timer_rollover_cnt;
246  DecodePpmFrame(now);
247  }
248 }
249 
250 #elif USE_PPM_TIM8 && defined(STM32F4)
251 
252 #if defined(STM32F1)
253 void tim8_up_isr(void) {
254 #elif defined(STM32F4)
255 void tim8_up_tim13_isr(void) {
256 #endif
257  if((TIM8_SR & TIM_SR_UIF) != 0) {
258  timer_rollover_cnt+=(1<<16);
259  timer_clear_flag(TIM8, TIM_SR_UIF);
260  }
261 }
262 
263 void tim8_cc_isr(void) {
264  if((TIM8_SR & PPM_CC_IF) != 0) {
265  timer_clear_flag(TIM8, PPM_CC_IF);
266 
267  uint32_t now = timer_get_counter(TIM8) + timer_rollover_cnt;
268  DecodePpmFrame(now);
269  }
270 }
271 
272 #endif /* USE_PPM_TIM1 */
273 
CM3_WEAK tim8_cc_isr(void)
timer_clear_flag(TIM6, TIM_SR_UIF)
CM3_WEAK tim2_isr(void)
uint32_t ppm_last_pulse_time
Definition: ppm_arch.c:26
bool_t ppm_data_valid
Definition: ppm_arch.c:27
void ppm_arch_init(void)
Architecture dependant code.
Definition: ppm_arch.c:29
CM3_WEAK tim3_isr(void)
#define RC_PPM_TICKS_PER_USEC
The ppm counter is set-up to have 1/6 us resolution.
Definition: ppm_arch.h:46
Some architecture independent helper functions for GPIOs.
CM3_WEAK tim1_cc_isr(void)
#define ONE_MHZ_CLK
Definition: ppm_arch.c:50
#define PPM_TIMER_INPUT
Definition: apogee_0.99.h:248
#define PPM_GPIO_AF
Definition: apogee_0.99.h:256
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...
Definition: mcu_arch.c:139
#define PPM_CHANNEL
Definition: apogee_0.99.h:247
#define FALSE
Definition: imu_chimu.h:141
uint8_t ppm_cur_pulse
State machine for decoding ppm frames.
Definition: ppm_arch.c:25
#define PPM_IRQ2
Definition: apogee_0.99.h:250
CM3_WEAK tim1_up_tim10_isr(void)
Architecture independent timing functions.
unsigned long uint32_t
Definition: types.h:18
#define DecodePpmFrame(_ppm_time)
A valid ppm frame:
Definition: ppm.h:97
void gpio_setup_pin_af(uint32_t port, uint16_t pin, uint8_t af, bool_t is_output)
Setup a gpio for input or output with alternate function.
#define PPM_IRQ_PRIO
Definition: ppm_arch.c:54
#define RADIO_CONTROL_NB_CHANNEL
Definition: spektrum_arch.h:34
CM3_WEAK tim4_isr(void)
unsigned char uint8_t
Definition: types.h:14
#define PPM_GPIO_PIN
Definition: apogee_0.99.h:255
static uint32_t timer_rollover_cnt
Definition: ppm_arch.c:61
CM3_WEAK tim8_up_tim13_isr(void)
#define PPM_GPIO_PORT
Definition: apogee_0.99.h:254
#define PPM_CC_IE
Definition: apogee_0.99.h:252
CM3_WEAK tim5_isr(void)
#define PPM_CC_IF
Definition: apogee_0.99.h:253
#define PPM_IRQ
Definition: apogee_0.99.h:249