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
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 
48 #define ONE_MHZ_CLK 1000000
49 
54 
55 /*
56  * Timer clock frequency (before prescaling) is twice the frequency
57  * of the APB domain to which the timer is connected.
58  */
59 
60 #ifdef STM32F1
61 
66 #define PPM_TIMER_CLK AHB_CLK
67 #endif
68 
69 #if USE_PPM_TIM2
70 
71 PRINT_CONFIG_MSG("Using TIM2 for PPM input.")
72 
73 #define PPM_RCC &RCC_APB1ENR
74 #define PPM_PERIPHERAL RCC_APB1ENR_TIM2EN
75 #define PPM_TIMER TIM2
76 
77 #ifdef STM32F4
78 /* Since APB prescaler != 1 :
79  * Timer clock frequency (before prescaling) is twice the frequency
80  * of the APB domain to which the timer is connected.
81  */
82 #define PPM_TIMER_CLK (rcc_ppre1_frequency * 2)
83 #endif
84 
85 #elif USE_PPM_TIM1
86 
87 PRINT_CONFIG_MSG("Using TIM1 for PPM input.")
88 
89 #define PPM_RCC &RCC_APB2ENR
90 #define PPM_PERIPHERAL RCC_APB2ENR_TIM1EN
91 #define PPM_TIMER TIM1
92 
93 #ifdef STM32F4
94 #define PPM_TIMER_CLK (rcc_ppre2_frequency * 2)
95 #endif
96 
97 #else
98 #error Unknown PPM input timer configuration.
99 #endif
100 
101 void ppm_arch_init ( void ) {
102 
103  /* timer clock enable */
104  rcc_peripheral_enable_clock(PPM_RCC, PPM_PERIPHERAL);
105 
106  /* GPIO clock enable */
108 
109  /* timer gpio configuration */
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  timer_set_prescaler(PPM_TIMER, (PPM_TIMER_CLK / (RC_PPM_TICKS_PER_USEC*ONE_MHZ_CLK)) - 1);
118 
119  /* TIM configuration: Input Capture mode ---------------------
120  The Rising edge is used as active edge
121  ------------------------------------------------------------ */
122 #if defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_POSITIVE
123  timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_RISING);
124 #elif defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_NEGATIVE
125  timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_FALLING);
126 #else
127 #error "Unknown PPM_PULSE_TYPE"
128 #endif
129  timer_ic_set_input(PPM_TIMER, PPM_CHANNEL, PPM_TIMER_INPUT);
130  timer_ic_set_prescaler(PPM_TIMER, PPM_CHANNEL, TIM_IC_PSC_OFF);
131  timer_ic_set_filter(PPM_TIMER, PPM_CHANNEL, TIM_IC_OFF);
132 
133  /* Enable timer Interrupt(s). */
134  nvic_set_priority(PPM_IRQ, 2);
135  nvic_enable_irq(PPM_IRQ);
136 
137 #ifdef PPM_IRQ2
138  nvic_set_priority(PPM_IRQ2, 2);
139  nvic_enable_irq(PPM_IRQ2);
140 #endif
141 
142  /* Enable the Capture/Compare and Update interrupt requests. */
143  timer_enable_irq(PPM_TIMER, (PPM_CC_IE | TIM_DIER_UIE));
144 
145  /* Enable capture channel. */
146  timer_ic_enable(PPM_TIMER, PPM_CHANNEL);
147 
148  /* TIM enable counter */
149  timer_enable_counter(PPM_TIMER);
150 
153  timer_rollover_cnt = 0;
154 
155 }
156 
157 #if USE_PPM_TIM2
158 
159 void tim2_isr(void) {
160 
161  if((TIM2_SR & PPM_CC_IF) != 0) {
162  timer_clear_flag(TIM2, PPM_CC_IF);
163 
164  uint32_t now = timer_get_counter(TIM2) + timer_rollover_cnt;
165  DecodePpmFrame(now);
166  }
167  else if((TIM2_SR & TIM_SR_UIF) != 0) {
168  timer_rollover_cnt+=(1<<16);
169  timer_clear_flag(TIM2, TIM_SR_UIF);
170  }
171 
172 }
173 
174 #elif USE_PPM_TIM1
175 
176 #if defined(STM32F1)
177 void tim1_up_isr(void) {
178 #elif defined(STM32F4)
179 void tim1_up_tim10_isr(void) {
180 #endif
181  if((TIM1_SR & TIM_SR_UIF) != 0) {
182  timer_rollover_cnt+=(1<<16);
183  timer_clear_flag(TIM1, TIM_SR_UIF);
184  }
185 }
186 
187 void tim1_cc_isr(void) {
188  if((TIM1_SR & PPM_CC_IF) != 0) {
189  timer_clear_flag(TIM1, PPM_CC_IF);
190 
191  uint32_t now = timer_get_counter(TIM1) + timer_rollover_cnt;
192  DecodePpmFrame(now);
193  }
194 }
195 
196 #endif /* USE_PPM_TIM1 */
197 
timer_clear_flag(TIM6, TIM_SR_UIF)
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
#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.
#define ONE_MHZ_CLK
Definition: ppm_arch.c:48
#define PPM_TIMER_INPUT
Definition: apogee_0.99.h:278
#define PPM_GPIO_AF
Definition: apogee_0.99.h:286
#define PPM_CHANNEL
Definition: apogee_0.99.h:277
#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:280
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_enable_clock(uint32_t port)
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 RADIO_CONTROL_NB_CHANNEL
Definition: spektrum_arch.h:34
unsigned char uint8_t
Definition: types.h:14
#define PPM_GPIO_PIN
Definition: apogee_0.99.h:285
static uint32_t timer_rollover_cnt
Definition: ppm_arch.c:53
#define PPM_GPIO_PORT
Definition: apogee_0.99.h:284
#define PPM_CC_IE
Definition: apogee_0.99.h:282
#define PPM_CC_IF
Definition: apogee_0.99.h:283
#define PPM_IRQ
Definition: apogee_0.99.h:279