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  * Additional note on redistribution: The copyright and license notices above
30  * must be maintained in each individual source file that is a derivative work
31  * of this source file; otherwise redistribution is prohibited.
32  */
33 #include <pios_config.h>
34 #include <pios_board_info.h>
35 
36 #if defined(PIOS_INCLUDE_ANNUNC)
37 
38 #include <pios_annunc_priv.h>
39 
40 static const struct pios_annunc pios_annuncs[] = {
41  [PIOS_LED_HEARTBEAT] = {
42  .pin = {
43  .gpio = GPIOB,
44  .init = {
45  .GPIO_Pin = GPIO_Pin_5,
46  .GPIO_Speed = GPIO_Speed_50MHz,
47  .GPIO_Mode = GPIO_Mode_OUT,
48  .GPIO_OType = GPIO_OType_PP,
49  .GPIO_PuPd = GPIO_PuPd_UP
50  },
51  },
52  },
53  [PIOS_LED_ALARM] = {
54  .pin = {
55  .gpio = GPIOB,
56  .init = {
57  .GPIO_Pin = GPIO_Pin_4,
58  .GPIO_Speed = GPIO_Speed_50MHz,
59  .GPIO_Mode = GPIO_Mode_OUT,
60  .GPIO_OType = GPIO_OType_PP,
61  .GPIO_PuPd = GPIO_PuPd_UP
62  },
63  },
64  },
65  [PIOS_LED_LINK] = {
66  .pin = {
67  .gpio = GPIOB,
68  .init = {
69  .GPIO_Pin = GPIO_Pin_6,
70  .GPIO_Speed = GPIO_Speed_50MHz,
71  .GPIO_Mode = GPIO_Mode_OUT,
72  .GPIO_OType = GPIO_OType_PP,
73  .GPIO_PuPd = GPIO_PuPd_UP
74  },
75  },
76  },
77 };
78 
79 static const struct pios_annunc_cfg pios_annunc_cfg = {
80  .annunciators = pios_annuncs,
81  .num_annunciators = NELEMENTS(pios_annuncs),
82 };
83 
84 const struct pios_annunc_cfg * PIOS_BOARD_HW_DEFS_GetLedCfg (uint32_t board_revision)
85 {
86  return &pios_annunc_cfg;
87 }
88 
89 #endif /* PIOS_INCLUDE_ANNUNC */
90 
91 #if defined(PIOS_INCLUDE_SPI)
92 #include <pios_spi_priv.h>
93 
94 /*
95  * SPI1 Interface
96  * Used for MPU9250 gyro, accelerometer and mag
97  */
98 static const struct pios_spi_cfg pios_spi_gyro_cfg = {
99  .regs = SPI1,
100  .remap = GPIO_AF_SPI1,
101  .init = {
102  .SPI_Mode = SPI_Mode_Master,
103  .SPI_Direction = SPI_Direction_2Lines_FullDuplex,
104  .SPI_DataSize = SPI_DataSize_8b,
105  .SPI_NSS = SPI_NSS_Soft,
106  .SPI_FirstBit = SPI_FirstBit_MSB,
107  .SPI_CRCPolynomial = 7,
108  .SPI_CPOL = SPI_CPOL_High,
109  .SPI_CPHA = SPI_CPHA_2Edge,
110  .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16,
111  },
112  .sclk = {
113  .gpio = GPIOA,
114  .init = {
115  .GPIO_Pin = GPIO_Pin_5,
116  .GPIO_Speed = GPIO_Speed_100MHz,
117  .GPIO_Mode = GPIO_Mode_AF,
118  .GPIO_OType = GPIO_OType_PP,
119  .GPIO_PuPd = GPIO_PuPd_UP
120  },
121  },
122  .miso = {
123  .gpio = GPIOA,
124  .init = {
125  .GPIO_Pin = GPIO_Pin_6,
126  .GPIO_Speed = GPIO_Speed_50MHz,
127  .GPIO_Mode = GPIO_Mode_AF,
128  .GPIO_OType = GPIO_OType_PP,
129  .GPIO_PuPd = GPIO_PuPd_UP
130  },
131  },
132  .mosi = {
133  .gpio = GPIOA,
134  .init = {
135  .GPIO_Pin = GPIO_Pin_7,
136  .GPIO_Speed = GPIO_Speed_50MHz,
137  .GPIO_Mode = GPIO_Mode_AF,
138  .GPIO_OType = GPIO_OType_PP,
139  .GPIO_PuPd = GPIO_PuPd_UP
140  },
141  },
142  .slave_count = 1,
143  .ssel = { {
144  .gpio = GPIOC,
145  .init = {
146  .GPIO_Pin = GPIO_Pin_4,
147  .GPIO_Speed = GPIO_Speed_50MHz,
148  .GPIO_Mode = GPIO_Mode_OUT,
149  .GPIO_OType = GPIO_OType_PP,
150  .GPIO_PuPd = GPIO_PuPd_UP
151  } }
152  }
153 };
154 
155 /*
156  * SPI3 Interface
157  * Used for Flash and the RFM22B
158  */
159 static const struct pios_spi_cfg pios_spi_telem_flash_cfg = {
160  .regs = SPI3,
161  .remap = GPIO_AF_SPI3,
162  .init = {
163  .SPI_Mode = SPI_Mode_Master,
164  .SPI_Direction = SPI_Direction_2Lines_FullDuplex,
165  .SPI_DataSize = SPI_DataSize_8b,
166  .SPI_NSS = SPI_NSS_Soft,
167  .SPI_FirstBit = SPI_FirstBit_MSB,
168  .SPI_CRCPolynomial = 7,
169  .SPI_CPOL = SPI_CPOL_Low,
170  .SPI_CPHA = SPI_CPHA_1Edge,
171  .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8,
172  },
173  .sclk = {
174  .gpio = GPIOC,
175  .init = {
176  .GPIO_Pin = GPIO_Pin_10,
177  .GPIO_Speed = GPIO_Speed_100MHz,
178  .GPIO_Mode = GPIO_Mode_AF,
179  .GPIO_OType = GPIO_OType_PP,
180  .GPIO_PuPd = GPIO_PuPd_NOPULL
181  },
182  },
183  .miso = {
184  .gpio = GPIOC,
185  .init = {
186  .GPIO_Pin = GPIO_Pin_11,
187  .GPIO_Speed = GPIO_Speed_50MHz,
188  .GPIO_Mode = GPIO_Mode_AF,
189  .GPIO_OType = GPIO_OType_PP,
190  .GPIO_PuPd = GPIO_PuPd_NOPULL
191  },
192  },
193  .mosi = {
194  .gpio = GPIOC,
195  .init = {
196  .GPIO_Pin = GPIO_Pin_12,
197  .GPIO_Speed = GPIO_Speed_50MHz,
198  .GPIO_Mode = GPIO_Mode_AF,
199  .GPIO_OType = GPIO_OType_PP,
200  .GPIO_PuPd = GPIO_PuPd_NOPULL
201  },
202  },
203  .slave_count = 2,
204  .ssel = {
205  { // RFM22b
206  .gpio = GPIOA,
207  .init = {
208  .GPIO_Pin = GPIO_Pin_15,
209  .GPIO_Speed = GPIO_Speed_50MHz,
210  .GPIO_Mode = GPIO_Mode_OUT,
211  .GPIO_OType = GPIO_OType_PP,
212  .GPIO_PuPd = GPIO_PuPd_UP
213  } },
214  { // Flash
215  .gpio = GPIOB,
216  .init = {
217  .GPIO_Pin = GPIO_Pin_3,
218  .GPIO_Speed = GPIO_Speed_50MHz,
219  .GPIO_Mode = GPIO_Mode_OUT,
220  .GPIO_OType = GPIO_OType_PP,
221  .GPIO_PuPd = GPIO_PuPd_UP
222  } },
223  },
224 };
225 
226 pios_spi_t pios_spi_telem_flash_id;
227 
228 #if defined(PIOS_INCLUDE_OPENLRS)
229 
230 #include <pios_openlrs_priv.h>
231 
232 pios_openlrs_t openlrs_handle;
233 
234 static bool openlrs_int(void) {
235  return PIOS_OpenLRS_EXT_Int(openlrs_handle);
236 }
237 
238 static const struct pios_exti_cfg pios_exti_openlrs_pb7_cfg __exti_config = {
239  .vector = openlrs_int,
240  .line = EXTI_Line7,
241  .pin = {
242  .gpio = GPIOB,
243  .init = {
244  .GPIO_Pin = GPIO_Pin_7,
245  .GPIO_Speed = GPIO_Speed_100MHz,
246  .GPIO_Mode = GPIO_Mode_IN,
247  .GPIO_OType = GPIO_OType_OD,
248  .GPIO_PuPd = GPIO_PuPd_NOPULL,
249  },
250  },
251  .irq = {
252  .init = {
253  .NVIC_IRQChannel = EXTI9_5_IRQn,
254  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
255  .NVIC_IRQChannelSubPriority = 0,
256  .NVIC_IRQChannelCmd = ENABLE,
257  },
258  },
259  .exti = {
260  .init = {
261  .EXTI_Line = EXTI_Line7, // matches above GPIO pin
262  .EXTI_Mode = EXTI_Mode_Interrupt,
263  .EXTI_Trigger = EXTI_Trigger_Falling,
264  .EXTI_LineCmd = ENABLE,
265  },
266  },
267 };
268 
269 static const struct pios_exti_cfg pios_exti_openlrs_pbd2_cfg __exti_config = {
270  .vector = openlrs_int,
271  .line = EXTI_Line2,
272  .pin = {
273  .gpio = GPIOD,
274  .init = {
275  .GPIO_Pin = GPIO_Pin_2,
276  .GPIO_Speed = GPIO_Speed_100MHz,
277  .GPIO_Mode = GPIO_Mode_IN,
278  .GPIO_OType = GPIO_OType_OD,
279  .GPIO_PuPd = GPIO_PuPd_NOPULL,
280  },
281  },
282  .irq = {
283  .init = {
284  .NVIC_IRQChannel = EXTI2_IRQn,
285  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
286  .NVIC_IRQChannelSubPriority = 0,
287  .NVIC_IRQChannelCmd = ENABLE,
288  },
289  },
290  .exti = {
291  .init = {
292  .EXTI_Line = EXTI_Line2, // matches above GPIO pin
293  .EXTI_Mode = EXTI_Mode_Interrupt,
294  .EXTI_Trigger = EXTI_Trigger_Falling,
295  .EXTI_LineCmd = ENABLE,
296  },
297  },
298 };
299 
300 const struct pios_openlrs_cfg pios_openlrs_pb7_cfg = {
301  .spi_cfg = &pios_spi_telem_flash_cfg,
302  .exti_cfg = &pios_exti_openlrs_pb7_cfg,
303  .gpio_direction = GPIO0_TX_GPIO1_RX,
304 };
305 
306 const struct pios_openlrs_cfg pios_openlrs_pd2_cfg = {
307  .spi_cfg = &pios_spi_telem_flash_cfg,
308  .exti_cfg = &pios_exti_openlrs_pbd2_cfg,
309  .gpio_direction = GPIO0_TX_GPIO1_RX,
310 };
311 
312 const struct pios_openlrs_cfg * PIOS_BOARD_HW_DEFS_GetOpenLRSCfg (uint32_t board_revision)
313 {
314  switch(board_revision) {
315  case SPARKY2_V2_0:
316  return &pios_openlrs_pd2_cfg;
317  case BRUSHEDSPARKY_V0_1:
318  return &pios_openlrs_pd2_cfg;
319  case BRUSHEDSPARKY_V0_2:
320  return &pios_openlrs_pb7_cfg;
321  }
322 
323  PIOS_Assert(0);
324 }
325 
326 #endif /* PIOS_INCLUDE_OPENLRS */
327 
328 #endif /* PIOS_INCLUDE_SPI */
329 
330 #if defined(PIOS_INCLUDE_FLASH)
331 #include "pios_flashfs_logfs_priv.h"
332 
333 static const struct flashfs_logfs_cfg flashfs_settings_internal_cfg = {
334  .fs_magic = 0x99abcedf,
335  .arena_size = 0x00004000, /* 256 * slot size */
336  .slot_size = 0x00000100, /* 256 bytes */
337 };
338 
339 static const struct flashfs_logfs_cfg flashfs_settings_external_cfg = {
340  .fs_magic = 0x77abcedf,
341  .arena_size = 0x00010000, /* 256 * slot size */
342  .slot_size = 0x00000100, /* 256 bytes */
343 };
344 
345 #if defined(PIOS_INCLUDE_FLASH_JEDEC)
346 #include "pios_flash_jedec_priv.h"
347 
348 static const struct pios_flash_jedec_cfg flash_m25p_cfg = {
350  .expect_memorytype = 0x20,
351  .expect_capacity = 0x15,
352  .sector_erase = 0xD8,
353 };
354 #endif /* PIOS_INCLUDE_FLASH_JEDEC */
355 
356 #if defined(PIOS_INCLUDE_FLASH_INTERNAL)
358 
359 static const struct pios_flash_internal_cfg flash_internal_cfg = {
360 };
361 #endif /* PIOS_INCLUDE_FLASH_INTERNAL */
362 
363 #include "pios_flash_priv.h"
364 
365 #if defined(PIOS_INCLUDE_FLASH_INTERNAL)
366 static const struct pios_flash_sector_range stm32f4_sectors[] = {
367  {
368  .base_sector = 0,
369  .last_sector = 3,
370  .sector_size = FLASH_SECTOR_16KB,
371  },
372  {
373  .base_sector = 4,
374  .last_sector = 4,
375  .sector_size = FLASH_SECTOR_64KB,
376  },
377  {
378  .base_sector = 5,
379  .last_sector = 11,
380  .sector_size = FLASH_SECTOR_128KB,
381  },
382 
383 };
384 
385 uintptr_t pios_internal_flash_id;
386 static const struct pios_flash_chip pios_flash_chip_internal = {
388  .chip_id = &pios_internal_flash_id,
389  .page_size = 16, /* 128-bit rows */
390  .sector_blocks = stm32f4_sectors,
391  .num_blocks = NELEMENTS(stm32f4_sectors),
392 };
393 #endif /* PIOS_INCLUDE_FLASH_INTERNAL */
394 
395 #if defined(PIOS_INCLUDE_FLASH_JEDEC)
396 static const struct pios_flash_sector_range m25p16_sectors[] = {
397  {
398  .base_sector = 0,
399  .last_sector = 31,
400  .sector_size = FLASH_SECTOR_64KB,
401  },
402 };
403 
404 uintptr_t pios_external_flash_id;
405 static const struct pios_flash_chip pios_flash_chip_external = {
407  .chip_id = &pios_external_flash_id,
408  .page_size = 256,
409  .sector_blocks = m25p16_sectors,
410  .num_blocks = NELEMENTS(m25p16_sectors),
411 };
412 #endif /* PIOS_INCLUDE_FLASH_JEDEC */
413 
414 static const struct pios_flash_partition pios_flash_partition_table_external[] = {
415 #if defined(PIOS_INCLUDE_FLASH_INTERNAL)
416  {
418  .chip_desc = &pios_flash_chip_internal,
419  .first_sector = 0,
420  .last_sector = 1,
421  .chip_offset = 0,
422  .size = (1 - 0 + 1) * FLASH_SECTOR_16KB,
423  },
424 
425  {
426  .label = FLASH_PARTITION_LABEL_FW,
427  .chip_desc = &pios_flash_chip_internal,
428  .first_sector = 5,
429  .last_sector = 7,
430  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB),
431  .size = (7 - 5 + 1) * FLASH_SECTOR_128KB,
432  },
433 
434  /* NOTE: sectors 8-9, 11 of the internal flash are currently unallocated */
435  {
437  .chip_desc = &pios_flash_chip_internal,
438  .first_sector = 10,
439  .last_sector = 10,
440  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB) + (5 * FLASH_SECTOR_128KB),
441  .size = (10 - 10 + 1) * FLASH_SECTOR_128KB,
442  },
443 
444 #endif /* PIOS_INCLUDE_FLASH_INTERNAL */
445 
446 #if defined(PIOS_INCLUDE_FLASH_JEDEC)
447  {
449  .chip_desc = &pios_flash_chip_external,
450  .first_sector = 0,
451  .last_sector = 5,
452  .chip_offset = 0,
453  .size = (5 - 0 + 1) * FLASH_SECTOR_64KB,
454  },
455 
456  {
458  .chip_desc = &pios_flash_chip_external,
459  .first_sector = 6,
460  .last_sector = 10,
461  .chip_offset = (6 * FLASH_SECTOR_64KB),
462  .size = (10 - 6 + 1) * FLASH_SECTOR_64KB,
463  },
464 
465  {
466  .label = FLASH_PARTITION_LABEL_LOG,
467  .chip_desc = &pios_flash_chip_external,
468  .first_sector = 16,
469  .last_sector = 31,
470  .chip_offset = (16 * FLASH_SECTOR_64KB),
471  .size = (31 - 16 + 1) * FLASH_SECTOR_64KB,
472  },
473 #endif /* PIOS_INCLUDE_FLASH_JEDEC */
474 };
475 
476 static const struct pios_flash_partition pios_flash_partition_table_internal[] = {
477 #if defined(PIOS_INCLUDE_FLASH_INTERNAL)
478  {
480  .chip_desc = &pios_flash_chip_internal,
481  .first_sector = 0,
482  .last_sector = 1,
483  .chip_offset = 0,
484  .size = (1 - 0 + 1) * FLASH_SECTOR_16KB,
485  },
486 
487  {
489  .chip_desc = &pios_flash_chip_internal,
490  .first_sector = 2,
491  .last_sector = 3,
492  .chip_offset = (2 * FLASH_SECTOR_16KB),
493  .size = (3 - 2 + 1) * FLASH_SECTOR_16KB,
494  },
495 
496  {
497  .label = FLASH_PARTITION_LABEL_FW,
498  .chip_desc = &pios_flash_chip_internal,
499  .first_sector = 5,
500  .last_sector = 7,
501  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB),
502  .size = (7 - 5 + 1) * FLASH_SECTOR_128KB,
503  },
504  {
506  .chip_desc = &pios_flash_chip_internal,
507  .first_sector = 10,
508  .last_sector = 10,
509  .chip_offset = (4 * FLASH_SECTOR_16KB) + (1 * FLASH_SECTOR_64KB) + (5 * FLASH_SECTOR_128KB),
510  .size = (10 - 10 + 1) * FLASH_SECTOR_128KB,
511  },
512 
513  /* NOTE: sectors 8-9, 11 of the internal flash are currently unallocated */
514 
515 #endif /* PIOS_INCLUDE_FLASH_INTERNAL */
516 };
517 
519 const struct pios_flash_partition * PIOS_BOARD_HW_DEFS_GetPartitionTable (uint32_t board_revision, uint32_t * num_partitions)
520 {
521  PIOS_Assert(num_partitions);
522 
523  switch(board_revision) {
524  case SPARKY2_V2_0:
525  *num_partitions = NELEMENTS(pios_flash_partition_table_external);
526  return pios_flash_partition_table_external;
527  case BRUSHEDSPARKY_V0_1:
528  *num_partitions = NELEMENTS(pios_flash_partition_table_internal);
529  return pios_flash_partition_table_internal;
530  case BRUSHEDSPARKY_V0_2:
531  *num_partitions = NELEMENTS(pios_flash_partition_table_internal);
532  return pios_flash_partition_table_internal;
533  }
534 
535  PIOS_Assert(0);
536 }
537 
539 const struct flashfs_logfs_cfg * get_flashfs_settings_cfg(uint32_t board_revision)
540 {
541  switch(board_revision) {
542  case SPARKY2_V2_0:
543  return &flashfs_settings_external_cfg;
544  case BRUSHEDSPARKY_V0_1:
545  return &flashfs_settings_internal_cfg;
546  case BRUSHEDSPARKY_V0_2:
547  return &flashfs_settings_internal_cfg;
548  }
549 
550  PIOS_Assert(0);
551 }
552 
554 bool get_external_flash(uint32_t board_revision)
555 {
556  switch(board_revision) {
557  case SPARKY2_V2_0:
558  return true;
559  case BRUSHEDSPARKY_V0_1:
560  return false;
561  case BRUSHEDSPARKY_V0_2:
562  return false;
563  }
564 
565  PIOS_Assert(0);
566 }
567 
568 #endif /* PIOS_INCLUDE_FLASH */
569 
570 #include <pios_usart_priv.h>
571 
572 /*
573  * MAIN USART
574  */
575 static const struct pios_usart_cfg pios_usart_main_cfg = {
576  .regs = USART1,
577  .remap = GPIO_AF_USART1,
578  .irq = {
579  .init = {
580  .NVIC_IRQChannel = USART1_IRQn,
581  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
582  .NVIC_IRQChannelSubPriority = 0,
583  .NVIC_IRQChannelCmd = ENABLE,
584  },
585  },
586  .rx = {
587  .gpio = GPIOA,
588  .init = {
589  .GPIO_Pin = GPIO_Pin_10,
590  .GPIO_Speed = GPIO_Speed_2MHz,
591  .GPIO_Mode = GPIO_Mode_AF,
592  .GPIO_OType = GPIO_OType_PP,
593  .GPIO_PuPd = GPIO_PuPd_UP
594  },
595  },
596  .tx = {
597  .gpio = GPIOA,
598  .init = {
599  .GPIO_Pin = GPIO_Pin_9,
600  .GPIO_Speed = GPIO_Speed_2MHz,
601  .GPIO_Mode = GPIO_Mode_AF,
602  .GPIO_OType = GPIO_OType_PP,
603  .GPIO_PuPd = GPIO_PuPd_UP
604  },
605  },
606 };
607 
609  .regs = USART6,
610  .remap = GPIO_AF_USART6,
611  .irq = {
612  .init = {
613  .NVIC_IRQChannel = USART6_IRQn,
614  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
615  .NVIC_IRQChannelSubPriority = 0,
616  .NVIC_IRQChannelCmd = ENABLE,
617  },
618  },
619  .rx = {
620  .gpio = GPIOC,
621  .init = {
622  .GPIO_Pin = GPIO_Pin_7,
623  .GPIO_Speed = GPIO_Speed_2MHz,
624  .GPIO_Mode = GPIO_Mode_AF,
625  .GPIO_OType = GPIO_OType_PP,
626  .GPIO_PuPd = GPIO_PuPd_UP
627  },
628  },
629 };
630 
632  .regs = UART5,
633  .remap = GPIO_AF_UART5,
634  .irq = {
635  .init = {
636  .NVIC_IRQChannel = UART5_IRQn,
637  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
638  .NVIC_IRQChannelSubPriority = 0,
639  .NVIC_IRQChannelCmd = ENABLE,
640  },
641  },
642  .rx = {
643  .gpio = GPIOD,
644  .init = {
645  .GPIO_Pin = GPIO_Pin_2,
646  .GPIO_Speed = GPIO_Speed_2MHz,
647  .GPIO_Mode = GPIO_Mode_AF,
648  .GPIO_OType = GPIO_OType_PP,
649  .GPIO_PuPd = GPIO_PuPd_UP
650  },
651  },
652 };
653 
655 const struct pios_usart_cfg * get_usart_rcvr_cfg(uint32_t board_revision)
656 {
657  switch(board_revision) {
658  case SPARKY2_V2_0:
659  return &pios_usart_rcvr_pc7_cfg;
660  case BRUSHEDSPARKY_V0_1:
661  return &pios_usart_rcvr_pc7_cfg;
662  case BRUSHEDSPARKY_V0_2:
663  return &pios_usart_rcvr_pd2_cfg;
664  }
665 
666  PIOS_Assert(0);
667 }
668 
669 
670 #if defined(PIOS_INCLUDE_SBUS)
671 
672 #include <pios_sbus_priv.h>
673 
674 static const struct pios_sbus_cfg pios_sbus_cfg = {
675  /* Inverter configuration */
676  .inv = {
677  .gpio = GPIOC,
678  .init = {
679  .GPIO_Pin = GPIO_Pin_6,
680  .GPIO_Speed = GPIO_Speed_2MHz,
681  .GPIO_Mode = GPIO_Mode_OUT,
682  .GPIO_OType = GPIO_OType_PP,
683  .GPIO_PuPd = GPIO_PuPd_UP
684  },
685  },
686  .gpio_inv_enable = Bit_SET,
687  .gpio_inv_disable = Bit_RESET,
688 };
689 
690 const struct pios_sbus_cfg * get_sbus_cfg(uint32_t board_revision)
691 {
692  switch(board_revision) {
693  case SPARKY2_V2_0:
694  return &pios_sbus_cfg;
695  case BRUSHEDSPARKY_V0_1:
696  return &pios_sbus_cfg;
697  case BRUSHEDSPARKY_V0_2:
698  return NULL;
699  }
700 
701  PIOS_Assert(0);
702 }
703 
704 #endif /* PIOS_INCLUDE_SBUS */
705 
706 /*
707  * FLEXI PORT
708  */
709 static const struct pios_usart_cfg pios_usart_flexi_cfg = {
710  .regs = USART3,
711  .remap = GPIO_AF_USART3,
712  .irq = {
713  .init = {
714  .NVIC_IRQChannel = USART3_IRQn,
715  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
716  .NVIC_IRQChannelSubPriority = 0,
717  .NVIC_IRQChannelCmd = ENABLE,
718  },
719  },
720  .rx = {
721  .gpio = GPIOB,
722  .init = {
723  .GPIO_Pin = GPIO_Pin_11,
724  .GPIO_Speed = GPIO_Speed_2MHz,
725  .GPIO_Mode = GPIO_Mode_AF,
726  .GPIO_OType = GPIO_OType_PP,
727  .GPIO_PuPd = GPIO_PuPd_UP
728  },
729  },
730  .tx = {
731  .gpio = GPIOB,
732  .init = {
733  .GPIO_Pin = GPIO_Pin_10,
734  .GPIO_Speed = GPIO_Speed_2MHz,
735  .GPIO_Mode = GPIO_Mode_AF,
736  .GPIO_OType = GPIO_OType_PP,
737  .GPIO_PuPd = GPIO_PuPd_UP
738  },
739  },
740 };
741 
742 #if defined(PIOS_INCLUDE_DSM)
743 /*
744  * Spektrum/JR DSM USART
745  */
746 #include <pios_dsm_priv.h>
747 
748 static const struct pios_dsm_cfg pios_dsm_main_cfg = {
749  .bind = {
750  .gpio = GPIOA,
751  .init = {
752  .GPIO_Pin = GPIO_Pin_10,
753  .GPIO_Speed = GPIO_Speed_2MHz,
754  .GPIO_Mode = GPIO_Mode_OUT,
755  .GPIO_OType = GPIO_OType_PP,
756  .GPIO_PuPd = GPIO_PuPd_NOPULL
757  },
758  },
759 };
760 
761 static const struct pios_dsm_cfg pios_dsm_flexi_cfg = {
762  .bind = {
763  .gpio = GPIOB,
764  .init = {
765  .GPIO_Pin = GPIO_Pin_11,
766  .GPIO_Speed = GPIO_Speed_2MHz,
767  .GPIO_Mode = GPIO_Mode_OUT,
768  .GPIO_OType = GPIO_OType_PP,
769  .GPIO_PuPd = GPIO_PuPd_NOPULL
770  },
771  },
772 };
773 
774 // Because of the inverter on the main port this will not
775 // work. Notice the mode is set to IN to maintain API
776 // compatibility but protect the pins
777 static const struct pios_dsm_cfg pios_dsm_rcvr_cfg = {
778  .bind = {
779  .gpio = GPIOC,
780  .init = {
781  .GPIO_Pin = GPIO_Pin_7,
782  .GPIO_Speed = GPIO_Speed_2MHz,
783  .GPIO_Mode = GPIO_Mode_IN,
784  .GPIO_OType = GPIO_OType_PP,
785  .GPIO_PuPd = GPIO_PuPd_NOPULL
786  },
787  },
788 };
789 #endif /* PIOS_INCLUDE_DSM */
790 
791 #if defined(PIOS_INCLUDE_COM)
792 
793 #include <pios_com_priv.h>
794 
795 #endif /* PIOS_INCLUDE_COM */
796 
797 #if defined(PIOS_INCLUDE_I2C)
798 
799 #include <pios_i2c_priv.h>
800 
801 /*
802  * I2C Adapters
803  */
804 void PIOS_I2C_mag_pressure_adapter_ev_irq_handler(void);
805 void PIOS_I2C_mag_pressureadapter_er_irq_handler(void);
806 void I2C1_EV_IRQHandler()
807  __attribute__ ((alias("PIOS_I2C_mag_pressure_adapter_ev_irq_handler")));
808 void I2C1_ER_IRQHandler()
809  __attribute__ ((alias("PIOS_I2C_mag_pressure_adapter_er_irq_handler")));
810 
811 static const struct pios_i2c_adapter_cfg pios_i2c_mag_pressure_adapter_cfg = {
812  .regs = I2C1,
813  .remap = GPIO_AF_I2C1,
814  .init = {
815  .I2C_Mode = I2C_Mode_I2C,
816  .I2C_OwnAddress1 = 0,
817  .I2C_Ack = I2C_Ack_Enable,
818  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
819  .I2C_DutyCycle = I2C_DutyCycle_2,
820  .I2C_ClockSpeed = 400000, /* bits/s */
821  },
822  .transfer_timeout_ms = 50,
823  .scl = {
824  .gpio = GPIOB,
825  .init = {
826  .GPIO_Pin = GPIO_Pin_8,
827  .GPIO_Mode = GPIO_Mode_AF,
828  .GPIO_Speed = GPIO_Speed_50MHz,
829  .GPIO_OType = GPIO_OType_OD,
830  .GPIO_PuPd = GPIO_PuPd_NOPULL,
831  },
832  },
833  .sda = {
834  .gpio = GPIOB,
835  .init = {
836  .GPIO_Pin = GPIO_Pin_9,
837  .GPIO_Mode = GPIO_Mode_AF,
838  .GPIO_Speed = GPIO_Speed_50MHz,
839  .GPIO_OType = GPIO_OType_OD,
840  .GPIO_PuPd = GPIO_PuPd_NOPULL,
841  },
842  },
843  .event = {
844  .flags = 0, /* FIXME: check this */
845  .init = {
846  .NVIC_IRQChannel = I2C1_EV_IRQn,
847  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
848  .NVIC_IRQChannelSubPriority = 0,
849  .NVIC_IRQChannelCmd = ENABLE,
850  },
851  },
852  .error = {
853  .flags = 0, /* FIXME: check this */
854  .init = {
855  .NVIC_IRQChannel = I2C1_ER_IRQn,
856  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
857  .NVIC_IRQChannelSubPriority = 0,
858  .NVIC_IRQChannelCmd = ENABLE,
859  },
860  },
861 };
862 
863 pios_i2c_t pios_i2c_mag_pressure_adapter_id;
864 void PIOS_I2C_mag_pressure_adapter_ev_irq_handler(void)
865 {
866  /* Call into the generic code to handle the IRQ for this specific device */
867  PIOS_I2C_EV_IRQ_Handler(pios_i2c_mag_pressure_adapter_id);
868 }
869 
870 void PIOS_I2C_mag_pressure_adapter_er_irq_handler(void)
871 {
872  /* Call into the generic code to handle the IRQ for this specific device */
873  PIOS_I2C_ER_IRQ_Handler(pios_i2c_mag_pressure_adapter_id);
874 }
875 
876 
877 void PIOS_I2C_flexiport_adapter_ev_irq_handler(void);
878 void PIOS_I2C_flexiport_adapter_er_irq_handler(void);
879 void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_flexiport_adapter_ev_irq_handler")));
880 void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_flexiport_adapter_er_irq_handler")));
881 
882 static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = {
883  .regs = I2C2,
884  .remap = GPIO_AF_I2C2,
885  .init = {
886  .I2C_Mode = I2C_Mode_I2C,
887  .I2C_OwnAddress1 = 0,
888  .I2C_Ack = I2C_Ack_Enable,
889  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
890  .I2C_DutyCycle = I2C_DutyCycle_2,
891  .I2C_ClockSpeed = 400000, /* bits/s */
892  },
893  .transfer_timeout_ms = 50,
894  .scl = {
895  .gpio = GPIOB,
896  .init = {
897  .GPIO_Pin = GPIO_Pin_10,
898  .GPIO_Mode = GPIO_Mode_AF,
899  .GPIO_Speed = GPIO_Speed_50MHz,
900  .GPIO_OType = GPIO_OType_OD,
901  .GPIO_PuPd = GPIO_PuPd_NOPULL,
902  },
903  },
904  .sda = {
905  .gpio = GPIOB,
906  .init = {
907  .GPIO_Pin = GPIO_Pin_11,
908  .GPIO_Mode = GPIO_Mode_AF,
909  .GPIO_Speed = GPIO_Speed_50MHz,
910  .GPIO_OType = GPIO_OType_OD,
911  .GPIO_PuPd = GPIO_PuPd_NOPULL,
912  },
913  },
914  .event = {
915  .flags = 0, /* FIXME: check this */
916  .init = {
917  .NVIC_IRQChannel = I2C2_EV_IRQn,
918  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
919  .NVIC_IRQChannelSubPriority = 0,
920  .NVIC_IRQChannelCmd = ENABLE,
921  },
922  },
923  .error = {
924  .flags = 0, /* FIXME: check this */
925  .init = {
926  .NVIC_IRQChannel = I2C2_ER_IRQn,
927  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
928  .NVIC_IRQChannelSubPriority = 0,
929  .NVIC_IRQChannelCmd = ENABLE,
930  },
931  },
932 };
933 
934 pios_i2c_t pios_i2c_flexiport_adapter_id;
935 void PIOS_I2C_flexiport_adapter_ev_irq_handler(void)
936 {
937  /* Call into the generic code to handle the IRQ for this specific device */
938  PIOS_I2C_EV_IRQ_Handler(pios_i2c_flexiport_adapter_id);
939 }
940 
941 void PIOS_I2C_flexiport_adapter_er_irq_handler(void)
942 {
943  /* Call into the generic code to handle the IRQ for this specific device */
944  PIOS_I2C_ER_IRQ_Handler(pios_i2c_flexiport_adapter_id);
945 }
946 
947 
948 void PIOS_I2C_pressure_adapter_ev_irq_handler(void);
949 void PIOS_I2C_pressure_adapter_er_irq_handler(void);
950 
951 #endif /* PIOS_INCLUDE_I2C */
952 
953 #if defined(PIOS_INCLUDE_RTC)
954 /*
955  * Realtime Clock (RTC)
956  */
957 #include <pios_rtc_priv.h>
958 
959 void PIOS_RTC_IRQ_Handler (void);
960 void RTC_WKUP_IRQHandler() __attribute__ ((alias ("PIOS_RTC_IRQ_Handler")));
961 static const struct pios_rtc_cfg pios_rtc_main_cfg = {
962  .clksrc = RCC_RTCCLKSource_HSE_Div8, // Divide 8 Mhz crystal down to 1
963  // This clock is then divided by another 16 to give a nominal 62.5 khz clock
964  .prescaler = 100, // Every 100 cycles gives 625 Hz
965  .irq = {
966  .init = {
967  .NVIC_IRQChannel = RTC_WKUP_IRQn,
968  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
969  .NVIC_IRQChannelSubPriority = 0,
970  .NVIC_IRQChannelCmd = ENABLE,
971  },
972  },
973 };
974 
975 void PIOS_RTC_IRQ_Handler (void)
976 {
978 }
979 
980 #endif
981 
982 #include "pios_tim_priv.h"
983 
984 // Set up timers on APB1
985 // TIM2,3,4,5,6,7,12,13,14
986 static const TIM_TimeBaseInitTypeDef tim_apb1_time_base = {
987  .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_COUNTER_CLOCK / 1000000) - 1,
988  .TIM_ClockDivision = TIM_CKD_DIV1,
989  .TIM_CounterMode = TIM_CounterMode_Up,
990  .TIM_Period = 0xFFFF,
991  .TIM_RepetitionCounter = 0x0000,
992 };
993 
994 
995 // Set up timers on APB2
996 // TIM1,8,9,10,11
997 static const TIM_TimeBaseInitTypeDef tim_apb2_time_base = {
998  .TIM_Prescaler = (PIOS_PERIPHERAL_APB2_COUNTER_CLOCK / 1000000) - 1,
999  .TIM_ClockDivision = TIM_CKD_DIV1,
1000  .TIM_CounterMode = TIM_CounterMode_Up,
1001  .TIM_Period = 0xFFFF,
1002  .TIM_RepetitionCounter = 0x0000,
1003 };
1004 
1005 
1006 static const struct pios_tim_clock_cfg tim_3_cfg = {
1007  .timer = TIM3,
1008  .time_base_init = &tim_apb1_time_base,
1009  .irq = {
1010  .init = {
1011  .NVIC_IRQChannel = TIM3_IRQn,
1012  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1013  .NVIC_IRQChannelSubPriority = 0,
1014  .NVIC_IRQChannelCmd = ENABLE,
1015  },
1016  },
1017 };
1018 
1019 static const struct pios_tim_clock_cfg tim_5_cfg = {
1020  .timer = TIM5,
1021  .time_base_init = &tim_apb1_time_base,
1022  .irq = {
1023  .init = {
1024  .NVIC_IRQChannel = TIM5_IRQn,
1025  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1026  .NVIC_IRQChannelSubPriority = 0,
1027  .NVIC_IRQChannelCmd = ENABLE,
1028  },
1029  },
1030 };
1031 
1032 static const struct pios_tim_clock_cfg tim_8_cfg = {
1033  .timer = TIM8,
1034  .time_base_init = &tim_apb2_time_base,
1035  .irq = {
1036  .init = {
1037  .NVIC_IRQChannel = TIM8_CC_IRQn,
1038  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1039  .NVIC_IRQChannelSubPriority = 0,
1040  .NVIC_IRQChannelCmd = ENABLE,
1041  },
1042  },
1043 };
1044 
1045 static const struct pios_tim_clock_cfg tim_9_cfg = {
1046  .timer = TIM9,
1047  .time_base_init = &tim_apb2_time_base,
1048  .irq = {
1049  .init = {
1050  .NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn,
1051  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1052  .NVIC_IRQChannelSubPriority = 0,
1053  .NVIC_IRQChannelCmd = ENABLE,
1054  },
1055  },
1056 };
1057 
1058 static const struct pios_tim_clock_cfg tim_12_cfg = {
1059  .timer = TIM12,
1060  .time_base_init = &tim_apb1_time_base,
1061  .irq = {
1062  .init = {
1063  .NVIC_IRQChannel = TIM8_BRK_TIM12_IRQn,
1064  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1065  .NVIC_IRQChannelSubPriority = 0,
1066  .NVIC_IRQChannelCmd = ENABLE,
1067  },
1068  },
1069 };
1070 
1071 
1076 #include <pios_servo_priv.h>
1078  {
1079  .timer = TIM3,
1080  .timer_chan = TIM_Channel_3,
1081  .pin = {
1082  .gpio = GPIOB,
1083  .init = {
1084  .GPIO_Pin = GPIO_Pin_0,
1085  .GPIO_Speed = GPIO_Speed_2MHz,
1086  .GPIO_Mode = GPIO_Mode_AF,
1087  .GPIO_OType = GPIO_OType_PP,
1088  .GPIO_PuPd = GPIO_PuPd_DOWN
1089  },
1090  .pin_source = GPIO_PinSource0,
1091  },
1092  .remap = GPIO_AF_TIM3,
1093  },
1094  {
1095  .timer = TIM3,
1096  .timer_chan = TIM_Channel_4,
1097  .pin = {
1098  .gpio = GPIOB,
1099  .init = {
1100  .GPIO_Pin = GPIO_Pin_1,
1101  .GPIO_Speed = GPIO_Speed_2MHz,
1102  .GPIO_Mode = GPIO_Mode_AF,
1103  .GPIO_OType = GPIO_OType_PP,
1104  .GPIO_PuPd = GPIO_PuPd_DOWN
1105  },
1106  .pin_source = GPIO_PinSource1,
1107  },
1108  .remap = GPIO_AF_TIM3,
1109  },
1110  {
1111  .timer = TIM9,
1112  .timer_chan = TIM_Channel_2,
1113  .pin = {
1114  .gpio = GPIOA,
1115  .init = {
1116  .GPIO_Pin = GPIO_Pin_3,
1117  .GPIO_Speed = GPIO_Speed_2MHz,
1118  .GPIO_Mode = GPIO_Mode_AF,
1119  .GPIO_OType = GPIO_OType_PP,
1120  .GPIO_PuPd = GPIO_PuPd_DOWN
1121  },
1122  .pin_source = GPIO_PinSource3,
1123  },
1124  .remap = GPIO_AF_TIM9,
1125  },
1126  {
1127  .timer = TIM9,
1128  .timer_chan = TIM_Channel_1,
1129  .pin = {
1130  .gpio = GPIOA,
1131  .init = {
1132  .GPIO_Pin = GPIO_Pin_2,
1133  .GPIO_Speed = GPIO_Speed_2MHz,
1134  .GPIO_Mode = GPIO_Mode_AF,
1135  .GPIO_OType = GPIO_OType_PP,
1136  .GPIO_PuPd = GPIO_PuPd_DOWN
1137  },
1138  .pin_source = GPIO_PinSource2,
1139  },
1140  .remap = GPIO_AF_TIM9,
1141  },
1142  {
1143  .timer = TIM5,
1144  .timer_chan = TIM_Channel_2,
1145  .pin = {
1146  .gpio = GPIOA,
1147  .init = {
1148  .GPIO_Pin = GPIO_Pin_1,
1149  .GPIO_Speed = GPIO_Speed_2MHz,
1150  .GPIO_Mode = GPIO_Mode_AF,
1151  .GPIO_OType = GPIO_OType_PP,
1152  .GPIO_PuPd = GPIO_PuPd_DOWN
1153  },
1154  .pin_source = GPIO_PinSource1,
1155  },
1156  .remap = GPIO_AF_TIM5,
1157  },
1158  {
1159  .timer = TIM5,
1160  .timer_chan = TIM_Channel_1,
1161  .pin = {
1162  .gpio = GPIOA,
1163  .init = {
1164  .GPIO_Pin = GPIO_Pin_0,
1165  .GPIO_Speed = GPIO_Speed_2MHz,
1166  .GPIO_Mode = GPIO_Mode_AF,
1167  .GPIO_OType = GPIO_OType_PP,
1168  .GPIO_PuPd = GPIO_PuPd_DOWN
1169  },
1170  .pin_source = GPIO_PinSource0,
1171  },
1172  .remap = GPIO_AF_TIM5,
1173  },
1174 
1175  // Outputs below are buffered via output transmitter. This will make them inverterd.
1176  {
1177  .timer = TIM8,
1178  .timer_chan = TIM_Channel_4,
1179  .pin = {
1180  .gpio = GPIOC,
1181  .init = {
1182  .GPIO_Pin = GPIO_Pin_9,
1183  .GPIO_Speed = GPIO_Speed_2MHz,
1184  .GPIO_Mode = GPIO_Mode_AF,
1185  .GPIO_OType = GPIO_OType_PP,
1186  .GPIO_PuPd = GPIO_PuPd_DOWN
1187  },
1188  .pin_source = GPIO_PinSource9,
1189  },
1190  .remap = GPIO_AF_TIM8,
1191  },
1192  {
1193  .timer = TIM8,
1194  .timer_chan = TIM_Channel_3,
1195  .pin = {
1196  .gpio = GPIOC,
1197  .init = {
1198  .GPIO_Pin = GPIO_Pin_8,
1199  .GPIO_Speed = GPIO_Speed_2MHz,
1200  .GPIO_Mode = GPIO_Mode_AF,
1201  .GPIO_OType = GPIO_OType_PP,
1202  .GPIO_PuPd = GPIO_PuPd_DOWN
1203  },
1204  .pin_source = GPIO_PinSource8,
1205  },
1206  .remap = GPIO_AF_TIM8,
1207  },
1208  {
1209  .timer = TIM12,
1210  .timer_chan = TIM_Channel_2,
1211  .pin = {
1212  .gpio = GPIOB,
1213  .init = {
1214  .GPIO_Pin = GPIO_Pin_15,
1215  .GPIO_Speed = GPIO_Speed_2MHz,
1216  .GPIO_Mode = GPIO_Mode_AF,
1217  .GPIO_OType = GPIO_OType_PP,
1218  .GPIO_PuPd = GPIO_PuPd_DOWN
1219  },
1220  .pin_source = GPIO_PinSource15,
1221  },
1222  .remap = GPIO_AF_TIM12,
1223  },
1224  {
1225  .timer = TIM12,
1226  .timer_chan = TIM_Channel_1,
1227  .pin = {
1228  .gpio = GPIOB,
1229  .init = {
1230  .GPIO_Pin = GPIO_Pin_14,
1231  .GPIO_Speed = GPIO_Speed_2MHz,
1232  .GPIO_Mode = GPIO_Mode_AF,
1233  .GPIO_OType = GPIO_OType_PP,
1234  .GPIO_PuPd = GPIO_PuPd_DOWN
1235  },
1236  .pin_source = GPIO_PinSource14,
1237  },
1238  .remap = GPIO_AF_TIM12,
1239  },
1240 
1241 };
1242 
1245  .tim_oc_init = {
1246  .TIM_OCMode = TIM_OCMode_PWM1,
1247  .TIM_OutputState = TIM_OutputState_Enable,
1248  .TIM_OutputNState = TIM_OutputNState_Disable,
1249  .TIM_Pulse = PIOS_SERVOS_INITIAL_POSITION,
1250  .TIM_OCPolarity = TIM_OCPolarity_High,
1251  .TIM_OCNPolarity = TIM_OCPolarity_High,
1252  .TIM_OCIdleState = TIM_OCIdleState_Reset,
1253  .TIM_OCNIdleState = TIM_OCNIdleState_Reset,
1254  },
1255  .channels = pios_tim_servoport_all_pins,
1256  .num_channels = NELEMENTS(pios_tim_servoport_all_pins),
1257 };
1258 
1260 const struct pios_servo_cfg pios_servo_8_cfg = {
1261  .tim_oc_init = {
1262  .TIM_OCMode = TIM_OCMode_PWM1,
1263  .TIM_OutputState = TIM_OutputState_Enable,
1264  .TIM_OutputNState = TIM_OutputNState_Disable,
1265  .TIM_Pulse = PIOS_SERVOS_INITIAL_POSITION,
1266  .TIM_OCPolarity = TIM_OCPolarity_High,
1267  .TIM_OCNPolarity = TIM_OCPolarity_High,
1268  .TIM_OCIdleState = TIM_OCIdleState_Reset,
1269  .TIM_OCNIdleState = TIM_OCNIdleState_Reset,
1270  },
1271  .channels = pios_tim_servoport_all_pins,
1272  .num_channels = NELEMENTS(pios_tim_servoport_all_pins)-2,
1273 };
1275 const struct pios_servo_cfg * get_servo_cfg(uint32_t board_revision)
1276 {
1277  switch(board_revision) {
1278  case SPARKY2_V2_0:
1279  return &pios_servo_cfg;
1280  case BRUSHEDSPARKY_V0_1:
1281  return &pios_servo_8_cfg;
1282  case BRUSHEDSPARKY_V0_2:
1283  return &pios_servo_8_cfg;
1284  }
1285 
1286  PIOS_Assert(0);
1287 }
1288 
1289 #if defined(PIOS_INCLUDE_PPM)
1290 /*
1291  * PPM Inputs
1292  * TIM8
1293  */
1294 static const struct pios_tim_channel pios_tim_rcvrport = {
1295  .timer = TIM8,
1296  .timer_chan = TIM_Channel_2,
1297  .pin = {
1298  .gpio = GPIOC,
1299  .init = {
1300  .GPIO_Pin = GPIO_Pin_7,
1301  .GPIO_Speed = GPIO_Speed_2MHz,
1302  .GPIO_Mode = GPIO_Mode_AF,
1303  .GPIO_OType = GPIO_OType_PP,
1304  .GPIO_PuPd = GPIO_PuPd_UP
1305  },
1306  .pin_source = GPIO_PinSource7,
1307  },
1308  .remap = GPIO_AF_TIM8,
1309 };
1310 
1311 #include <pios_ppm_priv.h>
1312 static const struct pios_ppm_cfg pios_ppm_cfg = {
1313  .tim_ic_init = {
1314  .TIM_ICPolarity = TIM_ICPolarity_Rising,
1315  .TIM_ICSelection = TIM_ICSelection_DirectTI,
1316  .TIM_ICPrescaler = TIM_ICPSC_DIV1,
1317  .TIM_ICFilter = 0x0,
1318  .TIM_Channel = TIM_Channel_2,
1319  },
1320  /* Use only the first channel for ppm */
1321  .channels = &pios_tim_rcvrport,
1322  .num_channels = 1,
1323 };
1324 
1325 #endif /* PIOS_INCLUDE_PPM */
1326 
1327 #if defined(PIOS_INCLUDE_RCVR)
1328 #include "pios_rcvr_priv.h"
1329 #endif /* PIOS_INCLUDE_RCVR */
1330 
1331 #if defined(PIOS_INCLUDE_USB)
1332 #include "pios_usb_priv.h"
1333 
1334 static const struct pios_usb_cfg pios_usb_main_cfg = {
1335  .irq = {
1336  .init = {
1337  .NVIC_IRQChannel = OTG_FS_IRQn,
1338  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
1339  .NVIC_IRQChannelSubPriority = 3,
1340  .NVIC_IRQChannelCmd = ENABLE,
1341  },
1342  },
1343  .vsense = {
1344  .gpio = GPIOA,
1345  .init = {
1346  .GPIO_Pin = GPIO_Pin_8,
1347  .GPIO_Speed = GPIO_Speed_25MHz,
1348  .GPIO_Mode = GPIO_Mode_IN,
1349  .GPIO_OType = GPIO_OType_OD,
1350  },
1351  }
1352 };
1353 
1354 const struct pios_usb_cfg * PIOS_BOARD_HW_DEFS_GetUsbCfg (uint32_t board_revision)
1355 {
1356  return &pios_usb_main_cfg;
1357 }
1358 
1359 #include "pios_usb_board_data_priv.h"
1362 #include "pios_usbhook.h"
1363 
1364 #endif /* PIOS_INCLUDE_USB */
1365 
1366 #if defined(PIOS_INCLUDE_COM_MSG)
1367 
1368 #include <pios_com_msg_priv.h>
1369 
1370 #endif /* PIOS_INCLUDE_COM_MSG */
1371 
1372 #if defined(PIOS_INCLUDE_USB_HID) && !defined(PIOS_INCLUDE_USB_CDC)
1373 #include <pios_usb_hid_priv.h>
1374 
1375 const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
1376  .data_if = 0,
1377  .data_rx_ep = 1,
1378  .data_tx_ep = 1,
1379 };
1380 #endif /* PIOS_INCLUDE_USB_HID && !PIOS_INCLUDE_USB_CDC */
1381 
1382 #if defined(PIOS_INCLUDE_USB_HID) && defined(PIOS_INCLUDE_USB_CDC)
1383 #include <pios_usb_cdc_priv.h>
1384 
1385 const struct pios_usb_cdc_cfg pios_usb_cdc_cfg = {
1386  .ctrl_if = 0,
1387  .ctrl_tx_ep = 2,
1388 
1389  .data_if = 1,
1390  .data_rx_ep = 3,
1391  .data_tx_ep = 3,
1392 };
1393 
1394 #include <pios_usb_hid_priv.h>
1395 
1396 const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
1397  .data_if = 2,
1398  .data_rx_ep = 1,
1399  .data_tx_ep = 1,
1400 };
1401 #endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_USB_CDC */
1402 
1403 #if defined(PIOS_INCLUDE_ADC)
1404 #include "pios_adc_priv.h"
1405 #include "pios_internal_adc_priv.h"
1406 
1407 static void PIOS_ADC_DMA_irq_handler(void);
1408 void DMA2_Stream4_IRQHandler(void) __attribute__((alias("PIOS_ADC_DMA_irq_handler")));
1409 struct pios_internal_adc_cfg pios_adc_cfg = {
1410  .adc_dev_master = ADC1,
1411  .dma = {
1412  .irq = {
1413  .flags = (DMA_FLAG_TCIF4 | DMA_FLAG_TEIF4 | DMA_FLAG_HTIF4),
1414  .init = {
1415  .NVIC_IRQChannel = DMA2_Stream4_IRQn,
1416  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
1417  .NVIC_IRQChannelSubPriority = 0,
1418  .NVIC_IRQChannelCmd = ENABLE,
1419  },
1420  },
1421  .rx = {
1422  .channel = DMA2_Stream4,
1423  .init = {
1424  .DMA_Channel = DMA_Channel_0,
1425  .DMA_PeripheralBaseAddr = (uint32_t) & ADC1->DR
1426  },
1427  }
1428  },
1429  .half_flag = DMA_IT_HTIF4,
1430  .full_flag = DMA_IT_TCIF4,
1431  .adc_pins = { \
1432  {GPIOC, GPIO_Pin_2, ADC_Channel_12}, /* Current sensor */ \
1433  {GPIOC, GPIO_Pin_3, ADC_Channel_13}, /* Voltage sensor */ \
1434  {GPIOA, GPIO_Pin_4, ADC_Channel_4}, /* DAC pin */ \
1435  {NULL, 0, ADC_Channel_Vrefint}, /* Voltage reference */ \
1436  {NULL, 0, ADC_Channel_TempSensor} /* Temperature sensor */ \
1437  },
1438  .adc_pin_count = 5
1439 };
1440 
1441 static void PIOS_ADC_DMA_irq_handler(void)
1442 {
1443  /* Call into the generic code to handle the IRQ for this specific device */
1445 }
1446 
1447 #endif /* PIOS_INCLUDE_ADC */
1448 
1449 #if defined(PIOS_INCLUDE_CAN)
1450 #include "pios_can_priv.h"
1451 struct pios_can_cfg pios_can_cfg = {
1452  .regs = CAN2,
1453  .init = {
1454  // To make it easy to use both F3 and F4 use the other APB1 bus rate
1455  // divided by 2. This matches the baud rate across devices
1456  .CAN_Prescaler = 21-1,
1458  .CAN_Mode = CAN_Mode_Normal,
1460  .CAN_SJW = CAN_SJW_1tq,
1464  .CAN_BS1 = CAN_BS1_9tq,
1467  .CAN_BS2 = CAN_BS2_8tq,
1469  .CAN_TTCM = DISABLE,
1471  .CAN_ABOM = DISABLE,
1473  .CAN_AWUM = DISABLE,
1475  .CAN_NART = ENABLE,
1477  .CAN_RFLM = DISABLE,
1479  .CAN_TXFP = DISABLE,
1481  },
1482  .remap = GPIO_AF_CAN2,
1483  .tx = {
1484  .gpio = GPIOB,
1485  .init = {
1486  .GPIO_Pin = GPIO_Pin_13,
1487  .GPIO_Speed = GPIO_Speed_50MHz,
1488  .GPIO_Mode = GPIO_Mode_AF,
1489  .GPIO_OType = GPIO_OType_PP,
1490  .GPIO_PuPd = GPIO_PuPd_UP
1491  },
1492  .pin_source = GPIO_PinSource13,
1493  },
1494  .rx = {
1495  .gpio = GPIOB,
1496  .init = {
1497  .GPIO_Pin = GPIO_Pin_12,
1498  .GPIO_Speed = GPIO_Speed_50MHz,
1499  .GPIO_Mode = GPIO_Mode_AF,
1500  .GPIO_OType = GPIO_OType_PP,
1501  .GPIO_PuPd = GPIO_PuPd_UP
1502  },
1503  .pin_source = GPIO_PinSource12,
1504  },
1505  .rx_irq = {
1506  .init = {
1507  .NVIC_IRQChannel = CAN2_RX1_IRQn,
1508  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1509  .NVIC_IRQChannelSubPriority = 0,
1510  .NVIC_IRQChannelCmd = ENABLE,
1511  },
1512  },
1513  .tx_irq = {
1514  .init = {
1515  .NVIC_IRQChannel = CAN2_TX_IRQn,
1516  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
1517  .NVIC_IRQChannelSubPriority = 0,
1518  .NVIC_IRQChannelCmd = ENABLE,
1519  },
1520  },
1521 };
1522 
1524 bool get_use_can(uint32_t board_revision)
1525 {
1526  switch(board_revision) {
1527  case SPARKY2_V2_0:
1528  return true;
1529  case BRUSHEDSPARKY_V0_1:
1530  return false;
1531  case BRUSHEDSPARKY_V0_2:
1532  return false;
1533  }
1534 
1535  PIOS_Assert(0);
1536 }
1537 #endif /* PIOS_INCLUDE_CAN */
1538 
1539 
1543 #if defined(PIOS_INCLUDE_MS5611)
1544 #include "pios_ms5611_priv.h"
1545 static const struct pios_ms5611_cfg pios_ms5611_cfg = {
1547  .temperature_interleaving = 1,
1548 };
1549 #endif /* PIOS_INCLUDE_MS5611 */
1550 
1554 #if defined(PIOS_INCLUDE_MPU)
1555 #include "pios_mpu.h"
1556 static const struct pios_exti_cfg pios_exti_mpu_cfg __exti_config = {
1558  .line = EXTI_Line5,
1559  .pin = {
1560  .gpio = GPIOC,
1561  .init = {
1562  .GPIO_Pin = GPIO_Pin_5,
1563  .GPIO_Speed = GPIO_Speed_100MHz,
1564  .GPIO_Mode = GPIO_Mode_IN,
1565  .GPIO_OType = GPIO_OType_OD,
1566  .GPIO_PuPd = GPIO_PuPd_NOPULL,
1567  },
1568  },
1569  .irq = {
1570  .init = {
1571  .NVIC_IRQChannel = EXTI9_5_IRQn,
1572  .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
1573  .NVIC_IRQChannelSubPriority = 0,
1574  .NVIC_IRQChannelCmd = ENABLE,
1575  },
1576  },
1577  .exti = {
1578  .init = {
1579  .EXTI_Line = EXTI_Line5, // matches above GPIO pin
1580  .EXTI_Mode = EXTI_Mode_Interrupt,
1581  .EXTI_Trigger = EXTI_Trigger_Rising,
1582  .EXTI_LineCmd = ENABLE,
1583  },
1584  },
1585 };
1586 
1587 static struct pios_mpu_cfg pios_mpu_cfg = {
1588  .exti_cfg = &pios_exti_mpu_cfg,
1589  .default_samplerate = 1000,
1590  .orientation = PIOS_MPU_TOP_180DEG,
1591  .use_internal_mag = true,
1592 };
1593 #endif /* PIOS_INCLUDE_MPU */
1594 
1598 #if defined(PIOS_INCLUDE_HMC5883)
1599 #include "pios_hmc5883_priv.h"
1600 static const struct pios_hmc5883_cfg pios_hmc5883_external_cfg = {
1601  .exti_cfg = NULL,
1602  .M_ODR = PIOS_HMC5883_ODR_75,
1603  .Meas_Conf = PIOS_HMC5883_MEASCONF_NORMAL,
1604  .Gain = PIOS_HMC5883_GAIN_1_9,
1605  .Mode = PIOS_HMC5883_MODE_SINGLE,
1606  .Default_Orientation = PIOS_HMC5883_TOP_0DEG,
1607 };
1608 #endif /* PIOS_INCLUDE_HMC5883 */
1609 
struct stm32_gpio pin
static const struct pios_usart_cfg pios_usart_rcvr_pd2_cfg
const struct pios_exti_cfg * exti_cfg
MS5611 functions header.
#define DMA2_Stream4_IRQHandler
#define PIOS_HMC5883_ODR_75
static const struct pios_usart_cfg pios_usart_rcvr_pc7_cfg
CAN_TypeDef * regs
Definition: pios_can_priv.h:36
const struct pios_flash_driver pios_jedec_flash_driver
SPI private definitions.
#define NELEMENTS(x)
Definition: pios.h:192
#define I2C2_EV_IRQHandler
struct stm32_gpio bind
COM private definitions.
COM MSG private definitions.
APIs for PIOS_USBHOOK layer.
GPIO_TypeDef * gpio
Definition: pios_stm32.h:60
const struct pios_servo_cfg pios_servo_8_cfg
Brushed Sparky skips last two output ports.
static const struct pios_tim_clock_cfg tim_8_cfg
static const struct pios_usart_cfg pios_usart_main_cfg
I2C_TypeDef * regs
Definition: pios_i2c_priv.h:37
static const struct pios_tim_channel pios_tim_servoport_all_pins[]
ADC private definitions.
#define PIOS_IRQ_PRIO_HIGHEST
Definition: pios_board.h:172
PiOS CAN interface header.
#define PIOS_SERVOS_INITIAL_POSITION
Definition: pios_board.h:210
#define BRUSHEDSPARKY_V0_1
Definition: pios_board.h:32
bool(* vector)(void)
Definition: pios_exti.h:38
Defines the API to set up the HID + CDC USB descriptor config.
void PIOS_INTERNAL_ADC_DMA_Handler()
#define RTC_WKUP_IRQHandler
#define SPARKY2_V2_0
Definition: pios_board.h:31
#define PIOS_LED_ALARM
Definition: pios_board.h:86
#define PIOS_IRQ_PRIO_MID
Definition: pios_board.h:170
Configuration structure for the MS5611 driver.
USART private definitions.
Spektrum/JR DSMx satellite receiver private structures.
enum pios_ms5611_osr oversampling
#define I2C2_ER_IRQHandler
#define FLASH_SECTOR_64KB
const struct pios_exti_cfg * exti_cfg
Definition: pios_mpu.h:140
Driver for talking to most JEDEC flash chips.
TIM_TypeDef * timer
Definition: pios_tim_priv.h:7
SPI_TypeDef * regs
Definition: pios_spi_priv.h:44
static const struct pios_tim_clock_cfg tim_3_cfg
static const struct pios_tim_clock_cfg tim_12_cfg
struct pios_i2c_adapter * pios_i2c_t
Definition: pios_i2c.h:48
static const struct pios_tim_clock_cfg tim_5_cfg
const struct pios_annunc * annunciators
const struct pios_usart_cfg * get_usart_rcvr_cfg(uint32_t board_revision)
Get the rcvr uart configuration.
void PIOS_I2C_EV_IRQ_Handler(pios_i2c_t i2c_id)
#define PIOS_HMC5883_GAIN_1_9
ppm private structures.
NVIC_InitTypeDef init
Definition: pios_stm32.h:36
#define I2C1_ER_IRQHandler
struct stm32_gpio inv
USART_TypeDef * regs
USB private definitions.
TIM_OCInitTypeDef tim_oc_init
USB COM HID private definitions.
#define I2C1_EV_IRQHandler
#define JEDEC_MANUFACTURER_ST
const struct pios_sbus_cfg * get_sbus_cfg(enum board_revision board_rev)
ADC private definitions.
Servo private structures.
#define FLASH_SECTOR_16KB
const struct pios_servo_cfg pios_servo_cfg
Sparky2 has all 10 outputs.
static const struct pios_usart_cfg pios_usart_flexi_cfg
#define BRUSHEDSPARKY_V0_2
Definition: pios_board.h:33
void PIOS_I2C_ER_IRQ_Handler(pios_i2c_t i2c_id)
TIM_ICInitTypeDef tim_ic_init
Definition: pios_ppm_priv.h:37
Defines the API to set up the HID-only USB descriptor config.
#define PIOS_HMC5883_MODE_SINGLE
#define PIOS_HMC5883_MEASCONF_NORMAL
void PIOS_RTC_irq_handler(void)
Futaba S.Bus Private structures.
bool PIOS_MPU_IRQHandler(void)
The IMU interrupt handler. Fetches new data from the IMU.
const struct pios_flash_driver * driver
static const struct pios_tim_clock_cfg tim_9_cfg
#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
#define PIOS_LED_LINK
Definition: pios_board.h:88
const struct pios_servo_cfg * get_servo_cfg(uint32_t board_revision)
Get the flashfs settings.
enum pios_flash_partition_labels label
board_revision
Definition: board_hw_defs.c:35
#define PIOS_IRQ_PRIO_LOW
Definition: pios_board.h:169
#define PIOS_Assert(test)
Definition: pios_debug.h:52
LED private definitions.
struct stm32_irq irq
Definition: pios_usb_priv.h:37
#define FLASH_SECTOR_128KB
static const TIM_TimeBaseInitTypeDef tim_apb1_time_base
Implements an OpenLRS driver for the RFM22B.
const struct pios_flash_driver pios_internal_flash_driver
USART private definitions.
static const TIM_TimeBaseInitTypeDef tim_apb2_time_base
#define PIOS_LED_HEARTBEAT
Definition: pios_board.h:85
#define __exti_config
Definition: pios_exti.h:48
Defines the API to the board-specific USB data setup code.