2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * jflyper - Refactoring, cleanup and made pin-configurable
32 #include "drivers/system.h"
33 #include "drivers/dma.h"
34 #include "drivers/io.h"
35 #include "drivers/nvic.h"
36 #include "drivers/rcc.h"
38 #include "drivers/serial.h"
39 #include "drivers/serial_uart.h"
40 #include "drivers/serial_uart_impl.h"
42 #ifndef UART1_TX_DMA_STREAM
43 #define UART1_TX_DMA_STREAM NULL
45 #ifndef UART1_RX_DMA_STREAM
46 #define UART1_RX_DMA_STREAM NULL
48 #ifndef UART2_TX_DMA_STREAM
49 #define UART2_TX_DMA_STREAM NULL
51 #ifndef UART2_RX_DMA_STREAM
52 #define UART2_RX_DMA_STREAM NULL
54 #ifndef UART3_TX_DMA_STREAM
55 #define UART3_TX_DMA_STREAM NULL
57 #ifndef UART3_RX_DMA_STREAM
58 #define UART3_RX_DMA_STREAM NULL
60 #ifndef UART4_TX_DMA_STREAM
61 #define UART4_TX_DMA_STREAM NULL
63 #ifndef UART4_RX_DMA_STREAM
64 #define UART4_RX_DMA_STREAM NULL
66 #ifndef UART5_TX_DMA_STREAM
67 #define UART5_TX_DMA_STREAM NULL
69 #ifndef UART5_RX_DMA_STREAM
70 #define UART5_RX_DMA_STREAM NULL
72 #ifndef UART6_TX_DMA_STREAM
73 #define UART6_TX_DMA_STREAM NULL
75 #ifndef UART6_RX_DMA_STREAM
76 #define UART6_RX_DMA_STREAM NULL
78 #ifndef UART7_TX_DMA_STREAM
79 #define UART7_TX_DMA_STREAM NULL
81 #ifndef UART7_RX_DMA_STREAM
82 #define UART7_RX_DMA_STREAM NULL
84 #ifndef UART8_TX_DMA_STREAM
85 #define UART8_TX_DMA_STREAM NULL
87 #ifndef UART8_RX_DMA_STREAM
88 #define UART8_RX_DMA_STREAM NULL
90 #ifndef UART9_TX_DMA_STREAM
91 #define UART9_TX_DMA_STREAM NULL
93 #ifndef UART9_RX_DMA_STREAM
94 #define UART9_RX_DMA_STREAM NULL
96 #ifndef UART10_TX_DMA_STREAM
97 #define UART10_TX_DMA_STREAM NULL
99 #ifndef UART10_RX_DMA_STREAM
100 #define UART10_RX_DMA_STREAM NULL
103 const uartHardware_t uartHardware
[UARTDEV_COUNT
] = {
109 .rxDMAChannel
= DMA_REQUEST_USART1_RX
,
110 .rxDMAResource
= (dmaResource_t
*)UART1_RX_DMA_STREAM
,
111 .txDMAChannel
= DMA_REQUEST_USART1_TX
,
112 .txDMAResource
= (dmaResource_t
*)UART1_TX_DMA_STREAM
,
115 { DEFIO_TAG_E(PA10
), GPIO_AF7_USART1
},
116 { DEFIO_TAG_E(PB7
), GPIO_AF7_USART1
},
117 { DEFIO_TAG_E(PB15
), GPIO_AF4_USART1
},
120 { DEFIO_TAG_E(PA9
), GPIO_AF7_USART1
},
121 { DEFIO_TAG_E(PB6
), GPIO_AF7_USART1
},
122 { DEFIO_TAG_E(PB14
), GPIO_AF4_USART1
},
124 .rcc
= RCC_APB2(USART1
),
125 .rxIrq
= USART1_IRQn
,
126 .txPriority
= NVIC_PRIO_SERIALUART1_TXDMA
,
127 .rxPriority
= NVIC_PRIO_SERIALUART1
,
128 .txBuffer
= uart1TxBuffer
,
129 .rxBuffer
= uart1RxBuffer
,
130 .txBufferSize
= sizeof(uart1TxBuffer
),
131 .rxBufferSize
= sizeof(uart1RxBuffer
),
140 .rxDMAChannel
= DMA_REQUEST_USART2_RX
,
141 .rxDMAResource
= (dmaResource_t
*)UART2_RX_DMA_STREAM
,
142 .txDMAChannel
= DMA_REQUEST_USART2_TX
,
143 .txDMAResource
= (dmaResource_t
*)UART2_TX_DMA_STREAM
,
146 { DEFIO_TAG_E(PA3
), GPIO_AF7_USART2
},
147 { DEFIO_TAG_E(PD6
), GPIO_AF7_USART2
}
150 { DEFIO_TAG_E(PA2
), GPIO_AF7_USART2
},
151 { DEFIO_TAG_E(PD5
), GPIO_AF7_USART2
}
153 .rcc
= RCC_APB1L(USART2
),
154 .rxIrq
= USART2_IRQn
,
155 .txPriority
= NVIC_PRIO_SERIALUART2_TXDMA
,
156 .rxPriority
= NVIC_PRIO_SERIALUART2
,
157 .txBuffer
= uart2TxBuffer
,
158 .rxBuffer
= uart2RxBuffer
,
159 .txBufferSize
= sizeof(uart2TxBuffer
),
160 .rxBufferSize
= sizeof(uart2RxBuffer
),
169 .rxDMAChannel
= DMA_REQUEST_USART3_RX
,
170 .rxDMAResource
= (dmaResource_t
*)UART3_RX_DMA_STREAM
,
171 .txDMAChannel
= DMA_REQUEST_USART3_TX
,
172 .txDMAResource
= (dmaResource_t
*)UART3_TX_DMA_STREAM
,
175 { DEFIO_TAG_E(PB11
), GPIO_AF7_USART3
},
176 { DEFIO_TAG_E(PC11
), GPIO_AF7_USART3
},
177 { DEFIO_TAG_E(PD9
), GPIO_AF7_USART3
}
180 { DEFIO_TAG_E(PB10
), GPIO_AF7_USART3
},
181 { DEFIO_TAG_E(PC10
), GPIO_AF7_USART3
},
182 { DEFIO_TAG_E(PD8
), GPIO_AF7_USART3
}
184 .rcc
= RCC_APB1L(USART3
),
185 .rxIrq
= USART3_IRQn
,
186 .txPriority
= NVIC_PRIO_SERIALUART3_TXDMA
,
187 .rxPriority
= NVIC_PRIO_SERIALUART3
,
188 .txBuffer
= uart3TxBuffer
,
189 .rxBuffer
= uart3RxBuffer
,
190 .txBufferSize
= sizeof(uart3TxBuffer
),
191 .rxBufferSize
= sizeof(uart3RxBuffer
),
200 .rxDMAChannel
= DMA_REQUEST_UART4_RX
,
201 .rxDMAResource
= (dmaResource_t
*)UART4_RX_DMA_STREAM
,
202 .txDMAChannel
= DMA_REQUEST_UART4_TX
,
203 .txDMAResource
= (dmaResource_t
*)UART4_TX_DMA_STREAM
,
206 { DEFIO_TAG_E(PA1
), GPIO_AF8_UART4
},
207 { DEFIO_TAG_E(PA11
), GPIO_AF6_UART4
},
208 { DEFIO_TAG_E(PB8
), GPIO_AF8_UART4
},
209 { DEFIO_TAG_E(PC11
), GPIO_AF8_UART4
},
210 { DEFIO_TAG_E(PD0
), GPIO_AF8_UART4
}
213 { DEFIO_TAG_E(PA0
), GPIO_AF8_UART4
},
214 { DEFIO_TAG_E(PA12
), GPIO_AF6_UART4
},
215 { DEFIO_TAG_E(PB9
), GPIO_AF8_UART4
},
216 { DEFIO_TAG_E(PC10
), GPIO_AF8_UART4
},
217 { DEFIO_TAG_E(PD1
), GPIO_AF8_UART4
}
219 .rcc
= RCC_APB1L(UART4
),
221 .txPriority
= NVIC_PRIO_SERIALUART4_TXDMA
,
222 .rxPriority
= NVIC_PRIO_SERIALUART4
,
223 .txBuffer
= uart4TxBuffer
,
224 .rxBuffer
= uart4RxBuffer
,
225 .txBufferSize
= sizeof(uart4TxBuffer
),
226 .rxBufferSize
= sizeof(uart4RxBuffer
),
235 .rxDMAChannel
= DMA_REQUEST_UART5_RX
,
236 .rxDMAResource
= (dmaResource_t
*)UART5_RX_DMA_STREAM
,
237 .txDMAChannel
= DMA_REQUEST_UART5_TX
,
238 .txDMAResource
= (dmaResource_t
*)UART5_TX_DMA_STREAM
,
241 { DEFIO_TAG_E(PB5
), GPIO_AF14_UART5
},
242 { DEFIO_TAG_E(PB12
), GPIO_AF14_UART5
},
243 { DEFIO_TAG_E(PD2
), GPIO_AF8_UART5
},
246 { DEFIO_TAG_E(PB6
), GPIO_AF14_UART5
},
247 { DEFIO_TAG_E(PB13
), GPIO_AF14_UART5
},
248 { DEFIO_TAG_E(PC12
), GPIO_AF8_UART5
},
250 .rcc
= RCC_APB1L(UART5
),
252 .txPriority
= NVIC_PRIO_SERIALUART5_TXDMA
,
253 .rxPriority
= NVIC_PRIO_SERIALUART5
,
254 .txBuffer
= uart5TxBuffer
,
255 .rxBuffer
= uart5RxBuffer
,
256 .txBufferSize
= sizeof(uart5TxBuffer
),
257 .rxBufferSize
= sizeof(uart5RxBuffer
),
266 .rxDMAChannel
= DMA_REQUEST_USART6_RX
,
267 .rxDMAResource
= (dmaResource_t
*)UART6_RX_DMA_STREAM
,
268 .txDMAChannel
= DMA_REQUEST_USART6_TX
,
269 .txDMAResource
= (dmaResource_t
*)UART6_TX_DMA_STREAM
,
272 { DEFIO_TAG_E(PC7
), GPIO_AF7_USART6
},
273 { DEFIO_TAG_E(PG9
), GPIO_AF7_USART6
}
276 { DEFIO_TAG_E(PC6
), GPIO_AF7_USART6
},
277 { DEFIO_TAG_E(PG14
), GPIO_AF7_USART6
}
279 .rcc
= RCC_APB2(USART6
),
280 .rxIrq
= USART6_IRQn
,
281 .txPriority
= NVIC_PRIO_SERIALUART6_TXDMA
,
282 .rxPriority
= NVIC_PRIO_SERIALUART6
,
283 .txBuffer
= uart6TxBuffer
,
284 .rxBuffer
= uart6RxBuffer
,
285 .txBufferSize
= sizeof(uart6TxBuffer
),
286 .rxBufferSize
= sizeof(uart6RxBuffer
),
295 .rxDMAChannel
= DMA_REQUEST_UART7_RX
,
296 .rxDMAResource
= (dmaResource_t
*)UART7_RX_DMA_STREAM
,
297 .txDMAChannel
= DMA_REQUEST_UART7_TX
,
298 .txDMAResource
= (dmaResource_t
*)UART7_TX_DMA_STREAM
,
301 { DEFIO_TAG_E(PA8
), GPIO_AF11_UART7
},
302 { DEFIO_TAG_E(PB3
), GPIO_AF11_UART7
},
303 { DEFIO_TAG_E(PE7
), GPIO_AF7_UART7
},
304 { DEFIO_TAG_E(PF6
), GPIO_AF7_UART7
},
307 { DEFIO_TAG_E(PA15
), GPIO_AF11_UART7
},
308 { DEFIO_TAG_E(PB4
), GPIO_AF11_UART7
},
309 { DEFIO_TAG_E(PE8
), GPIO_AF7_UART7
},
310 { DEFIO_TAG_E(PF7
), GPIO_AF7_UART7
},
312 .rcc
= RCC_APB1L(UART7
),
314 .txPriority
= NVIC_PRIO_SERIALUART7_TXDMA
,
315 .rxPriority
= NVIC_PRIO_SERIALUART7
,
316 .txBuffer
= uart7TxBuffer
,
317 .rxBuffer
= uart7RxBuffer
,
318 .txBufferSize
= sizeof(uart7TxBuffer
),
319 .rxBufferSize
= sizeof(uart7RxBuffer
),
328 .rxDMAChannel
= DMA_REQUEST_UART8_RX
,
329 .rxDMAResource
= (dmaResource_t
*)UART8_RX_DMA_STREAM
,
330 .txDMAChannel
= DMA_REQUEST_UART8_TX
,
331 .txDMAResource
= (dmaResource_t
*)UART8_TX_DMA_STREAM
,
334 { DEFIO_TAG_E(PE0
), GPIO_AF8_UART8
}
337 { DEFIO_TAG_E(PE1
), GPIO_AF8_UART8
}
339 .rcc
= RCC_APB1L(UART8
),
341 .txPriority
= NVIC_PRIO_SERIALUART8_TXDMA
,
342 .rxPriority
= NVIC_PRIO_SERIALUART8
,
343 .txBuffer
= uart8TxBuffer
,
344 .rxBuffer
= uart8RxBuffer
,
345 .txBufferSize
= sizeof(uart8TxBuffer
),
346 .rxBufferSize
= sizeof(uart8RxBuffer
),
355 .rxDMAChannel
= DMA_REQUEST_UART9_RX
,
356 .rxDMAResource
= (dmaResource_t
*)UART9_RX_DMA_STREAM
,
357 .txDMAChannel
= DMA_REQUEST_UART9_TX
,
358 .txDMAResource
= (dmaResource_t
*)UART9_TX_DMA_STREAM
,
361 { DEFIO_TAG_E(PD14
), GPIO_AF11_UART9
}
364 { DEFIO_TAG_E(PD15
), GPIO_AF11_UART9
}
366 .rcc
= RCC_APB2(UART9
),
368 .txPriority
= NVIC_PRIO_SERIALUART9_TXDMA
,
369 .rxPriority
= NVIC_PRIO_SERIALUART9
,
370 .txBuffer
= uart9TxBuffer
,
371 .rxBuffer
= uart9RxBuffer
,
372 .txBufferSize
= sizeof(uart9TxBuffer
),
373 .rxBufferSize
= sizeof(uart9RxBuffer
),
379 .device
= UARTDEV_10
,
382 .rxDMAChannel
= DMA_REQUEST_USART10_RX
,
383 .rxDMAResource
= (dmaResource_t
*)UART10_RX_DMA_STREAM
,
384 .txDMAChannel
= DMA_REQUEST_USART10_TX
,
385 .txDMAResource
= (dmaResource_t
*)UART10_TX_DMA_STREAM
,
388 { DEFIO_TAG_E(PE2
), GPIO_AF11_USART10
}
391 { DEFIO_TAG_E(PE3
), GPIO_AF11_USART10
}
393 .rcc
= RCC_APB2(USART10
),
394 .rxIrq
= USART10_IRQn
,
395 .txPriority
= NVIC_PRIO_SERIALUART10_TXDMA
,
396 .rxPriority
= NVIC_PRIO_SERIALUART10
,
397 .txBuffer
= uart10TxBuffer
,
398 .rxBuffer
= uart10RxBuffer
,
399 .txBufferSize
= sizeof(uart10TxBuffer
),
400 .rxBufferSize
= sizeof(uart10RxBuffer
),
406 .device
= LPUARTDEV_1
,
409 .rxDMAChannel
= BDMA_REQUEST_LPUART1_RX
,
410 .rxDMAResource
= (dmaResource_t
*)NULL
, // No DMA support yet (Need BDMA support)
411 .txDMAChannel
= BDMA_REQUEST_LPUART1_TX
,
412 .txDMAResource
= (dmaResource_t
*)NULL
, // No DMA support yet (Need BDMA support)
415 { DEFIO_TAG_E(PA10
), GPIO_AF3_LPUART
},
416 { DEFIO_TAG_E(PB7
), GPIO_AF8_LPUART
}
419 { DEFIO_TAG_E(PA9
), GPIO_AF3_LPUART
},
420 { DEFIO_TAG_E(PB6
), GPIO_AF8_LPUART
}
422 .rcc
= RCC_APB4(LPUART1
),
423 .rxIrq
= LPUART1_IRQn
,
424 .txPriority
= NVIC_PRIO_SERIALLPUART1_TXDMA
, // Not used until DMA is supported
425 .rxPriority
= NVIC_PRIO_SERIALLPUART1
, // Not used until DMA is supported
426 .txBuffer
= lpuart1TxBuffer
,
427 .rxBuffer
= lpuart1RxBuffer
,
428 .txBufferSize
= sizeof(lpuart1TxBuffer
),
429 .rxBufferSize
= sizeof(lpuart1RxBuffer
),
435 // XXX Should serialUART be consolidated?
437 uartPort_t
*serialUART(UARTDevice_e device
, uint32_t baudRate
, portMode_e mode
, portOptions_e options
)
439 uartDevice_t
*uartdev
= uartDevmap
[device
];
444 uartPort_t
*s
= &(uartdev
->port
);
446 s
->port
.vTable
= uartVTable
;
448 s
->port
.baudRate
= baudRate
;
450 const uartHardware_t
*hardware
= uartdev
->hardware
;
452 s
->USARTx
= hardware
->reg
;
454 s
->port
.rxBuffer
= hardware
->rxBuffer
;
455 s
->port
.txBuffer
= hardware
->txBuffer
;
456 s
->port
.rxBufferSize
= hardware
->rxBufferSize
;
457 s
->port
.txBufferSize
= hardware
->txBufferSize
;
460 uartConfigureDma(uartdev
);
463 s
->Handle
.Instance
= hardware
->reg
;
466 RCC_ClockCmd(hardware
->rcc
, ENABLE
);
469 IO_t txIO
= IOGetByTag(uartdev
->tx
.pin
);
470 IO_t rxIO
= IOGetByTag(uartdev
->rx
.pin
);
472 if ((options
& SERIAL_BIDIR
) && txIO
) {
473 ioConfig_t ioCfg
= IO_CONFIG(
474 ((options
& SERIAL_INVERTED
) || (options
& SERIAL_BIDIR_PP
) || (options
& SERIAL_BIDIR_PP_PD
)) ? GPIO_MODE_AF_PP
: GPIO_MODE_AF_OD
,
475 GPIO_SPEED_FREQ_HIGH
,
476 ((options
& SERIAL_INVERTED
) || (options
& SERIAL_BIDIR_PP_PD
)) ? GPIO_PULLDOWN
: GPIO_PULLUP
479 IOInit(txIO
, OWNER_SERIAL_TX
, RESOURCE_INDEX(device
));
480 IOConfigGPIOAF(txIO
, ioCfg
, uartdev
->tx
.af
);
482 if ((mode
& MODE_TX
) && txIO
) {
483 IOInit(txIO
, OWNER_SERIAL_TX
, RESOURCE_INDEX(device
));
484 IOConfigGPIOAF(txIO
, IOCFG_AF_PP
, uartdev
->tx
.af
);
487 if ((mode
& MODE_RX
) && rxIO
) {
488 IOInit(rxIO
, OWNER_SERIAL_RX
, RESOURCE_INDEX(device
));
489 IOConfigGPIOAF(rxIO
, IOCFG_AF_PP
, uartdev
->rx
.af
);
494 if (!s
->rxDMAResource
)
497 HAL_NVIC_SetPriority(hardware
->rxIrq
, NVIC_PRIORITY_BASE(hardware
->rxPriority
), NVIC_PRIORITY_SUB(hardware
->rxPriority
));
498 HAL_NVIC_EnableIRQ(hardware
->rxIrq
);