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