dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
board_hw_defs.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 #include <pios_config.h>
31 #include <pios_board_info.h>
32 
33 #if defined(PIOS_INCLUDE_ANNUNC)
34 
35 #include <pios_annunc_priv.h>
36 static const struct pios_annunc pios_annuncs[] = {
37  [PIOS_LED_HEARTBEAT] = {
38  .pin = {
39  .gpio = GPIOB,
40  .init = {
41  .GPIO_Pin = GPIO_Pin_9,
42  .GPIO_Speed = GPIO_Speed_2MHz,
43  .GPIO_Mode = GPIO_Mode_OUT,
44  .GPIO_OType = GPIO_OType_PP,
45  .GPIO_PuPd = GPIO_PuPd_NOPULL,
46  },
47  },
48  .active_high = false,
49  },
50  [PIOS_LED_ALARM] = {
51  .pin = {
52  .gpio = GPIOA,
53  .init = {
54  .GPIO_Pin = GPIO_Pin_14,
55  .GPIO_Speed = GPIO_Speed_2MHz,
56  .GPIO_Mode = GPIO_Mode_OUT,
57  .GPIO_OType = GPIO_OType_PP,
58  .GPIO_PuPd = GPIO_PuPd_NOPULL,
59  },
60  },
61  .active_high = false,
62  },
64  .pin = {
65  .gpio = GPIOC,
66  .init = {
67  .GPIO_Pin = GPIO_Pin_13,
68  .GPIO_Speed = GPIO_Speed_50MHz,
69  .GPIO_Mode = GPIO_Mode_OUT,
70  .GPIO_OType = GPIO_OType_PP,
71  .GPIO_PuPd = GPIO_PuPd_NOPULL
72  },
73  },
74  .active_high = true,
75  },
76 };
77 
78 static const struct pios_annunc_cfg pios_annunc_cfg = {
79  .annunciators = pios_annuncs,
80  .num_annunciators = NELEMENTS(pios_annuncs),
81 };
82 
83 const struct pios_annunc_cfg * PIOS_BOARD_HW_DEFS_GetLedCfg (uint32_t board_revision)
84 {
85  return &pios_annunc_cfg;
86 }
87 
88 #endif /* PIOS_INCLUDE_ANNUNC */
89 
90 #if defined(PIOS_INCLUDE_SPI)
91 #include <pios_spi_priv.h>
92 
93 /* SPI2 Interface
94  * - Used for OSD
95  */
96 
97 static const struct pios_spi_cfg pios_spi_osd_cfg = {
98  .regs = SPI2,
99  .remap = GPIO_AF_SPI2,
100  .init = {
101  .SPI_Mode = SPI_Mode_Master,
102  .SPI_Direction = SPI_Direction_2Lines_FullDuplex,
103  .SPI_DataSize = SPI_DataSize_8b,
104  .SPI_NSS = SPI_NSS_Soft,
105  .SPI_FirstBit = SPI_FirstBit_MSB,
106  .SPI_CRCPolynomial = 7,
107  .SPI_CPOL = SPI_CPOL_Low,
108  .SPI_CPHA = SPI_CPHA_1Edge,
109  .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8,
110  },
111  .sclk = {
112  .gpio = GPIOB,
113  .init = {
114  .GPIO_Pin = GPIO_Pin_13,
115  .GPIO_Speed = GPIO_Speed_100MHz,
116  .GPIO_Mode = GPIO_Mode_AF,
117  .GPIO_OType = GPIO_OType_PP,
118  .GPIO_PuPd = GPIO_PuPd_NOPULL
119  },
120  .pin_source = GPIO_PinSource13,
121  },
122  .miso = {
123  .gpio = GPIOB,
124  .init = {
125  .GPIO_Pin = GPIO_Pin_14,
126  .GPIO_Speed = GPIO_Speed_100MHz,
127  .GPIO_Mode = GPIO_Mode_AF,
128  .GPIO_OType = GPIO_OType_PP,
129  .GPIO_PuPd = GPIO_PuPd_NOPULL
130  },
131  .pin_source = GPIO_PinSource14,
132  },
133  .mosi = {
134  .gpio = GPIOB,
135  .init = {
136  .GPIO_Pin = GPIO_Pin_15,
137  .GPIO_Speed = GPIO_Speed_100MHz,
138  .GPIO_Mode = GPIO_Mode_AF,
139  .GPIO_OType = GPIO_OType_PP,
140  .GPIO_PuPd = GPIO_PuPd_NOPULL
141  },
142  .pin_source = GPIO_PinSource15,
143  },
144  .slave_count = 1,
145  .ssel = { {
146  .gpio = GPIOB,
147  .init = {
148  .GPIO_Pin = GPIO_Pin_10,
149  .GPIO_Speed = GPIO_Speed_100MHz,
150  .GPIO_Mode = GPIO_Mode_OUT,
151  .GPIO_OType = GPIO_OType_PP,
152  .GPIO_PuPd = GPIO_PuPd_NOPULL
153  },
154  } },
155 };
156 
157 pios_spi_t pios_spi_osd_id;
158 
159 /* SPI3 Interface
160  * - Used for gyro communications
161  */
162 
163 static const struct pios_spi_cfg pios_spi_gyro_cfg = {
164  .regs = SPI1,
165  .remap = GPIO_AF_SPI1,
166  .init = {
167  .SPI_Mode = SPI_Mode_Master,
168  .SPI_Direction = SPI_Direction_2Lines_FullDuplex,
169  .SPI_DataSize = SPI_DataSize_8b,
170  .SPI_NSS = SPI_NSS_Soft,
171  .SPI_FirstBit = SPI_FirstBit_MSB,
172  .SPI_CRCPolynomial = 7,
173  .SPI_CPOL = SPI_CPOL_High,
174  .SPI_CPHA = SPI_CPHA_2Edge,
175  .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32, //@ APB2 PCLK1 82MHz / 32 == 2.6MHz
176  },
177  .sclk = {
178  .gpio = GPIOA,
179  .init = {
180  .GPIO_Pin = GPIO_Pin_5,
181  .GPIO_Speed = GPIO_Speed_100MHz,
182  .GPIO_Mode = GPIO_Mode_AF,
183  .GPIO_OType = GPIO_OType_PP,
184  .GPIO_PuPd = GPIO_PuPd_NOPULL
185  },
186  .pin_source = GPIO_PinSource5,
187  },
188  .miso = {
189  .gpio = GPIOA,
190  .init = {
191  .GPIO_Pin = GPIO_Pin_6,
192  .GPIO_Speed = GPIO_Speed_100MHz,
193  .GPIO_Mode = GPIO_Mode_AF,
194  .GPIO_OType = GPIO_OType_PP,
195  .GPIO_PuPd = GPIO_PuPd_NOPULL
196  },
197  .pin_source = GPIO_PinSource6,
198  },
199  .mosi = {
200  .gpio = GPIOA,
201  .init = {
202  .GPIO_Pin = GPIO_Pin_7,
203  .GPIO_Speed = GPIO_Speed_100MHz,
204  .GPIO_Mode = GPIO_Mode_AF,
205  .GPIO_OType = GPIO_OType_PP,
206  .GPIO_PuPd = GPIO_PuPd_NOPULL
207  },
208  .pin_source = GPIO_PinSource7,
209  },
210  .slave_count = 1,
211  .ssel = { {
212  .gpio = GPIOC,
213  .init = {
214  .GPIO_Pin = GPIO_Pin_2,
215  .GPIO_Speed = GPIO_Speed_100MHz,
216  .GPIO_Mode = GPIO_Mode_OUT,
217  .GPIO_OType = GPIO_OType_PP,
218  .GPIO_PuPd = GPIO_PuPd_NOPULL
219  },
220  } },
221 };
222 
223 pios_spi_t pios_spi_gyro_id;
224 
225 #endif /* PIOS_INCLUDE_SPI */
226 
227 #if defined(PIOS_INCLUDE_I2C)
228 
229 #include <pios_i2c_priv.h>
230 
231 void PIOS_I2C_internal_ev_irq_handler(void);
232 void PIOS_I2C_internal_er_irq_handler(void);
233 
234 void I2C1_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_internal_ev_irq_handler")));
235 void I2C1_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_internal_er_irq_handler")));
236 
237 static const struct pios_i2c_adapter_cfg pios_i2c_internal_cfg = {
238  .regs = I2C1,
239  .remap = GPIO_AF_I2C1,
240  .init = {
241  .I2C_Mode = I2C_Mode_I2C,
242  .I2C_OwnAddress1 = 0,
243  .I2C_Ack = I2C_Ack_Enable,
244  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
245  .I2C_DutyCycle = I2C_DutyCycle_2,
246  .I2C_ClockSpeed = 400000, /* bits/s */
247  },
248  .transfer_timeout_ms = 50,
249  .scl = {
250  .gpio = GPIOB,
251  .init = {
252  .GPIO_Pin = GPIO_Pin_6,
253  .GPIO_Mode = GPIO_Mode_AF,
254  .GPIO_Speed = GPIO_Speed_50MHz,
255  .GPIO_OType = GPIO_OType_OD,
256  .GPIO_PuPd = GPIO_PuPd_UP,
257  },
258  .pin_source = GPIO_PinSource6,
259  },
260  .sda = {
261  .gpio = GPIOB,
262  .init = {
263  .GPIO_Pin = GPIO_Pin_7,
264  .GPIO_Mode = GPIO_Mode_AF,
265  .GPIO_Speed = GPIO_Speed_50MHz,
266  .GPIO_OType = GPIO_OType_OD,
267  .GPIO_PuPd = GPIO_PuPd_UP,
268  },
269  .pin_source = GPIO_PinSource7,
270  },
271  .event = {
272  .flags = 0, /* FIXME: check this */
273  .init = {
274  .NVIC_IRQChannel = I2C1_EV_IRQn,
275  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
276  .NVIC_IRQChannelSubPriority = 0,
277  .NVIC_IRQChannelCmd = ENABLE,
278  },
279  },
280  .error = {
281  .flags = 0, /* FIXME: check this */
282  .init = {
283  .NVIC_IRQChannel = I2C1_ER_IRQn,
284  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
285  .NVIC_IRQChannelSubPriority = 0,
286  .NVIC_IRQChannelCmd = ENABLE,
287  },
288  },
289 };
290 
291 pios_i2c_t pios_i2c_internal_id;
292 void PIOS_I2C_internal_ev_irq_handler(void)
293 {
294  /* Call into the generic code to handle the IRQ for this specific device */
295  PIOS_I2C_EV_IRQ_Handler(pios_i2c_internal_id);
296 }
297 
298 void PIOS_I2C_internal_er_irq_handler(void)
299 {
300  /* Call into the generic code to handle the IRQ for this specific device */
301  PIOS_I2C_ER_IRQ_Handler(pios_i2c_internal_id);
302 }
303 
304 void PIOS_I2C_external_ev_irq_handler(void);
305 void PIOS_I2C_external_er_irq_handler(void);
306 
307 void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_external_ev_irq_handler")));
308 void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_external_er_irq_handler")));
309 
310 static const struct pios_i2c_adapter_cfg pios_i2c_external_cfg = {
311  .regs = I2C2,
312  .remap = GPIO_AF_I2C2,
313  .init = {
314  .I2C_Mode = I2C_Mode_I2C,
315  .I2C_OwnAddress1 = 0,
316  .I2C_Ack = I2C_Ack_Enable,
317  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
318  .I2C_DutyCycle = I2C_DutyCycle_2,
319  .I2C_ClockSpeed = 400000, /* bits/s */
320  },
321  .transfer_timeout_ms = 50,
322  .scl = {
323  .gpio = GPIOB,
324  .init = {
325  .GPIO_Pin = GPIO_Pin_10,
326  .GPIO_Mode = GPIO_Mode_AF,
327  .GPIO_Speed = GPIO_Speed_50MHz,
328  .GPIO_OType = GPIO_OType_OD,
329  .GPIO_PuPd = GPIO_PuPd_UP,
330  },
331  .pin_source = GPIO_PinSource10,
332  },
333  .sda = {
334  .gpio = GPIOB,
335  .init = {
336  .GPIO_Pin = GPIO_Pin_11,
337  .GPIO_Mode = GPIO_Mode_AF,
338  .GPIO_Speed = GPIO_Speed_50MHz,
339  .GPIO_OType = GPIO_OType_OD,
340  .GPIO_PuPd = GPIO_PuPd_UP,
341  },
342  .pin_source = GPIO_PinSource11,
343  },
344  .event = {
345  .flags = 0, /* FIXME: check this */
346  . init = {
347  .NVIC_IRQChannel = I2C2_EV_IRQn,
348  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
349  .NVIC_IRQChannelSubPriority = 0,
350  .NVIC_IRQChannelCmd = ENABLE,
351  },
352  },
353  .error = {
354  .flags = 0, /* FIXME: check this */
355  .init = {
356  .NVIC_IRQChannel = I2C2_ER_IRQn,
357  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
358  .NVIC_IRQChannelSubPriority = 0,
359  .NVIC_IRQChannelCmd = ENABLE,
360  },
361  },
362 };
363 
364 pios_i2c_t pios_i2c_external_id;
365 void PIOS_I2C_external_ev_irq_handler(void)
366 {
367 /* Call into the generic code to handle the IRQ for this specific device */
368 PIOS_I2C_EV_IRQ_Handler(pios_i2c_external_id);
369 }
370 
371 void PIOS_I2C_external_er_irq_handler(void)
372 {
373  /* Call into the generic code to handle the IRQ for this specific device */
374  PIOS_I2C_ER_IRQ_Handler(pios_i2c_external_id);
375 }
376 
377 #endif /* PIOS_INCLUDE_I2C */
378 
379 #if defined(PIOS_INCLUDE_FLASH)
380 #include "pios_flashfs_logfs_priv.h"
381 
382 static const struct flashfs_logfs_cfg flashfs_settings_cfg = {
383  .fs_magic = 0x3b1b14cf,
384  .arena_size = 0x00004000, /* 64 * slot size = 16K bytes = 1 sector */
385  .slot_size = 0x00000100, /* 256 bytes */
386 };
387 
389 
390 static const struct pios_flash_internal_cfg flash_internal_cfg = {
391 };
392 
393 #include "pios_flash_priv.h"
394 
395 static const struct pios_flash_sector_range stm32f4_sectors[] = {
396  {
397  .base_sector = 0,
398  .last_sector = 3,
399  .sector_size = FLASH_SECTOR_16KB,
400  },
401  {
402  .base_sector = 4,
403  .last_sector = 4,
404  .sector_size = FLASH_SECTOR_64KB,
405  },
406  {
407  .base_sector = 5,
408  .last_sector = 11,
409  .sector_size = FLASH_SECTOR_128KB,
410  },
411 
412 };
413 
414 uintptr_t pios_internal_flash_id;
415 static const struct pios_flash_chip pios_flash_chip_internal = {
417  .chip_id = &pios_internal_flash_id,
418  .page_size = 16, /* 128-bit rows */
419  .sector_blocks = stm32f4_sectors,
420  .num_blocks = NELEMENTS(stm32f4_sectors),
421 };
422 
423 static const struct pios_flash_partition pios_flash_partition_table[] = {
424  {
426  .chip_desc = &pios_flash_chip_internal,
427  .first_sector = 0,
428  .last_sector = 1,
429  .chip_offset = 0, // 0x0800 0000
430  .size = (1 - 0 + 1) * FLASH_SECTOR_16KB, // 32KB
431  },
432 
433  {
435  .chip_desc = &pios_flash_chip_internal,
436  .first_sector = 2,
437  .last_sector = 3,
438  .chip_offset = (2 * FLASH_SECTOR_16KB), // 0x0800 8000
439  .size = (3 - 2 + 1) * FLASH_SECTOR_16KB, // 32KB
440  },
441 
442  /* NOTE: sector 4 of internal flash is currently unallocated */
443 
444  {
445  .label = FLASH_PARTITION_LABEL_FW,
446  .chip_desc = &pios_flash_chip_internal,
447  .first_sector = 5,
448  .last_sector = 7,
449  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB), // 0x0802 0000
450  .size = (7 - 5 + 1) * FLASH_SECTOR_128KB, // 384KB
451  },
452 
453  /* NOTE: sectors 8-9 of the internal flash are currently unallocated */
454 
455  {
457  .chip_desc = &pios_flash_chip_internal,
458  .first_sector = 10,
459  .last_sector = 10,
460  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB) + (5 * FLASH_SECTOR_128KB), // 0x080C 0000
461  .size = (10 - 10 + 1) * FLASH_SECTOR_128KB, // 128KB
462  },
463 
464  /* Sector 11 is unallocated, but in old bootloaders was allocated to
465  * waypoints/autotune.
466  */
467 };
468 
469 const struct pios_flash_partition * PIOS_BOARD_HW_DEFS_GetPartitionTable (uint32_t board_revision, uint32_t * num_partitions)
470 {
471  PIOS_Assert(num_partitions);
472 
473  *num_partitions = NELEMENTS(pios_flash_partition_table);
475 }
476 
477 #endif /* PIOS_INCLUDE_FLASH */
478 
479 #if defined(PIOS_INCLUDE_USART)
480 
481 #include "pios_usart_priv.h"
482 
483 #if defined(PIOS_INCLUDE_DSM)
484 /*
485  * Spektrum/JR DSM USART
486  */
487 #include <pios_dsm_priv.h>
488 
489 static const struct pios_dsm_cfg pios_usart1_dsm_aux_cfg = {
490  .bind = {
491  .gpio = GPIOA,
492  .init = {
493  .GPIO_Pin = GPIO_Pin_10,
494  .GPIO_Speed = GPIO_Speed_2MHz,
495  .GPIO_Mode = GPIO_Mode_OUT,
496  .GPIO_OType = GPIO_OType_PP,
497  .GPIO_PuPd = GPIO_PuPd_NOPULL
498  },
499  },
500 };
501 
502 static const struct pios_dsm_cfg pios_usart2_dsm_aux_cfg = {
503  .bind = {
504  .gpio = GPIOA,
505  .init = {
506  .GPIO_Pin = GPIO_Pin_3,
507  .GPIO_Speed = GPIO_Speed_2MHz,
508  .GPIO_Mode = GPIO_Mode_OUT,
509  .GPIO_OType = GPIO_OType_PP,
510  .GPIO_PuPd = GPIO_PuPd_NOPULL
511  },
512  },
513 };
514 
515 static const struct pios_dsm_cfg pios_usart3_dsm_aux_cfg = {
516  .bind = {
517  .gpio = GPIOC,
518  .init = {
519  .GPIO_Pin = GPIO_Pin_11,
520  .GPIO_Speed = GPIO_Speed_2MHz,
521  .GPIO_Mode = GPIO_Mode_OUT,
522  .GPIO_OType = GPIO_OType_PP,
523  .GPIO_PuPd = GPIO_PuPd_NOPULL
524  },
525  },
526 };
527 
528 static const struct pios_dsm_cfg pios_usart4_dsm_aux_cfg = {
529  .bind = {
530  .gpio = GPIOA,
531  .init = {
532  .GPIO_Pin = GPIO_Pin_1,
533  .GPIO_Speed = GPIO_Speed_2MHz,
534  .GPIO_Mode = GPIO_Mode_OUT,
535  .GPIO_OType = GPIO_OType_PP,
536  .GPIO_PuPd = GPIO_PuPd_NOPULL
537  },
538  },
539 };
540 
541 static const struct pios_dsm_cfg pios_usart5_dsm_aux_cfg = {
542  .bind = {
543  .gpio = GPIOD,
544  .init = {
545  .GPIO_Pin = GPIO_Pin_2,
546  .GPIO_Speed = GPIO_Speed_2MHz,
547  .GPIO_Mode = GPIO_Mode_OUT,
548  .GPIO_OType = GPIO_OType_PP,
549  .GPIO_PuPd = GPIO_PuPd_NOPULL
550  },
551  },
552 };
553 
554 #endif /* PIOS_INCLUDE_DSM */
555 
556 static const struct pios_usart_cfg pios_usart1_cfg = {
557  .regs = USART1,
558  .remap = GPIO_AF_USART1,
559  .irq = {
560  .init = {
561  .NVIC_IRQChannel = USART1_IRQn,
562  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
563  .NVIC_IRQChannelSubPriority = 0,
564  .NVIC_IRQChannelCmd = ENABLE,
565  },
566  },
567  .rx = {
568  .gpio = GPIOA,
569  .init = {
570  .GPIO_Pin = GPIO_Pin_10,
571  .GPIO_Speed = GPIO_Speed_2MHz,
572  .GPIO_Mode = GPIO_Mode_AF,
573  .GPIO_OType = GPIO_OType_PP,
574  .GPIO_PuPd = GPIO_PuPd_UP
575  },
576  .pin_source = GPIO_PinSource10,
577  },
578  .tx = {
579  .gpio = GPIOA,
580  .init = {
581  .GPIO_Pin = GPIO_Pin_9,
582  .GPIO_Speed = GPIO_Speed_2MHz,
583  .GPIO_Mode = GPIO_Mode_AF,
584  .GPIO_OType = GPIO_OType_PP,
585  .GPIO_PuPd = GPIO_PuPd_UP
586  },
587  .pin_source = GPIO_PinSource9,
588  },
589 };
590 
591 static const struct pios_usart_cfg pios_usart2_cfg = {
592  .regs = USART2,
593  .remap = GPIO_AF_USART2,
594  .irq = {
595  .init = {
596  .NVIC_IRQChannel = USART2_IRQn,
597  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
598  .NVIC_IRQChannelSubPriority = 0,
599  .NVIC_IRQChannelCmd = ENABLE,
600  },
601  },
602  .rx = {
603  .gpio = GPIOA,
604  .init = {
605  .GPIO_Pin = GPIO_Pin_3,
606  .GPIO_Speed = GPIO_Speed_2MHz,
607  .GPIO_Mode = GPIO_Mode_AF,
608  .GPIO_OType = GPIO_OType_PP,
609  .GPIO_PuPd = GPIO_PuPd_UP
610  },
611  .pin_source = GPIO_PinSource3,
612  },
613  .tx = {
614  .gpio = GPIOA,
615  .init = {
616  .GPIO_Pin = GPIO_Pin_2,
617  .GPIO_Speed = GPIO_Speed_2MHz,
618  .GPIO_Mode = GPIO_Mode_AF,
619  .GPIO_OType = GPIO_OType_PP,
620  .GPIO_PuPd = GPIO_PuPd_UP
621  },
622  .pin_source = GPIO_PinSource2,
623  },
624 };
625 
626 static const struct pios_usart_cfg pios_usart3_cfg = {
627  .regs = USART3,
628  .remap = GPIO_AF_USART3,
629  .irq = {
630  .init = {
631  .NVIC_IRQChannel = USART3_IRQn,
632  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
633  .NVIC_IRQChannelSubPriority = 0,
634  .NVIC_IRQChannelCmd = ENABLE,
635  },
636  },
637  .rx = {
638  .gpio = GPIOC,
639  .init = {
640  .GPIO_Pin = GPIO_Pin_11,
641  .GPIO_Speed = GPIO_Speed_2MHz,
642  .GPIO_Mode = GPIO_Mode_AF,
643  .GPIO_OType = GPIO_OType_PP,
644  .GPIO_PuPd = GPIO_PuPd_UP
645  },
646  .pin_source = GPIO_PinSource11,
647  },
648  .tx = {
649  .gpio = GPIOC,
650  .init = {
651  .GPIO_Pin = GPIO_Pin_10,
652  .GPIO_Speed = GPIO_Speed_2MHz,
653  .GPIO_Mode = GPIO_Mode_AF,
654  .GPIO_OType = GPIO_OType_PP,
655  .GPIO_PuPd = GPIO_PuPd_UP
656  },
657  .pin_source = GPIO_PinSource10,
658  },
659 };
660 
661 static const struct pios_usart_cfg pios_usart4_cfg = {
662  .regs = UART4,
663  .remap = GPIO_AF_UART4,
664  .irq = {
665  .init = {
666  .NVIC_IRQChannel = UART4_IRQn,
667  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
668  .NVIC_IRQChannelSubPriority = 0,
669  .NVIC_IRQChannelCmd = ENABLE,
670  },
671  },
672  .rx = {
673  .gpio = GPIOA,
674  .init = {
675  .GPIO_Pin = GPIO_Pin_1,
676  .GPIO_Speed = GPIO_Speed_2MHz,
677  .GPIO_Mode = GPIO_Mode_AF,
678  .GPIO_OType = GPIO_OType_PP,
679  .GPIO_PuPd = GPIO_PuPd_UP
680  },
681  .pin_source = GPIO_PinSource1,
682  },
683  .tx = {
684  .gpio = GPIOA,
685  .init = {
686  .GPIO_Pin = GPIO_Pin_0,
687  .GPIO_Speed = GPIO_Speed_2MHz,
688  .GPIO_Mode = GPIO_Mode_AF,
689  .GPIO_OType = GPIO_OType_PP,
690  .GPIO_PuPd = GPIO_PuPd_UP
691  },
692  .pin_source = GPIO_PinSource0,
693  },
694 };
695 
696 static const struct pios_usart_cfg pios_usart5_cfg = {
697  .regs = UART5,
698  .remap = GPIO_AF_UART5,
699  .irq = {
700  .init = {
701  .NVIC_IRQChannel = UART5_IRQn,
702  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
703  .NVIC_IRQChannelSubPriority = 0,
704  .NVIC_IRQChannelCmd = ENABLE,
705  },
706  },
707  .rx = {
708  .gpio = GPIOD,
709  .init = {
710  .GPIO_Pin = GPIO_Pin_2,
711  .GPIO_Speed = GPIO_Speed_2MHz,
712  .GPIO_Mode = GPIO_Mode_AF,
713  .GPIO_OType = GPIO_OType_PP,
714  .GPIO_PuPd = GPIO_PuPd_UP
715  },
716  .pin_source = GPIO_PinSource2,
717  },
718  .tx = {
719  .gpio = GPIOC,
720  .init = {
721  .GPIO_Pin = GPIO_Pin_12,
722  .GPIO_Speed = GPIO_Speed_2MHz,
723  .GPIO_Mode = GPIO_Mode_AF,
724  .GPIO_OType = GPIO_OType_PP,
725  .GPIO_PuPd = GPIO_PuPd_UP
726  },
727  .pin_source = GPIO_PinSource12,
728  },
729 };
730 
731 #endif /* PIOS_INCLUDE_USART */
732 
733 #if defined(PIOS_INCLUDE_COM)
734 
735 #include "pios_com_priv.h"
736 
737 #endif /* PIOS_INCLUDE_COM */
738 
739 #if defined(PIOS_INCLUDE_RTC)
740 /*
741  * Realtime Clock (RTC)
742  */
743 #include <pios_rtc_priv.h>
744 
745 void PIOS_RTC_IRQ_Handler (void);
746 void RTC_WKUP_IRQHandler() __attribute__ ((alias ("PIOS_RTC_IRQ_Handler")));
747 static const struct pios_rtc_cfg pios_rtc_main_cfg = {
748  .clksrc = RCC_RTCCLKSource_HSE_Div8, // Divide 8 MHz HSE by 8 = 1 MHz
749  // 1 MHz resulting clock is then divided
750  // by another 16 to give a nominal 62.5 kHz clock
751  .prescaler = 100, // Every 100 cycles gives 625 Hz
752  .irq = {
753  .init = {
754  .NVIC_IRQChannel = RTC_WKUP_IRQn,
755  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
756  .NVIC_IRQChannelSubPriority = 0,
757  .NVIC_IRQChannelCmd = ENABLE,
758  },
759  },
760 };
761 
762 void PIOS_RTC_IRQ_Handler (void)
763 {
765 }
766 
767 #endif
768 
769 #include "pios_tim_priv.h"
770 
771 //Timers used for inputs (5)
772 
773 // Set up timers that only have outputs on APB1
774 static const TIM_TimeBaseInitTypeDef tim_5_time_base = {
775  .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_COUNTER_CLOCK / 1000000) - 1,
776  .TIM_ClockDivision = TIM_CKD_DIV1,
777  .TIM_CounterMode = TIM_CounterMode_Up,
778  .TIM_Period = 0xFFFF,
779  .TIM_RepetitionCounter = 0x0000,
780 };
781 
782 static const struct pios_tim_clock_cfg tim_5_cfg = {
783  .timer = TIM5,
784  .time_base_init = &tim_5_time_base,
785  .irq = {
786  .init = {
787  .NVIC_IRQChannel = TIM5_IRQn,
788  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
789  .NVIC_IRQChannelSubPriority = 0,
790  .NVIC_IRQChannelCmd = ENABLE,
791  },
792  },
793 };
794 
795 // Timers used for outputs (3,8)
796 
797 // Set up timers that only have outputs on APB1
798 static const TIM_TimeBaseInitTypeDef tim_2_3_4_time_base = {
799  .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_COUNTER_CLOCK / 1000000) - 1,
800  .TIM_ClockDivision = TIM_CKD_DIV1,
801  .TIM_CounterMode = TIM_CounterMode_Up,
802  .TIM_Period = ((1000000 / PIOS_SERVO_UPDATE_HZ) - 1),
803  .TIM_RepetitionCounter = 0x0000,
804 };
805 
806 // Set up timers that only have outputs on APB2
807 static const TIM_TimeBaseInitTypeDef tim_1_8_time_base = {
808  .TIM_Prescaler = (PIOS_PERIPHERAL_APB2_COUNTER_CLOCK / 1000000) - 1,
809  .TIM_ClockDivision = TIM_CKD_DIV1,
810  .TIM_CounterMode = TIM_CounterMode_Up,
811  .TIM_Period = ((1000000 / PIOS_SERVO_UPDATE_HZ) - 1),
812  .TIM_RepetitionCounter = 0x0000,
813 };
814 
815 static const struct pios_tim_clock_cfg tim_3_cfg = {
816  .timer = TIM3,
817  .time_base_init = &tim_2_3_4_time_base,
818  .irq = {
819  .init = {
820  .NVIC_IRQChannel = TIM3_IRQn,
821  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
822  .NVIC_IRQChannelSubPriority = 0,
823  .NVIC_IRQChannelCmd = ENABLE,
824  },
825  },
826 };
827 
828 static const struct pios_tim_clock_cfg tim_8_cfg = {
829  .timer = TIM8,
830  .time_base_init = &tim_1_8_time_base,
831  .irq = {
832  .init = {
833  .NVIC_IRQChannel = TIM8_CC_IRQn,
834  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
835  .NVIC_IRQChannelSubPriority = 0,
836  .NVIC_IRQChannelCmd = ENABLE,
837  },
838  },
839 };
840 
841 static const struct pios_tim_clock_cfg tim_2_cfg = {
842  .timer = TIM2,
843  .time_base_init = &tim_2_3_4_time_base,
844  .irq = {
845  .init = {
846  .NVIC_IRQChannel = TIM2_IRQn,
847  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
848  .NVIC_IRQChannelSubPriority = 0,
849  .NVIC_IRQChannelCmd = ENABLE,
850  },
851  },
852 };
853 
854 static const struct pios_tim_clock_cfg tim_1_cfg = {
855  .timer = TIM1,
856  .time_base_init = &tim_1_8_time_base,
857  .irq = {
858  .init = {
859  .NVIC_IRQChannel = TIM1_CC_IRQn,
860  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
861  .NVIC_IRQChannelSubPriority = 0,
862  .NVIC_IRQChannelCmd = ENABLE,
863  },
864  },
865 };
866 
867 static const struct pios_tim_clock_cfg tim_4_cfg = {
868  .timer = TIM4,
869  .time_base_init = &tim_2_3_4_time_base,
870  .irq = {
871  .init = {
872  .NVIC_IRQChannel = TIM4_IRQn,
873  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
874  .NVIC_IRQChannelSubPriority = 0,
875  .NVIC_IRQChannelCmd = ENABLE,
876  },
877  },
878 };
879 
884 /*
885  * Outputs
886  1: TIM3_CH1 (PC6) DMA1 Stream 2 Channel 5
887  2: TIM8_CH2 (PC7) DMA2 Stream 1 Channel 7
888  3: TIM8_CH3 (PC8)
889  4: TIM8_CH4 (PC9)
890  5: TIM2_CH1 (PA15) DMA1 Stream 1 Channel 3
891  6: TIM1_CH1 (PA8) DMA2 Stream 5 Channel 6
892  7: TIM4_CH3 (PB8) DMA1 Stream 6 Channel 2
893  */
894 
896  {
897  .timer = TIM3,
898  .timer_chan = TIM_Channel_1,
899  .remap = GPIO_AF_TIM3,
900  .pin = {
901  .gpio = GPIOC,
902  .init = {
903  .GPIO_Pin = GPIO_Pin_6,
904  .GPIO_Speed = GPIO_Speed_2MHz,
905  .GPIO_Mode = GPIO_Mode_AF,
906  .GPIO_OType = GPIO_OType_PP,
907  .GPIO_PuPd = GPIO_PuPd_NOPULL
908  },
909  .pin_source = GPIO_PinSource6,
910  },
911  },
912  {
913  .timer = TIM8,
914  .timer_chan = TIM_Channel_2,
915  .remap = GPIO_AF_TIM8,
916  .pin = {
917  .gpio = GPIOC,
918  .init = {
919  .GPIO_Pin = GPIO_Pin_7,
920  .GPIO_Speed = GPIO_Speed_2MHz,
921  .GPIO_Mode = GPIO_Mode_AF,
922  .GPIO_OType = GPIO_OType_PP,
923  .GPIO_PuPd = GPIO_PuPd_NOPULL
924  },
925  .pin_source = GPIO_PinSource7,
926  },
927  },
928  {
929  .timer = TIM8,
930  .timer_chan = TIM_Channel_3,
931  .remap = GPIO_AF_TIM8,
932  .pin = {
933  .gpio = GPIOC,
934  .init = {
935  .GPIO_Pin = GPIO_Pin_8,
936  .GPIO_Speed = GPIO_Speed_2MHz,
937  .GPIO_Mode = GPIO_Mode_AF,
938  .GPIO_OType = GPIO_OType_PP,
939  .GPIO_PuPd = GPIO_PuPd_NOPULL
940  },
941  .pin_source = GPIO_PinSource8,
942  },
943  },
944  {
945  .timer = TIM8,
946  .timer_chan = TIM_Channel_4,
947  .remap = GPIO_AF_TIM8,
948  .pin = {
949  .gpio = GPIOC,
950  .init = {
951  .GPIO_Pin = GPIO_Pin_9,
952  .GPIO_Speed = GPIO_Speed_2MHz,
953  .GPIO_Mode = GPIO_Mode_AF,
954  .GPIO_OType = GPIO_OType_PP,
955  .GPIO_PuPd = GPIO_PuPd_NOPULL
956  },
957  .pin_source = GPIO_PinSource9,
958  },
959  },
960  {
961  .timer = TIM2,
962  .timer_chan = TIM_Channel_1,
963  .remap = GPIO_AF_TIM2,
964  .pin = {
965  .gpio = GPIOA,
966  .init = {
967  .GPIO_Pin = GPIO_Pin_15,
968  .GPIO_Speed = GPIO_Speed_2MHz,
969  .GPIO_Mode = GPIO_Mode_AF,
970  .GPIO_OType = GPIO_OType_PP,
971  .GPIO_PuPd = GPIO_PuPd_NOPULL
972  },
973  .pin_source = GPIO_PinSource15,
974  },
975  },
976  {
977  .timer = TIM1,
978  .timer_chan = TIM_Channel_1,
979  .remap = GPIO_AF_TIM1,
980  .pin = {
981  .gpio = GPIOA,
982  .init = {
983  .GPIO_Pin = GPIO_Pin_8,
984  .GPIO_Speed = GPIO_Speed_2MHz,
985  .GPIO_Mode = GPIO_Mode_AF,
986  .GPIO_OType = GPIO_OType_PP,
987  .GPIO_PuPd = GPIO_PuPd_NOPULL
988  },
989  .pin_source = GPIO_PinSource8,
990  },
991  },
992  {
993  .timer = TIM4,
994  .timer_chan = TIM_Channel_3,
995  .remap = GPIO_AF_TIM4,
996  .pin = {
997  .gpio = GPIOB,
998  .init = {
999  .GPIO_Pin = GPIO_Pin_8,
1000  .GPIO_Speed = GPIO_Speed_2MHz,
1001  .GPIO_Mode = GPIO_Mode_AF,
1002  .GPIO_OType = GPIO_OType_PP,
1003  .GPIO_PuPd = GPIO_PuPd_NOPULL
1004  },
1005  .pin_source = GPIO_PinSource8,
1006  },
1007  },
1008 };
1009 
1011  {
1012  .timer = TIM3,
1013  .timer_chan = TIM_Channel_1,
1014  .remap = GPIO_AF_TIM3,
1015  .pin = {
1016  .gpio = GPIOC,
1017  .init = {
1018  .GPIO_Pin = GPIO_Pin_6,
1019  .GPIO_Speed = GPIO_Speed_2MHz,
1020  .GPIO_Mode = GPIO_Mode_AF,
1021  .GPIO_OType = GPIO_OType_PP,
1022  .GPIO_PuPd = GPIO_PuPd_NOPULL
1023  },
1024  .pin_source = GPIO_PinSource6,
1025  },
1026  },
1027  {
1028  .timer = TIM8,
1029  .timer_chan = TIM_Channel_2,
1030  .remap = GPIO_AF_TIM8,
1031  .pin = {
1032  .gpio = GPIOC,
1033  .init = {
1034  .GPIO_Pin = GPIO_Pin_7,
1035  .GPIO_Speed = GPIO_Speed_2MHz,
1036  .GPIO_Mode = GPIO_Mode_AF,
1037  .GPIO_OType = GPIO_OType_PP,
1038  .GPIO_PuPd = GPIO_PuPd_NOPULL
1039  },
1040  .pin_source = GPIO_PinSource7,
1041  },
1042  },
1043  {
1044  .timer = TIM8,
1045  .timer_chan = TIM_Channel_3,
1046  .remap = GPIO_AF_TIM8,
1047  .pin = {
1048  .gpio = GPIOC,
1049  .init = {
1050  .GPIO_Pin = GPIO_Pin_8,
1051  .GPIO_Speed = GPIO_Speed_2MHz,
1052  .GPIO_Mode = GPIO_Mode_AF,
1053  .GPIO_OType = GPIO_OType_PP,
1054  .GPIO_PuPd = GPIO_PuPd_NOPULL
1055  },
1056  .pin_source = GPIO_PinSource8,
1057  },
1058  },
1059  {
1060  .timer = TIM8,
1061  .timer_chan = TIM_Channel_4,
1062  .remap = GPIO_AF_TIM8,
1063  .pin = {
1064  .gpio = GPIOC,
1065  .init = {
1066  .GPIO_Pin = GPIO_Pin_9,
1067  .GPIO_Speed = GPIO_Speed_2MHz,
1068  .GPIO_Mode = GPIO_Mode_AF,
1069  .GPIO_OType = GPIO_OType_PP,
1070  .GPIO_PuPd = GPIO_PuPd_NOPULL
1071  },
1072  .pin_source = GPIO_PinSource9,
1073  },
1074  },
1075  {
1076  .timer = TIM2,
1077  .timer_chan = TIM_Channel_1,
1078  .remap = GPIO_AF_TIM2,
1079  .pin = {
1080  .gpio = GPIOA,
1081  .init = {
1082  .GPIO_Pin = GPIO_Pin_15,
1083  .GPIO_Speed = GPIO_Speed_2MHz,
1084  .GPIO_Mode = GPIO_Mode_AF,
1085  .GPIO_OType = GPIO_OType_PP,
1086  .GPIO_PuPd = GPIO_PuPd_NOPULL
1087  },
1088  .pin_source = GPIO_PinSource15,
1089  },
1090  },
1091  {
1092  .timer = TIM4,
1093  .timer_chan = TIM_Channel_3,
1094  .remap = GPIO_AF_TIM4,
1095  .pin = {
1096  .gpio = GPIOB,
1097  .init = {
1098  .GPIO_Pin = GPIO_Pin_8,
1099  .GPIO_Speed = GPIO_Speed_2MHz,
1100  .GPIO_Mode = GPIO_Mode_AF,
1101  .GPIO_OType = GPIO_OType_PP,
1102  .GPIO_PuPd = GPIO_PuPd_NOPULL
1103  },
1104  .pin_source = GPIO_PinSource8,
1105  },
1106  },
1107 };
1108 
1109 #if defined(PIOS_INCLUDE_DMASHOT)
1110 
1111 #include <pios_dmashot.h>
1112 
1113 /*
1114  * Outputs
1115  1: TIM3_CH1 (PC6) DMA1 Stream 2 Channel 5
1116  2: TIM8_CH2 (PC7) DMA2 Stream 1 Channel 7
1117  3: TIM8_CH3 (PC8)
1118  4: TIM8_CH4 (PC9)
1119  5: TIM2_CH1 (PA15) DMA1 Stream 1 Channel 3
1120  6: TIM1_CH1 (PA8) DMA2 Stream 5 Channel 6
1121  7: TIM4_CH3 (PB8) DMA1 Stream 6 Channel 2
1122  */
1123 
1124  static const struct pios_dmashot_timer_cfg dmashot_tim_cfg_without_led_string[] = {
1125  {
1126  .timer = TIM3,
1127  .stream = DMA1_Stream2,
1128  .channel = DMA_Channel_5,
1129  .tcif = DMA_FLAG_TCIF2
1130  },
1131  {
1132  .timer = TIM8,
1133  .stream = DMA2_Stream1,
1134  .channel = DMA_Channel_7,
1135  .tcif = DMA_FLAG_TCIF1
1136  },
1137  {
1138  .timer = TIM2,
1139  .stream = DMA1_Stream1,
1140  .channel = DMA_Channel_3,
1141  .tcif = DMA_FLAG_TCIF1
1142  },
1143  {
1144  .timer = TIM1,
1145  .stream = DMA2_Stream5,
1146  .channel = DMA_Channel_6,
1147  .tcif = DMA_FLAG_TCIF5
1148  },
1149  {
1150  .timer = TIM4,
1151  .stream = DMA1_Stream6,
1152  .channel = DMA_Channel_2,
1153  .tcif = DMA_FLAG_TCIF6
1154  },
1155 };
1156 
1157  static const struct pios_dmashot_timer_cfg dmashot_tim_cfg_with_led_string[] = {
1158  {
1159  .timer = TIM3,
1160  .stream = DMA1_Stream2,
1161  .channel = DMA_Channel_5,
1162  .tcif = DMA_FLAG_TCIF2
1163  },
1164  {
1165  .timer = TIM8,
1166  .stream = DMA2_Stream1,
1167  .channel = DMA_Channel_7,
1168  .tcif = DMA_FLAG_TCIF1
1169  },
1170  {
1171  .timer = TIM2,
1172  .stream = DMA1_Stream1,
1173  .channel = DMA_Channel_3,
1174  .tcif = DMA_FLAG_TCIF1
1175  },
1176  {
1177  .timer = TIM4,
1178  .stream = DMA1_Stream6,
1179  .channel = DMA_Channel_2,
1180  .tcif = DMA_FLAG_TCIF6
1181  },
1182 };
1183 
1184 static const struct pios_dmashot_cfg dmashot_config_without_led_string = {
1185  .timer_cfg = &dmashot_tim_cfg_without_led_string[0],
1186  .num_timers = NELEMENTS(dmashot_tim_cfg_without_led_string)
1187 };
1188 
1189 static const struct pios_dmashot_cfg dmashot_config_with_led_string = {
1190  .timer_cfg = &dmashot_tim_cfg_with_led_string[0],
1191  .num_timers = NELEMENTS(dmashot_tim_cfg_with_led_string)
1192 };
1193 
1194 #endif // defined(PIOS_INCLUDE_DMASHOT)
1195 
1196 #if defined(PIOS_INCLUDE_SERVO) && defined(PIOS_INCLUDE_TIM)
1197 /*
1198  * Servo outputs
1199  */
1200 #include <pios_servo_priv.h>
1201 
1202 static const struct pios_servo_cfg pios_servo_cfg_without_led_string = {
1203  .tim_oc_init = {
1204  .TIM_OCMode = TIM_OCMode_PWM1,
1205  .TIM_OutputState = TIM_OutputState_Enable,
1206  .TIM_OutputNState = TIM_OutputNState_Disable,
1207  .TIM_Pulse = PIOS_SERVOS_INITIAL_POSITION,
1208  .TIM_OCPolarity = TIM_OCPolarity_High,
1209  .TIM_OCNPolarity = TIM_OCPolarity_High,
1210  .TIM_OCIdleState = TIM_OCIdleState_Reset,
1211  .TIM_OCNIdleState = TIM_OCNIdleState_Reset,
1212  },
1214  .num_channels = NELEMENTS(pios_tim_outputs_pins_without_led_string),
1215 };
1216 
1217 static const struct pios_servo_cfg pios_servo_cfg_with_led_string = {
1218  .tim_oc_init = {
1219  .TIM_OCMode = TIM_OCMode_PWM1,
1220  .TIM_OutputState = TIM_OutputState_Enable,
1221  .TIM_OutputNState = TIM_OutputNState_Disable,
1222  .TIM_Pulse = PIOS_SERVOS_INITIAL_POSITION,
1223  .TIM_OCPolarity = TIM_OCPolarity_High,
1224  .TIM_OCNPolarity = TIM_OCPolarity_High,
1225  .TIM_OCIdleState = TIM_OCIdleState_Reset,
1226  .TIM_OCNIdleState = TIM_OCNIdleState_Reset,
1227  },
1229  .num_channels = NELEMENTS(pios_tim_outputs_pins_with_led_string),
1230 };
1231 
1232 #endif /* PIOS_INCLUDE_SERVO && PIOS_INCLUDE_TIM */
1233 
1234 /*
1235  * PPM INPUT
1236  1: TIM5_CH4 (PA3)
1237  */
1238 static const struct pios_tim_channel pios_tim_rcvrport_ppm[] = {
1239  {
1240  .timer = TIM5,
1241  .timer_chan = TIM_Channel_4,
1242  .remap = GPIO_AF_TIM5,
1243  .pin = {
1244  .gpio = GPIOA,
1245  .init = {
1246  .GPIO_Pin = GPIO_Pin_3,
1247  .GPIO_Speed = GPIO_Speed_2MHz,
1248  .GPIO_Mode = GPIO_Mode_AF,
1249  .GPIO_OType = GPIO_OType_PP,
1250  .GPIO_PuPd = GPIO_PuPd_UP
1251  },
1252  .pin_source = GPIO_PinSource3,
1253  },
1254  },
1255 };
1256 
1257 /*
1258  * PPM Input
1259  */
1260 #if defined(PIOS_INCLUDE_PPM)
1261 #include <pios_ppm_priv.h>
1262 
1263 /*
1264  * PPM Input
1265  */
1266 const struct pios_ppm_cfg pios_ppm_cfg = {
1267  .tim_ic_init = {
1268  .TIM_ICPolarity = TIM_ICPolarity_Rising,
1269  .TIM_ICSelection = TIM_ICSelection_DirectTI,
1270  .TIM_ICPrescaler = TIM_ICPSC_DIV1,
1271  .TIM_ICFilter = 0x0,
1272  .TIM_Channel = TIM_Channel_4,
1273  },
1274  .channels = &pios_tim_rcvrport_ppm[0],
1275  .num_channels = 1,
1276 };
1277 
1278 #endif
1279 
1280 #if defined(PIOS_INCLUDE_RCVR)
1281 #include "pios_rcvr_priv.h"
1282 #endif /* PIOS_INCLUDE_RCVR */
1283 
1284 #if defined(PIOS_INCLUDE_USB)
1285 #include "pios_usb_priv.h"
1286 
1287 static const struct pios_usb_cfg pios_usb_main_cfg = {
1288  .irq = {
1289  .init = {
1290  .NVIC_IRQChannel = OTG_FS_IRQn,
1291  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
1292  .NVIC_IRQChannelSubPriority = 0,
1293  .NVIC_IRQChannelCmd = ENABLE,
1294  },
1295  },
1296  .vsense = {
1297  .gpio = NULL,
1298  },
1299 };
1300 
1301 const struct pios_usb_cfg * PIOS_BOARD_HW_DEFS_GetUsbCfg (uint32_t board_revision)
1302 {
1303  return &pios_usb_main_cfg;
1304 }
1305 
1306 #include "pios_usb_board_data_priv.h"
1309 #include "pios_usbhook.h"
1310 
1311 #endif /* PIOS_INCLUDE_USB */
1312 
1313 #if defined(PIOS_INCLUDE_COM_MSG)
1314 
1315 #include <pios_com_msg_priv.h>
1316 
1317 #endif /* PIOS_INCLUDE_COM_MSG */
1318 
1319 #if defined(PIOS_INCLUDE_USB_HID) && !defined(PIOS_INCLUDE_USB_CDC)
1320 #include <pios_usb_hid_priv.h>
1321 
1322 const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
1323  .data_if = 0,
1324  .data_rx_ep = 1,
1325  .data_tx_ep = 1,
1326 };
1327 #endif /* PIOS_INCLUDE_USB_HID && !PIOS_INCLUDE_USB_CDC */
1328 
1329 #if defined(PIOS_INCLUDE_USB_HID) && defined(PIOS_INCLUDE_USB_CDC)
1330 #include <pios_usb_cdc_priv.h>
1331 
1332 const struct pios_usb_cdc_cfg pios_usb_cdc_cfg = {
1333  .ctrl_if = 0,
1334  .ctrl_tx_ep = 2,
1335 
1336  .data_if = 1,
1337  .data_rx_ep = 3,
1338  .data_tx_ep = 3,
1339 };
1340 
1341 #include <pios_usb_hid_priv.h>
1342 
1343 const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
1344  .data_if = 2,
1345  .data_rx_ep = 1,
1346  .data_tx_ep = 1,
1347 };
1348 #endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_USB_CDC */
1349 
1350 #if defined(PIOS_INCLUDE_ADC)
1351 #include "pios_adc_priv.h"
1352 #include "pios_internal_adc_priv.h"
1353 
1354 void PIOS_ADC_DMA_irq_handler(void);
1355 void DMA2_Stream0_IRQHandler(void) __attribute__((alias("PIOS_ADC_DMA_irq_handler")));
1356 struct pios_internal_adc_cfg pios_adc_cfg = {
1357  .adc_dev_master = ADC1,
1358  .dma = {
1359  .irq = {
1360  .flags = (DMA_FLAG_TCIF0 | DMA_FLAG_TEIF0 | DMA_FLAG_HTIF0),
1361  .init = {
1362  .NVIC_IRQChannel = DMA2_Stream0_IRQn,
1363  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
1364  .NVIC_IRQChannelSubPriority = 0,
1365  .NVIC_IRQChannelCmd = ENABLE,
1366  },
1367  },
1368  .rx = {
1369  .channel = DMA2_Stream0,
1370  .init = {
1371  .DMA_Channel = DMA_Channel_0,
1372  .DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR
1373  },
1374  }
1375  },
1376  .half_flag = DMA_IT_HTIF0,
1377  .full_flag = DMA_IT_TCIF0,
1378  .adc_pins = { \
1379  { GPIOC, GPIO_Pin_4, ADC_Channel_14 }, /* Current */ \
1380  { GPIOC, GPIO_Pin_5, ADC_Channel_15 }, /* Voltage */ \
1381  { GPIOB, GPIO_Pin_1, ADC_Channel_9 }, /* RSSI */ \
1382  },
1383  .adc_pin_count = 3,
1384 };
1385 
1386 void PIOS_ADC_DMA_irq_handler(void)
1387 {
1388  /* Call into the generic code to handle the IRQ for this specific device */
1390 }
1391 
1392 #endif /* PIOS_INCLUDE_ADC */
1393 
1398 #if defined(PIOS_INCLUDE_WS2811)
1399 #include "pios_ws2811.h"
1400 
1402 
1403 void DMA2_Stream6_IRQHandler() {
1404  PIOS_WS2811_dma_interrupt_handler(pios_ws2811);
1405 }
1406 
1407 static const struct pios_ws2811_cfg pios_ws2811_cfg = {
1408  .timer = TIM1,
1409  .clock_cfg = {
1410  .TIM_Prescaler = (PIOS_PERIPHERAL_APB2_COUNTER_CLOCK / 12000000) - 1,
1411  .TIM_ClockDivision = TIM_CKD_DIV1,
1412  .TIM_CounterMode = TIM_CounterMode_Up,
1413  .TIM_Period = 25, /* 2.083us/bit */
1414  },
1415  .interrupt = {
1416  .NVIC_IRQChannel = DMA2_Stream6_IRQn,
1417  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
1418  .NVIC_IRQChannelSubPriority = 0,
1419  .NVIC_IRQChannelCmd = ENABLE,
1420  },
1421  .bit_clear_dma_tcif = DMA_IT_TCIF6,
1422  .fall_time_l = 5, /* 333ns */
1423  .fall_time_h = 11, /* 833ns */
1424  .led_gpio = GPIOA,
1425  .gpio_pin = GPIO_Pin_8, /* PA8 */
1426  .bit_set_dma_stream = DMA2_Stream4,
1427  .bit_set_dma_channel = DMA_Channel_6, /* 2/S4/C6: TIM1 CH4|TRIG|COM */
1428  .bit_clear_dma_stream = DMA2_Stream6,
1429  .bit_clear_dma_channel = DMA_Channel_0, /* 0/S6/C0: TIM1 CH1|CH2|CH3 */
1430 };
1431 #endif
1432 
1433 #if defined(PIOS_INCLUDE_DAC)
1434 #include "pios_dac.h"
1435 
1436 dac_dev_t pios_dac;
1437 
1438 void DMA1_Stream5_IRQHandler() {
1440 }
1441 
1442 typedef struct dac_dev_s *dac_dev_t;
1443 
1444 struct pios_dac_cfg pios_dac_cfg = {
1445  .timer = TIM6,
1446  .clock_cfg = {
1447  .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_COUNTER_CLOCK / 600000) - 1,
1448  .TIM_ClockDivision = TIM_CKD_DIV1,
1449  .TIM_CounterMode = TIM_CounterMode_Up,
1450  .TIM_Period = 25-1, /* 600000 / 25 = 24000 samples per sec */
1451  },
1452  .interrupt = {
1453  .NVIC_IRQChannel = DMA1_Stream5_IRQn,
1454  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
1455  .NVIC_IRQChannelSubPriority = 0,
1456  .NVIC_IRQChannelCmd = ENABLE,
1457  },
1458  .gpio = GPIOA,
1459  .gpio_pin = GPIO_Pin_4,
1460  .dma_stream = DMA1_Stream5,
1461  .dma_channel = DMA_Channel_7,
1462  .dac_channel = DAC_Channel_1,
1463  .dac_trigger = DAC_Trigger_T6_TRGO,
1464  .dac_outreg = (uintptr_t) (&DAC->DHR12L1),
1465  .dma_tcif = DMA_IT_TCIF5,
1466 };
1467 
1468 #endif /* PIOS_INCLUDE_DAC */
1469 
1473 #if defined(PIOS_INCLUDE_MPU)
1474 #include "pios_mpu.h"
1475 static const struct pios_exti_cfg pios_exti_mpu_cfg __exti_config = {
1476  .vector = PIOS_MPU_IRQHandler,
1477  .line = EXTI_Line3,
1478  .pin = {
1479  .gpio = GPIOC,
1480  .init = {
1481  .GPIO_Pin = GPIO_Pin_3,
1482  .GPIO_Speed = GPIO_Speed_100MHz,
1483  .GPIO_Mode = GPIO_Mode_IN,
1484  .GPIO_OType = GPIO_OType_OD,
1485  .GPIO_PuPd = GPIO_PuPd_NOPULL,
1486  },
1487  },
1488  .irq = {
1489  .init = {
1490  .NVIC_IRQChannel = EXTI3_IRQn,
1491  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
1492  .NVIC_IRQChannelSubPriority = 0,
1493  .NVIC_IRQChannelCmd = ENABLE,
1494  },
1495  },
1496  .exti = {
1497  .init = {
1498  .EXTI_Line = EXTI_Line3, // matches above GPIO pin
1499  .EXTI_Mode = EXTI_Mode_Interrupt,
1500  .EXTI_Trigger = EXTI_Trigger_Rising,
1501  .EXTI_LineCmd = ENABLE,
1502  },
1503  },
1504 };
1505 
1506 static struct pios_mpu_cfg pios_mpu_cfg = {
1507  .exti_cfg = &pios_exti_mpu_cfg,
1508  .default_samplerate = 1000,
1509  .orientation = PIOS_MPU_TOP_180DEG
1510 };
1511 #endif /* PIOS_INCLUDE_MPU */
1512 
1516 #ifdef PIOS_INCLUDE_BMP280
1517 #include "pios_bmp280_priv.h"
1518 
1519 static const struct pios_bmp280_cfg pios_bmp280_cfg = {
1521 };
1522 #endif /* PIOS_INCLUDE_BMP280 */
1523 
1524 #ifdef PIOS_INCLUDE_HMC5883
1525 #include "pios_hmc5883_priv.h"
1526 static const struct pios_hmc5883_cfg pios_hmc5883_external_cfg = {
1527  .exti_cfg = NULL,
1528  .M_ODR = PIOS_HMC5883_ODR_75,
1529  .Meas_Conf = PIOS_HMC5883_MEASCONF_NORMAL,
1530  .Gain = PIOS_HMC5883_GAIN_1_9,
1532  .Default_Orientation = PIOS_HMC5883_TOP_0DEG,
1533 };
1534 #endif
1535 
1536 #ifdef PIOS_INCLUDE_HMC5983_I2C
1537 #include "pios_hmc5983.h"
1538 
1539 static const struct pios_hmc5983_cfg pios_hmc5983_external_cfg = {
1540  .exti_cfg = NULL,
1541  .M_ODR = PIOS_HMC5983_ODR_75,
1542  .Meas_Conf = PIOS_HMC5983_MEASCONF_NORMAL,
1543  .Gain = PIOS_HMC5983_GAIN_1_9,
1545  .Averaging = PIOS_HMC5983_AVERAGING_1,
1546  .Orientation = PIOS_HMC5983_TOP_0DEG,
1547 };
1548 
1549 #endif
1550 
struct stm32_gpio pin
const struct pios_exti_cfg * exti_cfg
static const struct pios_tim_clock_cfg tim_2_cfg
const struct pios_dmashot_timer_cfg * timer_cfg
Definition: pios_dmashot.h:68
#define PIOS_HMC5883_ODR_75
#define DMA1_Stream5_IRQHandler
static const TIM_TimeBaseInitTypeDef tim_1_8_time_base
SPI private definitions.
#define NELEMENTS(x)
Definition: pios.h:192
TIM_TypeDef * timer
Definition: pios_dmashot.h:53
#define I2C2_EV_IRQHandler
struct stm32_gpio bind
HMC5983 functions header.
static const struct pios_tim_clock_cfg tim_8_cfg
COM private definitions.
COM MSG private definitions.
APIs for PIOS_USBHOOK layer.
GPIO_TypeDef * gpio
Definition: pios_stm32.h:60
#define PIOS_HMC5883_MODE_CONTINUOUS
I2C_TypeDef * regs
Definition: pios_i2c_priv.h:37
ADC private definitions.
static const struct pios_tim_clock_cfg tim_4_cfg
#define PIOS_IRQ_PRIO_HIGHEST
Definition: pios_board.h:172
Configuration structure for the BMP280 driver.
#define PIOS_SERVOS_INITIAL_POSITION
Definition: pios_board.h:210
Defines the API to set up the HID + CDC USB descriptor config.
void PIOS_INTERNAL_ADC_DMA_Handler()
#define RTC_WKUP_IRQHandler
#define PIOS_LED_ALARM
Definition: pios_board.h:86
#define PIOS_IRQ_PRIO_MID
Definition: pios_board.h:170
USART private definitions.
#define DMA2_Stream0_IRQHandler
Spektrum/JR DSMx satellite receiver private structures.
#define I2C2_ER_IRQHandler
static const struct pios_tim_clock_cfg tim_3_cfg
#define FLASH_SECTOR_64KB
const struct pios_exti_cfg * exti_cfg
Definition: pios_mpu.h:140
#define PIOS_SERVO_UPDATE_HZ
Definition: pios_board.h:209
#define PIOS_HMC5983_MEASCONF_NORMAL
Definition: pios_hmc5983.h:67
Configuration struct holding all timer configurations.
Definition: pios_dmashot.h:66
TIM_TypeDef * timer
Definition: pios_tim_priv.h:7
SPI_TypeDef * regs
Definition: pios_spi_priv.h:44
Configuration struct to assign a DMA channel and stream to a timer, and optionally specify a master t...
Definition: pios_dmashot.h:51
const struct pios_exti_cfg * exti_cfg
Definition: pios_hmc5983.h:121
static const TIM_TimeBaseInitTypeDef tim_5_time_base
#define PIOS_HMC5983_MODE_CONTINUOUS
Definition: pios_hmc5983.h:82
struct pios_i2c_adapter * pios_i2c_t
Definition: pios_i2c.h:48
static const struct pios_tim_clock_cfg tim_1_cfg
ws2811_dev_t pios_ws2811
Definition: pios_board.c:66
const struct pios_annunc * annunciators
void PIOS_I2C_EV_IRQ_Handler(pios_i2c_t i2c_id)
static const struct pios_tim_channel pios_tim_outputs_pins_with_led_string[]
#define PIOS_HMC5883_GAIN_1_9
#define PIOS_HMC5983_ODR_75
Definition: pios_hmc5983.h:63
TIM_TypeDef * timer
ppm private structures.
NVIC_InitTypeDef init
Definition: pios_stm32.h:36
#define I2C1_ER_IRQHandler
USART_TypeDef * regs
USB private definitions.
TIM_OCInitTypeDef tim_oc_init
USB COM HID private definitions.
#define I2C1_EV_IRQHandler
ADC private definitions.
Servo private structures.
#define FLASH_SECTOR_16KB
NVIC_InitTypeDef interrupt
Definition: pios_dac.h:46
#define PIOS_HMC5983_GAIN_1_9
Definition: pios_hmc5983.h:74
void PIOS_I2C_ER_IRQ_Handler(pios_i2c_t i2c_id)
TIM_ICInitTypeDef tim_ic_init
Definition: pios_ppm_priv.h:37
#define DMA2_Stream6_IRQHandler
Defines the API to set up the HID-only USB descriptor config.
static const struct pios_tim_channel pios_tim_rcvrport_ppm[]
NVIC_InitTypeDef interrupt
#define PIOS_HMC5883_MEASCONF_NORMAL
void PIOS_RTC_irq_handler(void)
void PIOS_WS2811_dma_interrupt_handler(ws2811_dev_t dev)
Handles a DMA completion interrupt on bit_clear_dma_stream.
struct dac_dev_s * dac_dev_t
Definition: pios_dac.h:40
bool PIOS_MPU_IRQHandler(void)
The IMU interrupt handler. Fetches new data from the IMU.
const struct pios_flash_driver * driver
const struct pios_flash_partition pios_flash_partition_table[]
Definition: unittest_init.c:50
static const struct pios_tim_channel pios_tim_outputs_pins_without_led_string[]
#define PIOS_IRQ_PRIO_HIGH
Definition: pios_board.h:171
TIM_TypeDef * timer
Definition: pios_tim_priv.h:14
USB COM CDC private definitions.
uint32_t clksrc
Definition: pios_rtc_priv.h:37
SPI_InitTypeDef init
Definition: pios_spi_priv.h:46
enum pios_flash_partition_labels label
board_revision
Definition: board_hw_defs.c:35
TIM_TypeDef * timer
Definition: pios_dac.h:43
static const TIM_TimeBaseInitTypeDef tim_2_3_4_time_base
#define PIOS_IRQ_PRIO_LOW
Definition: pios_board.h:169
#define PIOS_Assert(test)
Definition: pios_debug.h:52
LED private definitions.
void PIOS_DAC_dma_interrupt_handler(dac_dev_t dev)
Handles a DMA completion interrupt on dma_stream.
#define BMP280_HIGH_RESOLUTION
#define PIOS_ANNUNCIATOR_BUZZER
Definition: pios_board.h:87
struct stm32_irq irq
Definition: pios_usb_priv.h:37
#define FLASH_SECTOR_128KB
static const struct pios_tim_clock_cfg tim_5_cfg
const struct pios_flash_driver pios_internal_flash_driver
USART private definitions.
#define PIOS_LED_HEARTBEAT
Definition: pios_board.h:85
#define __exti_config
Definition: pios_exti.h:48
#define PIOS_HMC5983_AVERAGING_1
Definition: pios_hmc5983.h:97
Defines the API to the board-specific USB data setup code.