2 * This file is part of INAV.
4 * INAV 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 * INAV 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 INAV. If not, see <http://www.gnu.org/licenses/>.
23 #include "drivers/time.h"
24 #include "drivers/io.h"
26 #include "drivers/nvic.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
{
40 volatile uint8_t rxBuffer
[UART_RX_BUFFER_SIZE
];
41 volatile uint8_t txBuffer
[UART_TX_BUFFER_SIZE
];
48 #define UART_PIN_AF_HELPER(uart, pin) CONCAT4(UART_PIN_AF_UART, uart, _, pin)
51 #define UART_PIN_AF_UART1_PA9 GPIO_AF7_USART1
52 #define UART_PIN_AF_UART1_PA10 GPIO_AF7_USART1
53 #define UART_PIN_AF_UART1_PB6 GPIO_AF7_USART1
54 #define UART_PIN_AF_UART1_PB7 GPIO_AF7_USART1
55 #define UART_PIN_AF_UART1_PB14 GPIO_AF4_USART1
56 #define UART_PIN_AF_UART1_PB15 GPIO_AF4_USART1
58 static uartDevice_t uart1
=
61 .rx
= IO_TAG(UART1_RX_PIN
),
62 .tx
= IO_TAG(UART1_TX_PIN
),
63 .af_rx
= UART_PIN_AF_HELPER(1, UART1_RX_PIN
),
64 .af_tx
= UART_PIN_AF_HELPER(1, UART1_TX_PIN
),
65 .rcc
= RCC_APB2(USART1
),
71 static uartDevice_t uart2
=
74 .rx
= IO_TAG(UART2_RX_PIN
),
75 .tx
= IO_TAG(UART2_TX_PIN
),
76 .af_rx
= GPIO_AF7_USART2
,
77 .af_tx
= GPIO_AF7_USART2
,
78 .rcc
= RCC_APB1L(USART2
),
84 static uartDevice_t uart3
=
87 .rx
= IO_TAG(UART3_RX_PIN
),
88 .tx
= IO_TAG(UART3_TX_PIN
),
89 .af_rx
= GPIO_AF7_USART3
,
90 .af_tx
= GPIO_AF7_USART3
,
91 .rcc
= RCC_APB1L(USART3
),
97 #define UART_PIN_AF_UART4_PA0 GPIO_AF8_UART4
98 #define UART_PIN_AF_UART4_PA1 GPIO_AF8_UART4
99 #define UART_PIN_AF_UART4_PA11 GPIO_AF6_UART4
100 #define UART_PIN_AF_UART4_PA12 GPIO_AF6_UART4
101 #define UART_PIN_AF_UART4_PB8 GPIO_AF8_UART4
102 #define UART_PIN_AF_UART4_PB9 GPIO_AF8_UART4
103 #define UART_PIN_AF_UART4_PC10 GPIO_AF8_UART4
104 #define UART_PIN_AF_UART4_PC11 GPIO_AF8_UART4
105 #define UART_PIN_AF_UART4_PD0 GPIO_AF8_UART4
106 #define UART_PIN_AF_UART4_PD1 GPIO_AF8_UART4
108 static uartDevice_t uart4
=
111 .rx
= IO_TAG(UART4_RX_PIN
),
112 .tx
= IO_TAG(UART4_TX_PIN
),
113 .af_rx
= UART_PIN_AF_HELPER(4, UART4_RX_PIN
),
114 .af_tx
= UART_PIN_AF_HELPER(4, UART4_TX_PIN
),
115 .rcc
= RCC_APB1L(UART4
),
121 #define UART_PIN_AF_UART5_PB5 GPIO_AF14_UART5
122 #define UART_PIN_AF_UART5_PB6 GPIO_AF14_UART5
123 #define UART_PIN_AF_UART5_PB12 GPIO_AF14_UART5
124 #define UART_PIN_AF_UART5_PB13 GPIO_AF14_UART5
125 #define UART_PIN_AF_UART5_PD2 GPIO_AF8_UART5
126 #define UART_PIN_AF_UART5_PC12 GPIO_AF8_UART5
128 static uartDevice_t uart5
=
131 .rx
= IO_TAG(UART5_RX_PIN
),
132 .tx
= IO_TAG(UART5_TX_PIN
),
133 .af_rx
= UART_PIN_AF_HELPER(5, UART5_RX_PIN
),
134 .af_tx
= UART_PIN_AF_HELPER(5, UART5_TX_PIN
),
135 .rcc
= RCC_APB1L(UART5
),
141 static uartDevice_t uart6
=
144 .rx
= IO_TAG(UART6_RX_PIN
),
145 .tx
= IO_TAG(UART6_TX_PIN
),
146 .af_rx
= GPIO_AF7_USART6
,
147 .af_tx
= GPIO_AF7_USART6
,
148 .rcc
= RCC_APB2(USART6
),
154 #define UART_PIN_AF_UART7_PA8 GPIO_AF11_UART7
155 #define UART_PIN_AF_UART7_PA15 GPIO_AF11_UART7
156 #define UART_PIN_AF_UART7_PB3 GPIO_AF11_UART7
157 #define UART_PIN_AF_UART7_PB4 GPIO_AF11_UART7
158 #define UART_PIN_AF_UART7_PE7 GPIO_AF7_UART7
159 #define UART_PIN_AF_UART7_PE8 GPIO_AF7_UART7
160 #define UART_PIN_AF_UART7_PF6 GPIO_AF7_UART7
161 #define UART_PIN_AF_UART7_PF7 GPIO_AF7_UART7
163 static uartDevice_t uart7
=
166 .rx
= IO_TAG(UART7_RX_PIN
),
168 .tx
= IO_TAG(UART7_TX_PIN
),
170 .af_rx
= UART_PIN_AF_HELPER(7, UART7_RX_PIN
),
172 .af_tx
= UART_PIN_AF_HELPER(7, UART7_TX_PIN
),
174 .rcc
= RCC_APB1L(UART7
),
180 static uartDevice_t uart8
=
183 .rx
= IO_TAG(UART8_RX_PIN
),
184 .tx
= IO_TAG(UART8_TX_PIN
),
185 .af_rx
= GPIO_AF8_UART8
,
186 .af_tx
= GPIO_AF8_UART8
,
187 .rcc
= RCC_APB1L(UART8
),
194 static uartDevice_t
* uartHardwareMap
[] = {
237 void uartGetPortPins(UARTDevice_e device
, serialPortPins_t
* pins
)
239 uartDevice_t
*uart
= uartHardwareMap
[device
];
242 pins
->txPin
= uart
->tx
;
243 pins
->rxPin
= uart
->rx
;
246 pins
->txPin
= IO_TAG(NONE
);
247 pins
->rxPin
= IO_TAG(NONE
);
251 void uartIrqHandler(uartPort_t
*s
)
253 UART_HandleTypeDef
*huart
= &s
->Handle
;
254 /* UART in mode Receiver ---------------------------------------------------*/
255 if ((__HAL_UART_GET_IT(huart
, UART_IT_RXNE
) != RESET
)) {
256 uint8_t rbyte
= (uint8_t)(huart
->Instance
->RDR
& (uint8_t) 0xff);
258 if (s
->port
.rxCallback
) {
259 s
->port
.rxCallback(rbyte
, s
->port
.rxCallbackData
);
261 s
->port
.rxBuffer
[s
->port
.rxBufferHead
] = rbyte
;
262 s
->port
.rxBufferHead
= (s
->port
.rxBufferHead
+ 1) % s
->port
.rxBufferSize
;
264 CLEAR_BIT(huart
->Instance
->CR1
, (USART_CR1_PEIE
));
266 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
267 CLEAR_BIT(huart
->Instance
->CR3
, USART_CR3_EIE
);
269 __HAL_UART_SEND_REQ(huart
, UART_RXDATA_FLUSH_REQUEST
);
272 /* UART parity error interrupt occurred -------------------------------------*/
273 if ((__HAL_UART_GET_IT(huart
, UART_IT_PE
) != RESET
)) {
274 __HAL_UART_CLEAR_IT(huart
, UART_CLEAR_PEF
);
277 /* UART frame error interrupt occurred --------------------------------------*/
278 if ((__HAL_UART_GET_IT(huart
, UART_IT_FE
) != RESET
)) {
279 __HAL_UART_CLEAR_IT(huart
, UART_CLEAR_FEF
);
282 /* UART noise error interrupt occurred --------------------------------------*/
283 if ((__HAL_UART_GET_IT(huart
, UART_IT_NE
) != RESET
)) {
284 __HAL_UART_CLEAR_IT(huart
, UART_CLEAR_NEF
);
287 /* UART Over-Run interrupt occurred -----------------------------------------*/
288 if ((__HAL_UART_GET_IT(huart
, UART_IT_ORE
) != RESET
)) {
289 __HAL_UART_CLEAR_IT(huart
, UART_CLEAR_OREF
);
292 /* UART in mode Transmitter ------------------------------------------------*/
293 if (__HAL_UART_GET_IT(huart
, UART_IT_TXE
) != RESET
) {
294 /* Check that a Tx process is ongoing */
295 if (huart
->gState
!= HAL_UART_STATE_BUSY_TX
) {
296 if (s
->port
.txBufferTail
== s
->port
.txBufferHead
) {
297 huart
->TxXferCount
= 0;
298 /* Disable the UART Transmit Data Register Empty Interrupt */
299 CLEAR_BIT(huart
->Instance
->CR1
, USART_CR1_TXEIE
);
301 if ((huart
->Init
.WordLength
== UART_WORDLENGTH_9B
) && (huart
->Init
.Parity
== UART_PARITY_NONE
)) {
302 huart
->Instance
->TDR
= (((uint16_t) s
->port
.txBuffer
[s
->port
.txBufferTail
]) & (uint16_t) 0x01FFU
);
304 huart
->Instance
->TDR
= (uint8_t)(s
->port
.txBuffer
[s
->port
.txBufferTail
]);
306 s
->port
.txBufferTail
= (s
->port
.txBufferTail
+ 1) % s
->port
.txBufferSize
;
311 /* UART in mode Transmitter (transmission end) -----------------------------*/
312 if ((__HAL_UART_GET_IT(huart
, UART_IT_TC
) != RESET
)) {
313 HAL_UART_IRQHandler(huart
);
317 uartPort_t
*serialUART(UARTDevice_e device
, uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
321 uartDevice_t
*uart
= uartHardwareMap
[device
];
322 if (!uart
) return NULL
;
325 s
->port
.vTable
= uartVTable
;
327 s
->port
.baudRate
= baudRate
;
329 s
->port
.rxBuffer
= uart
->rxBuffer
;
330 s
->port
.txBuffer
= uart
->txBuffer
;
331 s
->port
.rxBufferSize
= sizeof(uart
->rxBuffer
);
332 s
->port
.txBufferSize
= sizeof(uart
->txBuffer
);
334 s
->USARTx
= uart
->dev
;
336 s
->Handle
.Instance
= uart
->dev
;
339 RCC_ClockCmd(uart
->rcc
, ENABLE
);
342 IO_t tx
= IOGetByTag(uart
->tx
);
343 IO_t rx
= IOGetByTag(uart
->rx
);
345 if (options
& SERIAL_BIDIR
) {
346 IOInit(tx
, OWNER_SERIAL
, RESOURCE_UART_TXRX
, RESOURCE_INDEX(device
));
347 IOConfigGPIOAF(tx
, IOCFG_AF_PP
, uart
->af_tx
);
350 if (mode
& MODE_TX
) {
351 IOInit(tx
, OWNER_SERIAL
, RESOURCE_UART_TX
, RESOURCE_INDEX(device
));
352 IOConfigGPIOAF(tx
, IOCFG_AF_PP
, uart
->af_tx
);
355 if (mode
& MODE_RX
) {
356 IOInit(rx
, OWNER_SERIAL
, RESOURCE_UART_RX
, RESOURCE_INDEX(device
));
357 IOConfigGPIOAF(rx
, IOCFG_AF_PP
, uart
->af_rx
);
361 HAL_NVIC_SetPriority(uart
->irq
, NVIC_PRIO_SERIALUART
, 0);
362 HAL_NVIC_EnableIRQ(uart
->irq
);
368 uartPort_t
*serialUART1(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
370 return serialUART(UARTDEV_1
, baudRate
, mode
, options
);
373 // USART1 Rx/Tx IRQ Handler
374 void USART1_IRQHandler(void)
376 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_1
]->port
);
382 uartPort_t
*serialUART2(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
384 return serialUART(UARTDEV_2
, baudRate
, mode
, options
);
387 // USART2 Rx/Tx IRQ Handler
388 void USART2_IRQHandler(void)
390 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_2
]->port
);
396 uartPort_t
*serialUART3(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
398 return serialUART(UARTDEV_3
, baudRate
, mode
, options
);
401 // USART3 Rx/Tx IRQ Handler
402 void USART3_IRQHandler(void)
404 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_3
]->port
);
410 uartPort_t
*serialUART4(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
412 return serialUART(UARTDEV_4
, baudRate
, mode
, options
);
415 // UART4 Rx/Tx IRQ Handler
416 void UART4_IRQHandler(void)
418 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_4
]->port
);
424 uartPort_t
*serialUART5(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
426 return serialUART(UARTDEV_5
, baudRate
, mode
, options
);
429 // UART5 Rx/Tx IRQ Handler
430 void UART5_IRQHandler(void)
432 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_5
]->port
);
438 uartPort_t
*serialUART6(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
440 return serialUART(UARTDEV_6
, baudRate
, mode
, options
);
443 // USART6 Rx/Tx IRQ Handler
444 void USART6_IRQHandler(void)
446 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_6
]->port
);
452 uartPort_t
*serialUART7(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
454 return serialUART(UARTDEV_7
, baudRate
, mode
, options
);
457 // UART7 Rx/Tx IRQ Handler
458 void UART7_IRQHandler(void)
460 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_7
]->port
);
466 uartPort_t
*serialUART8(uint32_t baudRate
, portMode_t mode
, portOptions_t options
)
468 return serialUART(UARTDEV_8
, baudRate
, mode
, options
);
471 // UART8 Rx/Tx IRQ Handler
472 void UART8_IRQHandler(void)
474 uartPort_t
*s
= &(uartHardwareMap
[UARTDEV_8
]->port
);