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/>.
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
];
43 rccPeriphTag_t rcc_apb2
;
44 rccPeriphTag_t rcc_apb1
;
51 static uartDevice_t uart1
=
54 .rx
= IO_TAG(UART1_RX_PIN
),
55 .tx
= IO_TAG(UART1_TX_PIN
),
57 .af
= UART_AF(USART1
, UART1_AF
),
59 .af
= GPIO_AF7_USART1
,
61 #ifdef UART1_AHB1_PERIPHERALS
62 .rcc_ahb1
= UART1_AHB1_PERIPHERALS
,
64 .rcc_apb2
= RCC_APB2(USART1
),
66 .irqPriority
= NVIC_PRIO_SERIALUART
71 static uartDevice_t uart2
=
74 .rx
= IO_TAG(UART2_RX_PIN
),
75 .tx
= IO_TAG(UART2_TX_PIN
),
77 .af
= UART_AF(USART2
, UART2_AF
),
79 .af
= GPIO_AF7_USART2
,
81 #ifdef UART2_AHB1_PERIPHERALS
82 .rcc_ahb1
= UART2_AHB1_PERIPHERALS
,
84 .rcc_apb1
= RCC_APB1(USART2
),
86 .irqPriority
= NVIC_PRIO_SERIALUART
91 static uartDevice_t uart3
=
94 .rx
= IO_TAG(UART3_RX_PIN
),
95 .tx
= IO_TAG(UART3_TX_PIN
),
97 .af
= UART_AF(USART3
, UART3_AF
),
99 .af
= GPIO_AF7_USART3
,
101 #ifdef UART3_AHB1_PERIPHERALS
102 .rcc_ahb1
= UART3_AHB1_PERIPHERALS
,
104 .rcc_apb1
= RCC_APB1(USART3
),
106 .irqPriority
= NVIC_PRIO_SERIALUART
111 static uartDevice_t uart4
=
114 .rx
= IO_TAG(UART4_RX_PIN
),
115 .tx
= IO_TAG(UART4_TX_PIN
),
117 .af
= UART_AF(UART4
, UART4_AF
),
119 .af
= GPIO_AF8_UART4
,
121 #ifdef UART4_AHB1_PERIPHERALS
122 .rcc_ahb1
= UART4_AHB1_PERIPHERALS
,
124 .rcc_apb1
= RCC_APB1(UART4
),
126 .irqPriority
= NVIC_PRIO_SERIALUART
131 static uartDevice_t uart5
=
134 .rx
= IO_TAG(UART5_RX_PIN
),
135 .tx
= IO_TAG(UART5_TX_PIN
),
137 .af
= UART_AF(UART5
, UART5_AF
),
139 .af
= GPIO_AF8_UART5
,
141 #ifdef UART5_AHB1_PERIPHERALS
142 .rcc_ahb1
= UART5_AHB1_PERIPHERALS
,
144 .rcc_apb1
= RCC_APB1(UART5
),
146 .irqPriority
= NVIC_PRIO_SERIALUART
151 static uartDevice_t uart6
=
154 .rx
= IO_TAG(UART6_RX_PIN
),
155 .tx
= IO_TAG(UART6_TX_PIN
),
157 .af
= UART_AF(USART6
, UART6_AF
),
159 .af
= GPIO_AF8_USART6
,
161 #ifdef UART6_AHB1_PERIPHERALS
162 .rcc_ahb1
= UART6_AHB1_PERIPHERALS
,
164 .rcc_apb2
= RCC_APB2(USART6
),
166 .irqPriority
= NVIC_PRIO_SERIALUART
171 static uartDevice_t uart7
=
174 .rx
= IO_TAG(UART7_RX_PIN
),
175 .tx
= IO_TAG(UART7_TX_PIN
),
177 .af
= UART_AF(UART7
, UART7_AF
),
179 .af
= GPIO_AF8_UART7
,
181 #ifdef UART7_AHB1_PERIPHERALS
182 .rcc_ahb1
= UART7_AHB1_PERIPHERALS
,
184 .rcc_apb1
= RCC_APB1(UART7
),
186 .irqPriority
= NVIC_PRIO_SERIALUART
190 static uartDevice_t uart8
=
193 .rx
= IO_TAG(UART8_RX_PIN
),
194 .tx
= IO_TAG(UART8_TX_PIN
),
196 .af
= UART_AF(UART8
, UART8_AF
),
198 .af
= GPIO_AF8_UART8
,
200 #ifdef UART8_AHB1_PERIPHERALS
201 .rcc_ahb1
= UART8_AHB1_PERIPHERALS
,
203 .rcc_apb1
= RCC_APB1(UART8
),
205 .irqPriority
= NVIC_PRIO_SERIALUART
211 static uartDevice_t
* uartHardwareMap
[] = {
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
);
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
);
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
);
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
];
325 pins
->txPin
= uart
->tx
;
326 pins
->rxPin
= uart
->rx
;
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
)
338 uartDevice_t
*uart
= uartHardwareMap
[device
];
339 if (!uart
) return NULL
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);