Merge pull request #10558 from iNavFlight/MrD_Correct-comments-on-OSD-symbols
[inav.git] / src / main / drivers / serial_uart_stm32f7xx.c
blob1f3c02f7e56fa64e0f37f074fcaf1c22d928492d
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_TX_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 #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 #ifdef UART1_AF
57 .af = UART_AF(USART1, UART1_AF),
58 #else
59 .af = GPIO_AF7_USART1,
60 #endif
61 #ifdef UART1_AHB1_PERIPHERALS
62 .rcc_ahb1 = UART1_AHB1_PERIPHERALS,
63 #endif
64 .rcc_apb2 = RCC_APB2(USART1),
65 .irq = USART1_IRQn,
66 .irqPriority = NVIC_PRIO_SERIALUART
68 #endif
70 #ifdef USE_UART2
71 static uartDevice_t uart2 =
73 .dev = USART2,
74 .rx = IO_TAG(UART2_RX_PIN),
75 .tx = IO_TAG(UART2_TX_PIN),
76 #ifdef UART2_AF
77 .af = UART_AF(USART2, UART2_AF),
78 #else
79 .af = GPIO_AF7_USART2,
80 #endif
81 #ifdef UART2_AHB1_PERIPHERALS
82 .rcc_ahb1 = UART2_AHB1_PERIPHERALS,
83 #endif
84 .rcc_apb1 = RCC_APB1(USART2),
85 .irq = USART2_IRQn,
86 .irqPriority = NVIC_PRIO_SERIALUART
88 #endif
90 #ifdef USE_UART3
91 static uartDevice_t uart3 =
93 .dev = USART3,
94 .rx = IO_TAG(UART3_RX_PIN),
95 .tx = IO_TAG(UART3_TX_PIN),
96 #ifdef UART3_AF
97 .af = UART_AF(USART3, UART3_AF),
98 #else
99 .af = GPIO_AF7_USART3,
100 #endif
101 #ifdef UART3_AHB1_PERIPHERALS
102 .rcc_ahb1 = UART3_AHB1_PERIPHERALS,
103 #endif
104 .rcc_apb1 = RCC_APB1(USART3),
105 .irq = USART3_IRQn,
106 .irqPriority = NVIC_PRIO_SERIALUART
108 #endif
110 #ifdef USE_UART4
111 static uartDevice_t uart4 =
113 .dev = UART4,
114 .rx = IO_TAG(UART4_RX_PIN),
115 .tx = IO_TAG(UART4_TX_PIN),
116 #ifdef UART4_AF
117 .af = UART_AF(UART4, UART4_AF),
118 #else
119 .af = GPIO_AF8_UART4,
120 #endif
121 #ifdef UART4_AHB1_PERIPHERALS
122 .rcc_ahb1 = UART4_AHB1_PERIPHERALS,
123 #endif
124 .rcc_apb1 = RCC_APB1(UART4),
125 .irq = UART4_IRQn,
126 .irqPriority = NVIC_PRIO_SERIALUART
128 #endif
130 #ifdef USE_UART5
131 static uartDevice_t uart5 =
133 .dev = UART5,
134 .rx = IO_TAG(UART5_RX_PIN),
135 .tx = IO_TAG(UART5_TX_PIN),
136 #ifdef UART5_AF
137 .af = UART_AF(UART5, UART5_AF),
138 #else
139 .af = GPIO_AF8_UART5,
140 #endif
141 #ifdef UART5_AHB1_PERIPHERALS
142 .rcc_ahb1 = UART5_AHB1_PERIPHERALS,
143 #endif
144 .rcc_apb1 = RCC_APB1(UART5),
145 .irq = UART5_IRQn,
146 .irqPriority = NVIC_PRIO_SERIALUART
148 #endif
150 #ifdef USE_UART6
151 static uartDevice_t uart6 =
153 .dev = USART6,
154 .rx = IO_TAG(UART6_RX_PIN),
155 .tx = IO_TAG(UART6_TX_PIN),
156 #ifdef UART6_AF
157 .af = UART_AF(USART6, UART6_AF),
158 #else
159 .af = GPIO_AF8_USART6,
160 #endif
161 #ifdef UART6_AHB1_PERIPHERALS
162 .rcc_ahb1 = UART6_AHB1_PERIPHERALS,
163 #endif
164 .rcc_apb2 = RCC_APB2(USART6),
165 .irq = USART6_IRQn,
166 .irqPriority = NVIC_PRIO_SERIALUART
168 #endif
170 #ifdef USE_UART7
171 static uartDevice_t uart7 =
173 .dev = UART7,
174 .rx = IO_TAG(UART7_RX_PIN),
175 .tx = IO_TAG(UART7_TX_PIN),
176 #ifdef UART7_AF
177 .af = UART_AF(UART7, UART7_AF),
178 #else
179 .af = GPIO_AF8_UART7,
180 #endif
181 #ifdef UART7_AHB1_PERIPHERALS
182 .rcc_ahb1 = UART7_AHB1_PERIPHERALS,
183 #endif
184 .rcc_apb1 = RCC_APB1(UART7),
185 .irq = UART7_IRQn,
186 .irqPriority = NVIC_PRIO_SERIALUART
188 #endif
189 #ifdef USE_UART8
190 static uartDevice_t uart8 =
192 .dev = UART8,
193 .rx = IO_TAG(UART8_RX_PIN),
194 .tx = IO_TAG(UART8_TX_PIN),
195 #ifdef UART8_AF
196 .af = UART_AF(UART8, UART8_AF),
197 #else
198 .af = GPIO_AF8_UART8,
199 #endif
200 #ifdef UART8_AHB1_PERIPHERALS
201 .rcc_ahb1 = UART8_AHB1_PERIPHERALS,
202 #endif
203 .rcc_apb1 = RCC_APB1(UART8),
204 .irq = UART8_IRQn,
205 .irqPriority = NVIC_PRIO_SERIALUART
207 #endif
211 static uartDevice_t* uartHardwareMap[] = {
212 #ifdef USE_UART1
213 &uart1,
214 #else
215 NULL,
216 #endif
217 #ifdef USE_UART2
218 &uart2,
219 #else
220 NULL,
221 #endif
222 #ifdef USE_UART3
223 &uart3,
224 #else
225 NULL,
226 #endif
227 #ifdef USE_UART4
228 &uart4,
229 #else
230 NULL,
231 #endif
232 #ifdef USE_UART5
233 &uart5,
234 #else
235 NULL,
236 #endif
237 #ifdef USE_UART6
238 &uart6,
239 #else
240 NULL,
241 #endif
242 #ifdef USE_UART7
243 &uart7,
244 #else
245 NULL,
246 #endif
247 #ifdef USE_UART8
248 &uart8,
249 #else
250 NULL,
251 #endif
254 void uartIrqHandler(uartPort_t *s)
256 UART_HandleTypeDef *huart = &s->Handle;
257 /* UART in mode Receiver ---------------------------------------------------*/
258 if ((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET)) {
259 uint8_t rbyte = (uint8_t)(huart->Instance->RDR & (uint8_t) 0xff);
261 if (s->port.rxCallback) {
262 s->port.rxCallback(rbyte, s->port.rxCallbackData);
263 } else {
264 s->port.rxBuffer[s->port.rxBufferHead] = rbyte;
265 s->port.rxBufferHead = (s->port.rxBufferHead + 1) % s->port.rxBufferSize;
267 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE));
269 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
270 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
272 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
275 /* UART parity error interrupt occurred -------------------------------------*/
276 if ((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET)) {
277 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
280 /* UART frame error interrupt occurred --------------------------------------*/
281 if ((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET)) {
282 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
285 /* UART noise error interrupt occurred --------------------------------------*/
286 if ((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET)) {
287 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
290 /* UART Over-Run interrupt occurred -----------------------------------------*/
291 if ((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET)) {
292 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
295 /* UART in mode Transmitter ------------------------------------------------*/
296 if (__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) {
297 /* Check that a Tx process is ongoing */
298 if (huart->gState != HAL_UART_STATE_BUSY_TX) {
299 if (s->port.txBufferTail == s->port.txBufferHead) {
300 huart->TxXferCount = 0;
301 /* Disable the UART Transmit Data Register Empty Interrupt */
302 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
303 } else {
304 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) {
305 huart->Instance->TDR = (((uint16_t) s->port.txBuffer[s->port.txBufferTail]) & (uint16_t) 0x01FFU);
306 } else {
307 huart->Instance->TDR = (uint8_t)(s->port.txBuffer[s->port.txBufferTail]);
309 s->port.txBufferTail = (s->port.txBufferTail + 1) % s->port.txBufferSize;
314 /* UART in mode Transmitter (transmission end) -----------------------------*/
315 if ((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET)) {
316 HAL_UART_IRQHandler(huart);
320 void uartGetPortPins(UARTDevice_e device, serialPortPins_t * pins)
322 uartDevice_t *uart = uartHardwareMap[device];
324 if (uart) {
325 pins->txPin = uart->tx;
326 pins->rxPin = uart->rx;
328 else {
329 pins->txPin = IO_TAG(NONE);
330 pins->rxPin = IO_TAG(NONE);
334 uartPort_t *serialUART(UARTDevice_e device, uint32_t baudRate, portMode_t mode, portOptions_t options)
336 uartPort_t *s;
338 uartDevice_t *uart = uartHardwareMap[device];
339 if (!uart) return NULL;
341 s = &(uart->port);
342 s->port.vTable = uartVTable;
344 s->port.baudRate = baudRate;
346 s->port.rxBuffer = uart->rxBuffer;
347 s->port.txBuffer = uart->txBuffer;
348 s->port.rxBufferSize = sizeof(uart->rxBuffer);
349 s->port.txBufferSize = sizeof(uart->txBuffer);
351 s->USARTx = uart->dev;
353 s->Handle.Instance = uart->dev;
355 IO_t tx = IOGetByTag(uart->tx);
356 IO_t rx = IOGetByTag(uart->rx);
358 if (options & SERIAL_BIDIR) {
359 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TXRX, RESOURCE_INDEX(device));
360 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
362 else {
363 if (mode & MODE_TX) {
364 IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(device));
365 IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
368 if (mode & MODE_RX) {
369 IOInit(rx, OWNER_SERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(device));
370 IOConfigGPIOAF(rx, IOCFG_AF_PP, uart->af);
374 HAL_NVIC_SetPriority(uart->irq, uart->irqPriority, 0);
375 HAL_NVIC_EnableIRQ(uart->irq);
377 return s;
380 #ifdef USE_UART1
381 uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
383 return serialUART(UARTDEV_1, baudRate, mode, options);
386 // USART1 Rx/Tx IRQ Handler
387 void USART1_IRQHandler(void)
389 uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
390 uartIrqHandler(s);
392 #endif
394 #ifdef USE_UART2
395 uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
397 return serialUART(UARTDEV_2, baudRate, mode, options);
400 // USART2 Rx/Tx IRQ Handler
401 void USART2_IRQHandler(void)
403 uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
404 uartIrqHandler(s);
406 #endif
408 #ifdef USE_UART3
409 uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
411 return serialUART(UARTDEV_3, baudRate, mode, options);
414 // USART3 Rx/Tx IRQ Handler
415 void USART3_IRQHandler(void)
417 uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
418 uartIrqHandler(s);
420 #endif
422 #ifdef USE_UART4
423 uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
425 return serialUART(UARTDEV_4, baudRate, mode, options);
428 // UART4 Rx/Tx IRQ Handler
429 void UART4_IRQHandler(void)
431 uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
432 uartIrqHandler(s);
434 #endif
436 #ifdef USE_UART5
437 uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
439 return serialUART(UARTDEV_5, baudRate, mode, options);
442 // UART5 Rx/Tx IRQ Handler
443 void UART5_IRQHandler(void)
445 uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
446 uartIrqHandler(s);
448 #endif
450 #ifdef USE_UART6
451 uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options)
453 return serialUART(UARTDEV_6, baudRate, mode, options);
456 // USART6 Rx/Tx IRQ Handler
457 void USART6_IRQHandler(void)
459 uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
460 uartIrqHandler(s);
462 #endif
464 #ifdef USE_UART7
465 uartPort_t *serialUART7(uint32_t baudRate, portMode_t mode, portOptions_t options)
467 return serialUART(UARTDEV_7, baudRate, mode, options);
470 // UART7 Rx/Tx IRQ Handler
471 void UART7_IRQHandler(void)
473 uartPort_t *s = &(uartHardwareMap[UARTDEV_7]->port);
474 uartIrqHandler(s);
476 #endif
478 #ifdef USE_UART8
479 uartPort_t *serialUART8(uint32_t baudRate, portMode_t mode, portOptions_t options)
481 return serialUART(UARTDEV_8, baudRate, mode, options);
484 // UART8 Rx/Tx IRQ Handler
485 void UART8_IRQHandler(void)
487 uartPort_t *s = &(uartHardwareMap[UARTDEV_8]->port);
488 uartIrqHandler(s);
490 #endif