Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / serial_uart_at32f43x.c
blob354ea6c934339c4cf9c85fa75e2d8c79367dd731
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #include "drivers/time.h"
24 #include "drivers/io.h"
25 #include "rcc.h"
26 #include "drivers/nvic.h"
28 #include "serial.h"
29 #include "serial_uart.h"
30 #include "serial_uart_impl.h"
32 #define UART_RX_BUFFER_SIZE UART1_RX_BUFFER_SIZE
33 #define UART_TX_BUFFER_SIZE UART1_RX_BUFFER_SIZE
35 typedef struct uartDevice_s {
36 usart_type* dev;
37 uartPort_t port;
38 ioTag_t rx;
39 ioTag_t tx;
40 volatile uint8_t rxBuffer[UART_RX_BUFFER_SIZE];
41 volatile uint8_t txBuffer[UART_TX_BUFFER_SIZE];
42 uint32_t rcc_ahb1;
43 rccPeriphTag_t rcc_apb2;
44 rccPeriphTag_t rcc_apb1;
45 uint8_t af;
46 uint8_t irq;
47 uint32_t irqPriority;
48 } uartDevice_t;
50 #ifdef USE_UART1
51 static uartDevice_t uart1 =
53 .dev = USART1,
54 .rx = IO_TAG(UART1_RX_PIN),
55 .tx = IO_TAG(UART1_TX_PIN),
56 .af = GPIO_MUX_7,
57 #ifdef UART1_AHB1_PERIPHERALS
58 .rcc_ahb1 = UART1_AHB1_PERIPHERALS,
59 #endif
60 .rcc_apb2 = RCC_APB2(USART1),
61 .irq = USART1_IRQn,
62 .irqPriority = NVIC_PRIO_SERIALUART
64 #endif
66 #ifdef USE_UART2
67 static uartDevice_t uart2 =
69 .dev = USART2,
70 .rx = IO_TAG(UART2_RX_PIN),
71 .tx = IO_TAG(UART2_TX_PIN),
72 .af = GPIO_MUX_7,
73 #ifdef UART2_AHB1_PERIPHERALS
74 .rcc_ahb1 = UART2_AHB1_PERIPHERALS,
75 #endif
76 .rcc_apb1 = RCC_APB1(USART2),
77 .irq = USART2_IRQn,
78 .irqPriority = NVIC_PRIO_SERIALUART
80 #endif
82 #ifdef USE_UART3
83 static uartDevice_t uart3 =
85 .dev = USART3,
86 .rx = IO_TAG(UART3_RX_PIN),
87 .tx = IO_TAG(UART3_TX_PIN),
88 .af = GPIO_MUX_7,
89 #ifdef UART3_AHB1_PERIPHERALS
90 .rcc_ahb1 = UART3_AHB1_PERIPHERALS,
91 #endif
92 .rcc_apb1 = RCC_APB1(USART3),
93 .irq = USART3_IRQn,
94 .irqPriority = NVIC_PRIO_SERIALUART
96 #endif
98 #ifdef USE_UART4
99 static uartDevice_t uart4 =
101 .dev = UART4,
102 .rx = IO_TAG(UART4_RX_PIN),
103 .tx = IO_TAG(UART4_TX_PIN),
104 .af = GPIO_MUX_8,
105 #ifdef UART4_AHB1_PERIPHERALS
106 .rcc_ahb1 = UART4_AHB1_PERIPHERALS,
107 #endif
108 .rcc_apb1 = RCC_APB1(UART4),
109 .irq = UART4_IRQn,
110 .irqPriority = NVIC_PRIO_SERIALUART
112 #endif
114 #ifdef USE_UART5
115 static uartDevice_t uart5 =
117 .dev = UART5,
118 .rx = IO_TAG(UART5_RX_PIN),
119 .tx = IO_TAG(UART5_TX_PIN),
120 .af = GPIO_MUX_8,
121 #ifdef UART5_AHB1_PERIPHERALS
122 .rcc_ahb1 = UART5_AHB1_PERIPHERALS,
123 #endif
124 .rcc_apb1 = RCC_APB1(UART5),
125 .irq = UART5_IRQn,
126 .irqPriority = NVIC_PRIO_SERIALUART
128 #endif
130 #ifdef USE_UART6
131 static uartDevice_t uart6 =
133 .dev = USART6,
134 .rx = IO_TAG(UART6_RX_PIN),
135 .tx = IO_TAG(UART6_TX_PIN),
136 .af = GPIO_MUX_8,
137 #ifdef UART6_AHB1_PERIPHERALS
138 .rcc_ahb1 = UART6_AHB1_PERIPHERALS,
139 #endif
140 .rcc_apb2 = RCC_APB2(USART6),
141 .irq = USART6_IRQn,
142 .irqPriority = NVIC_PRIO_SERIALUART
144 #endif
146 #ifdef USE_UART7
147 static uartDevice_t uart7 =
149 .dev = UART7,
150 .rx = IO_TAG(UART7_RX_PIN),
151 .tx = IO_TAG(UART7_TX_PIN),
152 .af = GPIO_MUX_8,
153 .rcc_apb1 = RCC_APB1(UART7),
154 .irq = UART7_IRQn,
155 .irqPriority = NVIC_PRIO_SERIALUART
157 #endif
159 #ifdef USE_UART8
160 static uartDevice_t uart8 =
162 .dev = UART8,
163 .rx = IO_TAG(UART8_RX_PIN),
164 .tx = IO_TAG(UART8_TX_PIN),
165 .af = GPIO_MUX_8,
166 .rcc_apb1 = RCC_APB1(UART8),
167 .irq = UART8_IRQn,
168 .irqPriority = NVIC_PRIO_SERIALUART
170 #endif
172 static uartDevice_t* uartHardwareMap[] = {
173 #ifdef USE_UART1
174 &uart1,
175 #else
176 NULL,
177 #endif
178 #ifdef USE_UART2
179 &uart2,
180 #else
181 NULL,
182 #endif
183 #ifdef USE_UART3
184 &uart3,
185 #else
186 NULL,
187 #endif
188 #ifdef USE_UART4
189 &uart4,
190 #else
191 NULL,
192 #endif
193 #ifdef USE_UART5
194 &uart5,
195 #else
196 NULL,
197 #endif
198 #ifdef USE_UART6
199 &uart6,
200 #else
201 NULL,
202 #endif
203 #ifdef USE_UART7
204 &uart7,
205 #else
206 NULL,
207 #endif
208 #ifdef USE_UART8
209 &uart8,
210 #else
211 NULL,
212 #endif
215 void uartIrqHandler(uartPort_t *s)
217 if (usart_flag_get(s->USARTx, USART_RDBF_FLAG) == SET) {
218 if (s->port.rxCallback) {
219 s->port.rxCallback(s->USARTx->dt, s->port.rxCallbackData);
220 } else {
221 s->port.rxBuffer[s->port.rxBufferHead] = s->USARTx->dt;
222 s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
226 if (usart_flag_get(s->USARTx, USART_TDBE_FLAG) == SET) {
227 if (s->port.txBufferTail != s->port.txBufferHead) {
228 usart_data_transmit(s->USARTx, s->port.txBuffer[s->port.txBufferTail]);
229 s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
230 } else {
231 usart_interrupt_enable (s->USARTx, USART_TDBE_INT, FALSE);
235 if (usart_flag_get(s->USARTx, USART_ROERR_FLAG) == SET)
237 usart_flag_clear(s->USARTx, USART_ROERR_FLAG);
241 void uartGetPortPins(UARTDevice_e device, serialPortPins_t * pins)
243 uartDevice_t *uart = uartHardwareMap[device];
245 if (uart) {
246 pins->txPin = uart->tx;
247 pins->rxPin = uart->rx;
249 else {
250 pins->txPin = IO_TAG(NONE);
251 pins->rxPin = IO_TAG(NONE);
255 void uartClearIdleFlag(uartPort_t *s)
257 (void) s->USARTx->sts;
258 (void) s->USARTx->dt;
261 uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_t mode, portOptions_t options)
263 uartPort_t *s;
265 uartDevice_t *uart = uartHardwareMap[device];
266 if (!uart) return NULL;
268 s = &(uart->port);
269 s->port.vTable = uartVTable;
271 s->port.baudRate = baudRate;
273 s->port.rxBuffer = uart->rxBuffer;
274 s->port.txBuffer = uart->txBuffer;
275 s->port.rxBufferSize = sizeof(uart->rxBuffer);
276 s->port.txBufferSize = sizeof(uart->txBuffer);
278 s->USARTx = uart->dev;
280 IO_t tx = IOGetByTag(uart->tx);
281 IO_t rx = IOGetByTag(uart->rx);
283 if (uart->rcc_apb2)
284 RCC_ClockCmd(uart->rcc_apb2, ENABLE);
286 if (uart->rcc_apb1)
287 RCC_ClockCmd(uart->rcc_apb1, ENABLE);
289 if (uart->rcc_ahb1)
290 RCC_ClockCmd(uart->rcc_apb1, ENABLE);
292 if (options & SERIAL_BIDIR) {
293 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TXRX, RESOURCE_INDEX(device));
294 if (options & SERIAL_BIDIR_PP) {
295 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
296 } else {
297 IOConfigGPIOAF(tx,
298 (options & SERIAL_BIDIR_NOPULL) ? IOCFG_AF_OD : IOCFG_AF_OD_UP,
299 uart->af);
302 else {
303 if (mode & MODE_TX) {
304 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(device));
305 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
308 if (mode & MODE_RX) {
309 IOInit(rx, OWNER_SERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(device));
310 IOConfigGPIOAF(rx, IOCFG_AF_PP, uart->af);
314 nvic_irq_enable(uart->irq, uart->irqPriority, 0);
317 return s;
320 #ifdef USE_UART1
321 uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
323 return serialUART(UARTDEV_1, baudRate, mode, options);
326 // USART1 Rx/Tx IRQ Handler
327 void USART1_IRQHandler(void)
329 uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
330 uartIrqHandler(s);
333 #endif
335 #ifdef USE_UART2
336 // USART2 (RX + TX by IRQ)
337 uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
339 return serialUART(UARTDEV_2, baudRate, mode, options);
342 void USART2_IRQHandler(void)
344 uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
345 uartIrqHandler(s);
347 #endif
349 #ifdef USE_UART3
350 // USART3
351 uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
353 return serialUART(UARTDEV_3, baudRate, mode, options);
356 void USART3_IRQHandler(void)
358 uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
359 uartIrqHandler(s);
361 #endif
363 #ifdef USE_UART4
364 // USART4
365 uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
367 return serialUART(UARTDEV_4, baudRate, mode, options);
370 void UART4_IRQHandler(void)
372 uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
373 uartIrqHandler(s);
375 #endif
377 #ifdef USE_UART5
378 // USART5
379 uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
381 return serialUART(UARTDEV_5, baudRate, mode, options);
384 void UART5_IRQHandler(void)
386 uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
387 uartIrqHandler(s);
389 #endif
391 #ifdef USE_UART6
392 // USART6
393 uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options)
395 return serialUART(UARTDEV_6, baudRate, mode, options);
398 void USART6_IRQHandler(void)
400 uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
401 uartIrqHandler(s);
403 #endif
405 #ifdef USE_UART7
406 uartPort_t *serialUART7(uint32_t baudRate, portMode_t mode, portOptions_t options)
408 return serialUART(UARTDEV_7, baudRate, mode, options);
411 // UART7 Rx/Tx IRQ Handler
412 void UART7_IRQHandler(void)
414 uartPort_t *s = &(uartHardwareMap[UARTDEV_7]->port);
415 uartIrqHandler(s);
417 #endif
419 #ifdef USE_UART8
420 uartPort_t *serialUART8(uint32_t baudRate, portMode_t mode, portOptions_t options)
422 return serialUART(UARTDEV_8, baudRate, mode, options);
425 // UART8 Rx/Tx IRQ Handler
426 void UART8_IRQHandler(void)
428 uartPort_t *s = &(uartHardwareMap[UARTDEV_8]->port);
429 uartIrqHandler(s);
431 #endif