dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_exti.c
Go to the documentation of this file.
1 
18 /*
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27  * for more details.
28  *
29  * You should have received a copy of the GNU General Public License along
30  * with this program; if not, see <http://www.gnu.org/licenses/>
31  */
32 
33 /* Project Includes */
34 #include "pios.h"
35 
36 #if defined(PIOS_INCLUDE_EXTI)
37 
38 /* Map EXTI line to full config */
39 #define EXTI_MAX_LINES 16
40 
41 const struct pios_exti_cfg * pios_exti_line_to_cfg_map[EXTI_MAX_LINES];
42 
43 static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
44 {
45  switch (line) {
46  case EXTI_Line0: return 0;
47  case EXTI_Line1: return 1;
48  case EXTI_Line2: return 2;
49  case EXTI_Line3: return 3;
50  case EXTI_Line4: return 4;
51  case EXTI_Line5: return 5;
52  case EXTI_Line6: return 6;
53  case EXTI_Line7: return 7;
54  case EXTI_Line8: return 8;
55  case EXTI_Line9: return 9;
56  case EXTI_Line10: return 10;
57  case EXTI_Line11: return 11;
58  case EXTI_Line12: return 12;
59  case EXTI_Line13: return 13;
60  case EXTI_Line14: return 14;
61  case EXTI_Line15: return 15;
62  }
63 
64  PIOS_Assert(0);
65  return 0xFF;
66 }
67 
68 static uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef * gpio_port)
69 {
70  switch ((uint32_t)gpio_port) {
71 #ifdef STM32F10X_MD
72  case (uint32_t)GPIOA: return (GPIO_PortSourceGPIOA);
73  case (uint32_t)GPIOB: return (GPIO_PortSourceGPIOB);
74  case (uint32_t)GPIOC: return (GPIO_PortSourceGPIOC);
75  case (uint32_t)GPIOD: return (GPIO_PortSourceGPIOD);
76  case (uint32_t)GPIOE: return (GPIO_PortSourceGPIOE);
77  case (uint32_t)GPIOF: return (GPIO_PortSourceGPIOF);
78  case (uint32_t)GPIOG: return (GPIO_PortSourceGPIOG);
79 #else
80  case (uint32_t)GPIOA: return (EXTI_PortSourceGPIOA);
81  case (uint32_t)GPIOB: return (EXTI_PortSourceGPIOB);
82  case (uint32_t)GPIOC: return (EXTI_PortSourceGPIOC);
83  case (uint32_t)GPIOD: return (EXTI_PortSourceGPIOD);
84  case (uint32_t)GPIOE: return (EXTI_PortSourceGPIOE);
85  case (uint32_t)GPIOF: return (EXTI_PortSourceGPIOF);
86 
87 #ifdef GPIOG
88  case (uint32_t)GPIOG: return (EXTI_PortSourceGPIOG);
89 #endif
90 
91 #endif /* !STM32F10X_MD */
92  }
93 
94  PIOS_Assert(0);
95  return 0xFF;
96 }
97 
98 static uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
99 {
100  switch ((uint32_t)gpio_pin) {
101  case GPIO_Pin_0: return (GPIO_PinSource0);
102  case GPIO_Pin_1: return (GPIO_PinSource1);
103  case GPIO_Pin_2: return (GPIO_PinSource2);
104  case GPIO_Pin_3: return (GPIO_PinSource3);
105  case GPIO_Pin_4: return (GPIO_PinSource4);
106  case GPIO_Pin_5: return (GPIO_PinSource5);
107  case GPIO_Pin_6: return (GPIO_PinSource6);
108  case GPIO_Pin_7: return (GPIO_PinSource7);
109  case GPIO_Pin_8: return (GPIO_PinSource8);
110  case GPIO_Pin_9: return (GPIO_PinSource9);
111  case GPIO_Pin_10: return (GPIO_PinSource10);
112  case GPIO_Pin_11: return (GPIO_PinSource11);
113  case GPIO_Pin_12: return (GPIO_PinSource12);
114  case GPIO_Pin_13: return (GPIO_PinSource13);
115  case GPIO_Pin_14: return (GPIO_PinSource14);
116  case GPIO_Pin_15: return (GPIO_PinSource15);
117  }
118 
119  PIOS_Assert(0);
120  return 0xFF;
121 }
122 
123 int32_t PIOS_EXTI_Init(const struct pios_exti_cfg * cfg)
124 {
125  /* Connect this config to the requested vector */
126  uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
127 
128  if (pios_exti_line_to_cfg_map[line_index] != NULL) {
129  /* Someone else already has this mapped */
130  goto out_fail;
131  }
132 
133  /* Bind the config to the exti line */
134  pios_exti_line_to_cfg_map[line_index] = cfg;
135 
136  /* Initialize the GPIO pin */
137  GPIO_Init(cfg->pin.gpio, (GPIO_InitTypeDef*)&cfg->pin.init);
138 
139  /* Set up the EXTI interrupt source */
140  uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
141  uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
142 
143 #ifdef STM32F10X_MD
144  GPIO_EXTILineConfig(exti_source_port, exti_source_pin);
145 #else
146  SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
147 #endif
148 
149  EXTI_Init((EXTI_InitTypeDef*)&cfg->exti.init);
150 
151  /* Enable the interrupt channel */
152  NVIC_Init((NVIC_InitTypeDef*)&cfg->irq.init);
153 
154  return 0;
155 
156 out_fail:
157  return -1;
158 }
159 
160 void PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
161 {
162  PIOS_Assert(cfg);
163 
164  /* Disconnect this config from the requested vector */
165  /* XXX: would be nice to make sure it's the same as cfg... */
166  uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
167  pios_exti_line_to_cfg_map[line_index] = NULL;
168 
169  /* Disconnect EXTI */
170  uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
171  // sadly std-periph doesn't provide a way to disable the exti line
172  uint32_t tmp = ((uint32_t)0x0F) << (0x04 * (exti_source_pin & (uint8_t)0x03));
173 
174 #ifdef STM32F10X_MD
175  AFIO ->EXTICR[exti_source_pin >> 0x02] &= ~tmp;
176 #else
177  SYSCFG->EXTICR[exti_source_pin >> 0x02] &= ~tmp;
178 #endif
179 
180  /* Disable EXTI */
181  EXTI_InitTypeDef init = {
182  .EXTI_LineCmd = DISABLE,
183  .EXTI_Mode = cfg->exti.init.EXTI_Mode,
184  .EXTI_Line = cfg->exti.init.EXTI_Line,
185  };
186  EXTI_Init(&init);
187 }
188 
189 static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
190 {
191  const struct pios_exti_cfg * cfg = pios_exti_line_to_cfg_map[line_index];
192 
193  if (!cfg) {
194  /* Unconfigured interrupt just fired! */
195  return false;
196  }
197 
198  return cfg->vector();
199 }
200 
201 /* Bind Interrupt Handlers */
202 
203 #define PIOS_EXTI_HANDLE_LINE(line) \
204  if (EXTI_GetITStatus(EXTI_Line ## line) != RESET) { \
205  EXTI_ClearITPendingBit(EXTI_Line ## line); \
206  PIOS_EXTI_generic_irq_handler(line); \
207  }
208 
209 static void PIOS_EXTI_0_irq_handler(void)
210 {
212  PIOS_EXTI_HANDLE_LINE(0);
214 }
215 void EXTI0_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_0_irq_handler")));
216 
217 static void PIOS_EXTI_1_irq_handler(void)
218 {
220  PIOS_EXTI_HANDLE_LINE(1);
222 }
223 void EXTI1_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_1_irq_handler")));
224 
225 static void PIOS_EXTI_2_irq_handler(void)
226 {
228  PIOS_EXTI_HANDLE_LINE(2);
230 }
231 void EXTI2_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_2_irq_handler")));
232 
233 static void PIOS_EXTI_3_irq_handler(void)
234 {
236  PIOS_EXTI_HANDLE_LINE(3);
238 }
239 void EXTI3_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_3_irq_handler")));
240 
241 static void PIOS_EXTI_4_irq_handler(void)
242 {
244  PIOS_EXTI_HANDLE_LINE(4);
246 }
247 void EXTI4_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_4_irq_handler")));
248 
249 static void PIOS_EXTI_9_5_irq_handler(void)
250 {
252 
253  PIOS_EXTI_HANDLE_LINE(5);
254  PIOS_EXTI_HANDLE_LINE(6);
255  PIOS_EXTI_HANDLE_LINE(7);
256  PIOS_EXTI_HANDLE_LINE(8);
257  PIOS_EXTI_HANDLE_LINE(9);
258 
260 }
261 void EXTI9_5_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_9_5_irq_handler")));
262 
263 static void PIOS_EXTI_15_10_irq_handler(void)
264 {
266 
267  PIOS_EXTI_HANDLE_LINE(10);
268  PIOS_EXTI_HANDLE_LINE(11);
269  PIOS_EXTI_HANDLE_LINE(12);
270  PIOS_EXTI_HANDLE_LINE(13);
271  PIOS_EXTI_HANDLE_LINE(14);
272  PIOS_EXTI_HANDLE_LINE(15);
273 
275 }
276 void EXTI15_10_IRQHandler(void) __attribute__ ((alias("PIOS_EXTI_15_10_irq_handler")));
277 
278 #endif /* PIOS_INCLUDE_EXTI */
279 
Main PiOS header to include all the compiled in PiOS options.
GPIO_InitTypeDef init
Definition: pios_stm32.h:61
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
GPIO_TypeDef * gpio
Definition: pios_stm32.h:60
#define PIOS_IRQ_Epilogue()
Definition: pios_irq.h:46
#define EXTI15_10_IRQHandler
bool(* vector)(void)
Definition: pios_exti.h:38
void PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
struct stm32_exti exti
Definition: pios_exti.h:42
#define EXTI0_IRQHandler
EXTI_InitTypeDef init
Definition: pios_stm32.h:40
NVIC_InitTypeDef init
Definition: pios_stm32.h:36
struct stm32_irq irq
Definition: pios_exti.h:41
#define EXTI3_IRQHandler
#define EXTI9_5_IRQHandler
#define EXTI1_IRQHandler
#define PIOS_IRQ_Prologue()
Definition: pios_irq.h:45
struct stm32_gpio pin
Definition: pios_exti.h:40
#define EXTI4_IRQHandler
uint32_t line
Definition: pios_exti.h:39
#define PIOS_Assert(test)
Definition: pios_debug.h:52
#define EXTI2_IRQHandler