Merge pull request #11939 from blckmn/flash-fix
[betaflight.git] / src / main / drivers / serial_uart_stm32h7xx.c
blob09011bb76a91fa3d377f9f6a14d48b68630cfc0b
1 /*
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)
8 * any later version.
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
25 #include <stdbool.h>
26 #include <stdint.h>
28 #include "platform.h"
30 #ifdef USE_UART
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
44 #endif
45 #ifndef UART1_RX_DMA_STREAM
46 #define UART1_RX_DMA_STREAM NULL
47 #endif
48 #ifndef UART2_TX_DMA_STREAM
49 #define UART2_TX_DMA_STREAM NULL
50 #endif
51 #ifndef UART2_RX_DMA_STREAM
52 #define UART2_RX_DMA_STREAM NULL
53 #endif
54 #ifndef UART3_TX_DMA_STREAM
55 #define UART3_TX_DMA_STREAM NULL
56 #endif
57 #ifndef UART3_RX_DMA_STREAM
58 #define UART3_RX_DMA_STREAM NULL
59 #endif
60 #ifndef UART4_TX_DMA_STREAM
61 #define UART4_TX_DMA_STREAM NULL
62 #endif
63 #ifndef UART4_RX_DMA_STREAM
64 #define UART4_RX_DMA_STREAM NULL
65 #endif
66 #ifndef UART5_TX_DMA_STREAM
67 #define UART5_TX_DMA_STREAM NULL
68 #endif
69 #ifndef UART5_RX_DMA_STREAM
70 #define UART5_RX_DMA_STREAM NULL
71 #endif
72 #ifndef UART6_TX_DMA_STREAM
73 #define UART6_TX_DMA_STREAM NULL
74 #endif
75 #ifndef UART6_RX_DMA_STREAM
76 #define UART6_RX_DMA_STREAM NULL
77 #endif
78 #ifndef UART7_TX_DMA_STREAM
79 #define UART7_TX_DMA_STREAM NULL
80 #endif
81 #ifndef UART7_RX_DMA_STREAM
82 #define UART7_RX_DMA_STREAM NULL
83 #endif
84 #ifndef UART8_TX_DMA_STREAM
85 #define UART8_TX_DMA_STREAM NULL
86 #endif
87 #ifndef UART8_RX_DMA_STREAM
88 #define UART8_RX_DMA_STREAM NULL
89 #endif
90 #ifndef UART9_TX_DMA_STREAM
91 #define UART9_TX_DMA_STREAM NULL
92 #endif
93 #ifndef UART9_RX_DMA_STREAM
94 #define UART9_RX_DMA_STREAM NULL
95 #endif
96 #ifndef UART10_TX_DMA_STREAM
97 #define UART10_TX_DMA_STREAM NULL
98 #endif
99 #ifndef UART10_RX_DMA_STREAM
100 #define UART10_RX_DMA_STREAM NULL
101 #endif
103 const uartHardware_t uartHardware[UARTDEV_COUNT] = {
104 #ifdef USE_UART1
106 .device = UARTDEV_1,
107 .reg = USART1,
108 #ifdef USE_DMA
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,
113 #endif
114 .rxPins = {
115 { DEFIO_TAG_E(PA10), GPIO_AF7_USART1 },
116 { DEFIO_TAG_E(PB7), GPIO_AF7_USART1 },
117 { DEFIO_TAG_E(PB15), GPIO_AF4_USART1 },
119 .txPins = {
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),
133 #endif
135 #ifdef USE_UART2
137 .device = UARTDEV_2,
138 .reg = USART2,
139 #ifdef USE_DMA
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,
144 #endif
145 .rxPins = {
146 { DEFIO_TAG_E(PA3), GPIO_AF7_USART2 },
147 { DEFIO_TAG_E(PD6), GPIO_AF7_USART2 }
149 .txPins = {
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),
162 #endif
164 #ifdef USE_UART3
166 .device = UARTDEV_3,
167 .reg = USART3,
168 #ifdef USE_DMA
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,
173 #endif
174 .rxPins = {
175 { DEFIO_TAG_E(PB11), GPIO_AF7_USART3 },
176 { DEFIO_TAG_E(PC11), GPIO_AF7_USART3 },
177 { DEFIO_TAG_E(PD9), GPIO_AF7_USART3 }
179 .txPins = {
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),
193 #endif
195 #ifdef USE_UART4
197 .device = UARTDEV_4,
198 .reg = UART4,
199 #ifdef USE_DMA
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,
204 #endif
205 .rxPins = {
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 }
212 .txPins = {
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),
220 .rxIrq = UART4_IRQn,
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),
228 #endif
230 #ifdef USE_UART5
232 .device = UARTDEV_5,
233 .reg = UART5,
234 #ifdef USE_DMA
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,
239 #endif
240 .rxPins = {
241 { DEFIO_TAG_E(PB5), GPIO_AF14_UART5 },
242 { DEFIO_TAG_E(PB12), GPIO_AF14_UART5 },
243 { DEFIO_TAG_E(PD2), GPIO_AF8_UART5 },
245 .txPins = {
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),
251 .rxIrq = UART5_IRQn,
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),
259 #endif
261 #ifdef USE_UART6
263 .device = UARTDEV_6,
264 .reg = USART6,
265 #ifdef USE_DMA
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,
270 #endif
271 .rxPins = {
272 { DEFIO_TAG_E(PC7), GPIO_AF7_USART6 },
273 { DEFIO_TAG_E(PG9), GPIO_AF7_USART6 }
275 .txPins = {
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),
288 #endif
290 #ifdef USE_UART7
292 .device = UARTDEV_7,
293 .reg = UART7,
294 #ifdef USE_DMA
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,
299 #endif
300 .rxPins = {
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 },
306 .txPins = {
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),
313 .rxIrq = UART7_IRQn,
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),
321 #endif
323 #ifdef USE_UART8
325 .device = UARTDEV_8,
326 .reg = UART8,
327 #ifdef USE_DMA
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,
332 #endif
333 .rxPins = {
334 { DEFIO_TAG_E(PE0), GPIO_AF8_UART8 }
336 .txPins = {
337 { DEFIO_TAG_E(PE1), GPIO_AF8_UART8 }
339 .rcc = RCC_APB1L(UART8),
340 .rxIrq = UART8_IRQn,
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),
348 #endif
350 #ifdef USE_UART9
352 .device = UARTDEV_9,
353 .reg = UART9,
354 #ifdef USE_DMA
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,
359 #endif
360 .rxPins = {
361 { DEFIO_TAG_E(PD14), GPIO_AF11_UART9 }
363 .txPins = {
364 { DEFIO_TAG_E(PD15), GPIO_AF11_UART9 }
366 .rcc = RCC_APB2(UART9),
367 .rxIrq = UART9_IRQn,
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),
375 #endif
377 #ifdef USE_UART10
379 .device = UARTDEV_10,
380 .reg = USART10,
381 #ifdef USE_DMA
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,
386 #endif
387 .rxPins = {
388 { DEFIO_TAG_E(PE2), GPIO_AF11_USART10 }
390 .txPins = {
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),
402 #endif
404 #ifdef USE_LPUART1
406 .device = LPUARTDEV_1,
407 .reg = LPUART1,
408 #ifdef USE_DMA
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)
413 #endif
414 .rxPins = {
415 { DEFIO_TAG_E(PA10), GPIO_AF3_LPUART },
416 { DEFIO_TAG_E(PB7), GPIO_AF8_LPUART }
418 .txPins = {
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),
431 #endif
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];
440 if (!uartdev) {
441 return NULL;
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;
459 #ifdef USE_DMA
460 uartConfigureDma(uartdev);
461 #endif
463 s->Handle.Instance = hardware->reg;
465 if (hardware->rcc) {
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);
481 } else {
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);
493 #ifdef USE_DMA
494 if (!s->rxDMAResource)
495 #endif
497 HAL_NVIC_SetPriority(hardware->rxIrq, NVIC_PRIORITY_BASE(hardware->rxPriority), NVIC_PRIORITY_SUB(hardware->rxPriority));
498 HAL_NVIC_EnableIRQ(hardware->rxIrq);
501 return s;
503 #endif // USE_UART