Merge pull request #10558 from iNavFlight/MrD_Correct-comments-on-OSD-symbols
[inav.git] / src / main / drivers / serial_uart_hal_at32f43x.c
blobf30726332f4236041397c27798971d0ef5e819ba
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/>.
19 * Authors:
20 * Dominic Clifton - Serial port abstraction, Separation of common STM32 code for cleanflight, various cleanups.
21 * Hamasaki/Timecop - Initial baseflight code
23 #include <stdbool.h>
24 #include <stdint.h>
26 #include "platform.h"
28 #include "build/build_config.h"
30 #include "common/utils.h"
32 #include "drivers/uart_inverter.h"
34 #include "serial.h"
35 #include "serial_uart.h"
36 #include "serial_uart_impl.h"
38 static void usartConfigurePinInversion(uartPort_t *uartPort) {
39 #if !defined(USE_UART_INVERTER)
40 UNUSED(uartPort);
41 #else
42 bool inverted = uartPort->port.options & SERIAL_INVERTED;
44 #ifdef USE_UART_INVERTER
45 uartInverterLine_e invertedLines = UART_INVERTER_LINE_NONE;
46 if (uartPort->port.mode & MODE_RX) {
47 invertedLines |= UART_INVERTER_LINE_RX;
49 if (uartPort->port.mode & MODE_TX) {
50 invertedLines |= UART_INVERTER_LINE_TX;
52 uartInverterSet(uartPort->USARTx, invertedLines, inverted);
53 #endif
55 #endif
58 static void uartReconfigure(uartPort_t *uartPort)
60 usart_enable(uartPort->USARTx, FALSE);
61 uint32_t baud_rate = 115200;
62 usart_data_bit_num_type data_bit = USART_DATA_8BITS;
63 usart_stop_bit_num_type stop_bit = USART_STOP_1_BIT;
64 usart_parity_selection_type parity_type = USART_PARITY_EVEN;
66 baud_rate = uartPort->port.baudRate;
67 stop_bit = (uartPort->port.options & SERIAL_STOPBITS_2) ? USART_STOP_2_BIT : USART_STOP_1_BIT;
69 // according to the stm32 documentation wordlen has to be 9 for parity bits
70 // this does not seem to matter for rx but will give bad data on tx!
71 if (uartPort->port.options & SERIAL_PARITY_EVEN) {
72 data_bit = USART_DATA_9BITS;
73 } else {
74 data_bit = USART_DATA_8BITS;
76 usart_init(uartPort->USARTx, baud_rate, data_bit, stop_bit);
78 parity_type = (uartPort->port.options & SERIAL_PARITY_EVEN) ? USART_PARITY_EVEN : USART_PARITY_NONE;
79 usart_parity_selection_config(uartPort->USARTx, parity_type);
80 usart_hardware_flow_control_set (uartPort->USARTx, USART_HARDWARE_FLOW_NONE);
82 if (uartPort->port.mode & MODE_RX)
83 usart_receiver_enable(uartPort->USARTx, TRUE);
84 if (uartPort->port.mode & MODE_TX)
85 usart_transmitter_enable(uartPort->USARTx, TRUE);
87 usartConfigurePinInversion(uartPort);
88 uartConfigurePinSwap(uartPort);
90 if (uartPort->port.options & SERIAL_BIDIR)
91 usart_single_line_halfduplex_select(uartPort->USARTx, TRUE);
92 else
93 usart_single_line_halfduplex_select(uartPort->USARTx, FALSE);
95 usart_enable(uartPort->USARTx, TRUE);
98 serialPort_t *uartOpen(usart_type *USARTx, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baudRate, portMode_t mode, portOptions_t options)
100 uartPort_t *s = NULL;
102 if (false) {
103 #ifdef USE_UART1
104 } else if (USARTx == USART1) {
105 s = serialUART1(baudRate, mode, options);
107 #endif
108 #ifdef USE_UART2
109 } else if (USARTx == USART2) {
110 s = serialUART2(baudRate, mode, options);
111 #endif
112 #ifdef USE_UART3
113 } else if (USARTx == USART3) {
114 s = serialUART3(baudRate, mode, options);
115 #endif
116 #ifdef USE_UART4
117 } else if (USARTx == UART4) {
118 s = serialUART4(baudRate, mode, options);
119 #endif
120 #ifdef USE_UART5
121 } else if (USARTx == UART5) {
122 s = serialUART5(baudRate, mode, options);
123 #endif
124 #ifdef USE_UART6
125 } else if (USARTx == USART6) {
126 s = serialUART6(baudRate, mode, options);
127 #endif
128 #ifdef USE_UART7
129 } else if (USARTx == UART7) {
130 s = serialUART7(baudRate, mode, options);
131 #endif
132 #ifdef USE_UART8
133 } else if (USARTx == UART8) {
134 s = serialUART8(baudRate, mode, options);
135 #endif
137 } else {
138 return (serialPort_t *)s;
141 // common serial initialisation code should move to serialPort::init()
142 s->port.rxBufferHead = s->port.rxBufferTail = 0;
143 s->port.txBufferHead = s->port.txBufferTail = 0;
144 // callback works for IRQ-based RX ONLY
145 s->port.rxCallback = rxCallback;
146 s->port.rxCallbackData = rxCallbackData;
147 s->port.mode = mode;
148 s->port.baudRate = baudRate;
149 s->port.options = options;
151 uartReconfigure(s);
153 if (mode & MODE_RX) {
154 usart_flag_clear(s->USARTx, USART_RDBF_FLAG);
155 usart_interrupt_enable (s->USARTx, USART_RDBF_INT, TRUE);
159 if (mode & MODE_TX) {
160 usart_interrupt_enable (s->USARTx, USART_TDBE_INT, TRUE);
163 usart_enable(s->USARTx, TRUE);
165 return (serialPort_t *)s;
168 void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate)
170 uartPort_t *uartPort = (uartPort_t *)instance;
171 uartPort->port.baudRate = baudRate;
172 uartReconfigure(uartPort);
175 void uartSetMode(serialPort_t *instance, portMode_t mode)
177 uartPort_t *uartPort = (uartPort_t *)instance;
178 uartPort->port.mode = mode;
179 uartReconfigure(uartPort);
182 void uartSetOptions(serialPort_t *instance, portOptions_t options)
184 uartPort_t *uartPort = (uartPort_t *)instance;
185 uartPort->port.options = options;
186 uartReconfigure(uartPort);
189 uint32_t uartTotalRxBytesWaiting(const serialPort_t *instance)
191 const uartPort_t *s = (const uartPort_t*)instance;
193 if (s->port.rxBufferHead >= s->port.rxBufferTail) {
194 return s->port.rxBufferHead - s->port.rxBufferTail;
195 } else {
196 return s->port.rxBufferSize + s->port.rxBufferHead - s->port.rxBufferTail;
200 uint32_t uartTotalTxBytesFree(const serialPort_t *instance)
202 const uartPort_t *s = (const uartPort_t*)instance;
204 uint32_t bytesUsed;
206 if (s->port.txBufferHead >= s->port.txBufferTail) {
207 bytesUsed = s->port.txBufferHead - s->port.txBufferTail;
208 } else {
209 bytesUsed = s->port.txBufferSize + s->port.txBufferHead - s->port.txBufferTail;
212 return (s->port.txBufferSize - 1) - bytesUsed;
215 bool isUartTransmitBufferEmpty(const serialPort_t *instance)
217 const uartPort_t *s = (const uartPort_t *)instance;
218 return s->port.txBufferTail == s->port.txBufferHead;
221 uint8_t uartRead(serialPort_t *instance)
223 uint8_t ch;
224 uartPort_t *s = (uartPort_t *)instance;
226 ch = s->port.rxBuffer[s->port.rxBufferTail];
227 if (s->port.rxBufferTail + 1 >= s->port.rxBufferSize) {
228 s->port.rxBufferTail = 0;
229 } else {
230 s->port.rxBufferTail++;
233 return ch;
236 void uartWrite(serialPort_t *instance, uint8_t ch)
238 uartPort_t *s = (uartPort_t *)instance;
239 s->port.txBuffer[s->port.txBufferHead] = ch;
240 if (s->port.txBufferHead + 1 >= s->port.txBufferSize) {
241 s->port.txBufferHead = 0;
242 } else {
243 s->port.txBufferHead++;
246 usart_interrupt_enable (s->USARTx, USART_TDBE_INT, TRUE);
250 bool isUartIdle(serialPort_t *instance)
252 uartPort_t *s = (uartPort_t *)instance;
253 if(usart_flag_get(s->USARTx, USART_IDLEF_FLAG)) {
255 uartClearIdleFlag(s);
256 return true;
257 } else {
258 return false;
262 const struct serialPortVTable uartVTable[] = {
264 .serialWrite = uartWrite,
265 .serialTotalRxWaiting = uartTotalRxBytesWaiting,
266 .serialTotalTxFree = uartTotalTxBytesFree,
267 .serialRead = uartRead,
268 .serialSetBaudRate = uartSetBaudRate,
269 .isSerialTransmitBufferEmpty = isUartTransmitBufferEmpty,
270 .setMode = uartSetMode,
271 .setOptions = uartSetOptions,
272 .isConnected = NULL,
273 .writeBuf = NULL,
274 .beginWrite = NULL,
275 .endWrite = NULL,
276 .isIdle = isUartIdle,