[SITL] Enable telemetry: LTM and MAVLink (#8940)
[inav.git] / src / main / drivers / serial_uart_stm32f4xx.c
blob0f54fb69142bfaab501b066725e903f5d7f62601
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_TypeDef* 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 //static uartPort_t uartPort[MAX_UARTS];
51 #ifdef USE_UART1
52 static uartDevice_t uart1 =
54 .dev = USART1,
55 .rx = IO_TAG(UART1_RX_PIN),
56 .tx = IO_TAG(UART1_TX_PIN),
57 .af = GPIO_AF_USART1,
58 #ifdef UART1_AHB1_PERIPHERALS
59 .rcc_ahb1 = UART1_AHB1_PERIPHERALS,
60 #endif
61 .rcc_apb2 = RCC_APB2(USART1),
62 .irq = USART1_IRQn,
63 .irqPriority = NVIC_PRIO_SERIALUART
65 #endif
67 #ifdef USE_UART2
68 static uartDevice_t uart2 =
70 .dev = USART2,
71 .rx = IO_TAG(UART2_RX_PIN),
72 .tx = IO_TAG(UART2_TX_PIN),
73 .af = GPIO_AF_USART2,
74 #ifdef UART2_AHB1_PERIPHERALS
75 .rcc_ahb1 = UART2_AHB1_PERIPHERALS,
76 #endif
77 .rcc_apb1 = RCC_APB1(USART2),
78 .irq = USART2_IRQn,
79 .irqPriority = NVIC_PRIO_SERIALUART
81 #endif
83 #ifdef USE_UART3
84 static uartDevice_t uart3 =
86 .dev = USART3,
87 .rx = IO_TAG(UART3_RX_PIN),
88 .tx = IO_TAG(UART3_TX_PIN),
89 .af = GPIO_AF_USART3,
90 #ifdef UART3_AHB1_PERIPHERALS
91 .rcc_ahb1 = UART3_AHB1_PERIPHERALS,
92 #endif
93 .rcc_apb1 = RCC_APB1(USART3),
94 .irq = USART3_IRQn,
95 .irqPriority = NVIC_PRIO_SERIALUART
97 #endif
99 #ifdef USE_UART4
100 static uartDevice_t uart4 =
102 .dev = UART4,
103 .rx = IO_TAG(UART4_RX_PIN),
104 .tx = IO_TAG(UART4_TX_PIN),
105 .af = GPIO_AF_UART4,
106 #ifdef UART4_AHB1_PERIPHERALS
107 .rcc_ahb1 = UART4_AHB1_PERIPHERALS,
108 #endif
109 .rcc_apb1 = RCC_APB1(UART4),
110 .irq = UART4_IRQn,
111 .irqPriority = NVIC_PRIO_SERIALUART
113 #endif
115 #ifdef USE_UART5
116 static uartDevice_t uart5 =
118 .dev = UART5,
119 .rx = IO_TAG(UART5_RX_PIN),
120 .tx = IO_TAG(UART5_TX_PIN),
121 .af = GPIO_AF_UART5,
122 #ifdef UART5_AHB1_PERIPHERALS
123 .rcc_ahb1 = UART5_AHB1_PERIPHERALS,
124 #endif
125 .rcc_apb1 = RCC_APB1(UART5),
126 .irq = UART5_IRQn,
127 .irqPriority = NVIC_PRIO_SERIALUART
129 #endif
131 #ifdef USE_UART6
132 static uartDevice_t uart6 =
134 .dev = USART6,
135 .rx = IO_TAG(UART6_RX_PIN),
136 .tx = IO_TAG(UART6_TX_PIN),
137 .af = GPIO_AF_USART6,
138 #ifdef UART6_AHB1_PERIPHERALS
139 .rcc_ahb1 = UART6_AHB1_PERIPHERALS,
140 #endif
141 .rcc_apb2 = RCC_APB2(USART6),
142 .irq = USART6_IRQn,
143 .irqPriority = NVIC_PRIO_SERIALUART
145 #endif
147 #ifdef USE_UART7
148 static uartDevice_t uart7 =
150 .dev = UART7,
151 .rx = IO_TAG(UART7_RX_PIN),
152 .tx = IO_TAG(UART7_TX_PIN),
153 .af = GPIO_AF_UART7,
154 .rcc_apb1 = RCC_APB1(UART7),
155 .irq = UART7_IRQn,
156 .irqPriority = NVIC_PRIO_SERIALUART
158 #endif
160 #ifdef USE_UART8
161 static uartDevice_t uart8 =
163 .dev = UART8,
164 .rx = IO_TAG(UART8_RX_PIN),
165 .tx = IO_TAG(UART8_TX_PIN),
166 .af = GPIO_AF_UART8,
167 .rcc_apb1 = RCC_APB1(UART8),
168 .irq = UART8_IRQn,
169 .irqPriority = NVIC_PRIO_SERIALUART
171 #endif
173 static uartDevice_t* uartHardwareMap[] = {
174 #ifdef USE_UART1
175 &uart1,
176 #else
177 NULL,
178 #endif
179 #ifdef USE_UART2
180 &uart2,
181 #else
182 NULL,
183 #endif
184 #ifdef USE_UART3
185 &uart3,
186 #else
187 NULL,
188 #endif
189 #ifdef USE_UART4
190 &uart4,
191 #else
192 NULL,
193 #endif
194 #ifdef USE_UART5
195 &uart5,
196 #else
197 NULL,
198 #endif
199 #ifdef USE_UART6
200 &uart6,
201 #else
202 NULL,
203 #endif
204 #ifdef USE_UART7
205 &uart7,
206 #else
207 NULL,
208 #endif
209 #ifdef USE_UART8
210 &uart8,
211 #else
212 NULL,
213 #endif
216 void uartIrqHandler(uartPort_t *s)
218 if (USART_GetITStatus(s->USARTx, USART_IT_RXNE) == SET) {
219 if (s->port.rxCallback) {
220 s->port.rxCallback(s->USARTx->DR, s->port.rxCallbackData);
221 } else {
222 s->port.rxBuffer[s->port.rxBufferHead] = s->USARTx->DR;
223 s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
227 if (USART_GetITStatus(s->USARTx, USART_IT_TXE) == SET) {
228 if (s->port.txBufferTail != s->port.txBufferHead) {
229 USART_SendData(s->USARTx, s->port.txBuffer[s->port.txBufferTail]);
230 s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
231 } else {
232 USART_ITConfig(s->USARTx, USART_IT_TXE, DISABLE);
236 if (USART_GetITStatus(s->USARTx, USART_FLAG_ORE) == SET)
238 USART_ClearITPendingBit (s->USARTx, USART_IT_ORE);
242 void uartGetPortPins(UARTDevice_e device, serialPortPins_t * pins)
244 uartDevice_t *uart = uartHardwareMap[device];
246 if (uart) {
247 pins->txPin = uart->tx;
248 pins->rxPin = uart->rx;
250 else {
251 pins->txPin = IO_TAG(NONE);
252 pins->rxPin = IO_TAG(NONE);
256 void uartClearIdleFlag(uartPort_t *s)
258 (void) s->USARTx->SR;
259 (void) s->USARTx->DR;
262 uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_t mode, portOptions_t options)
264 uartPort_t *s;
266 uartDevice_t *uart = uartHardwareMap[device];
267 if (!uart) return NULL;
269 s = &(uart->port);
270 s->port.vTable = uartVTable;
272 s->port.baudRate = baudRate;
274 s->port.rxBuffer = uart->rxBuffer;
275 s->port.txBuffer = uart->txBuffer;
276 s->port.rxBufferSize = sizeof(uart->rxBuffer);
277 s->port.txBufferSize = sizeof(uart->txBuffer);
279 s->USARTx = uart->dev;
281 IO_t tx = IOGetByTag(uart->tx);
282 IO_t rx = IOGetByTag(uart->rx);
284 if (uart->rcc_apb2)
285 RCC_ClockCmd(uart->rcc_apb2, ENABLE);
287 if (uart->rcc_apb1)
288 RCC_ClockCmd(uart->rcc_apb1, ENABLE);
290 if (uart->rcc_ahb1)
291 RCC_AHB1PeriphClockCmd(uart->rcc_ahb1, ENABLE);
293 if (options & SERIAL_BIDIR) {
294 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TXRX, RESOURCE_INDEX(device));
295 if (options & SERIAL_BIDIR_PP) {
296 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
297 } else {
298 IOConfigGPIOAF(tx,
299 (options & SERIAL_BIDIR_NOPULL) ? IOCFG_AF_OD : IOCFG_AF_OD_UP,
300 uart->af);
303 else {
304 if (mode & MODE_TX) {
305 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(device));
306 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
309 if (mode & MODE_RX) {
310 IOInit(rx, OWNER_SERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(device));
311 IOConfigGPIOAF(rx, IOCFG_AF_PP, uart->af);
315 NVIC_SetPriority(uart->irq, uart->irqPriority);
316 NVIC_EnableIRQ(uart->irq);
318 return s;
321 #ifdef USE_UART1
322 uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
324 return serialUART(UARTDEV_1, baudRate, mode, options);
327 // USART1 Rx/Tx IRQ Handler
328 void USART1_IRQHandler(void)
330 uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
331 uartIrqHandler(s);
334 #endif
336 #ifdef USE_UART2
337 // USART2 - GPS or Spektrum or ?? (RX + TX by IRQ)
338 uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
340 return serialUART(UARTDEV_2, baudRate, mode, options);
343 void USART2_IRQHandler(void)
345 uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
346 uartIrqHandler(s);
348 #endif
350 #ifdef USE_UART3
351 // USART3
352 uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
354 return serialUART(UARTDEV_3, baudRate, mode, options);
357 void USART3_IRQHandler(void)
359 uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
360 uartIrqHandler(s);
362 #endif
364 #ifdef USE_UART4
365 // USART4
366 uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
368 return serialUART(UARTDEV_4, baudRate, mode, options);
371 void UART4_IRQHandler(void)
373 uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
374 uartIrqHandler(s);
376 #endif
378 #ifdef USE_UART5
379 // USART5
380 uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
382 return serialUART(UARTDEV_5, baudRate, mode, options);
385 void UART5_IRQHandler(void)
387 uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
388 uartIrqHandler(s);
390 #endif
392 #ifdef USE_UART6
393 // USART6
394 uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options)
396 return serialUART(UARTDEV_6, baudRate, mode, options);
399 void USART6_IRQHandler(void)
401 uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
402 uartIrqHandler(s);
404 #endif
406 #ifdef USE_UART7
407 uartPort_t *serialUART7(uint32_t baudRate, portMode_t mode, portOptions_t options)
409 return serialUART(UARTDEV_7, baudRate, mode, options);
412 // UART7 Rx/Tx IRQ Handler
413 void UART7_IRQHandler(void)
415 uartPort_t *s = &(uartHardwareMap[UARTDEV_7]->port);
416 uartIrqHandler(s);
418 #endif
420 #ifdef USE_UART8
421 uartPort_t *serialUART8(uint32_t baudRate, portMode_t mode, portOptions_t options)
423 return serialUART(UARTDEV_8, baudRate, mode, options);
426 // UART8 Rx/Tx IRQ Handler
427 void UART8_IRQHandler(void)
429 uartPort_t *s = &(uartHardwareMap[UARTDEV_8]->port);
430 uartIrqHandler(s);
432 #endif