duplicate emptyline removal (#14027)
[betaflight.git] / src / main / io / serial_resource.c
blob33eb938bb93049fdd7ab7e781ba512a2b349f401
1 /*
2 * This file is part of Betaflight.
4 * Betaflight is free software. You can redistribute this software
5 * and/or modify this software under the terms of the GNU General
6 * Public License as published by the Free Software Foundation,
7 * either version 3 of the License, or (at your option) any later
8 * version.
10 * Betaflight is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this software.
19 * If not, see <http://www.gnu.org/licenses/>.
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <limits.h>
26 #include "platform.h"
28 #include "io/serial.h"
30 // convert identifier into port type
31 serialType_e serialType(serialPortIdentifier_e identifier)
33 #ifdef USE_VCP
34 if (identifier == SERIAL_PORT_USB_VCP) {
35 return SERIALTYPE_USB_VCP;
37 #endif
38 #ifdef USE_UART
39 if (identifier >= SERIAL_PORT_USART1 && identifier < SERIAL_PORT_USART1 + SERIAL_UART_MAX) {
40 const unsigned idx = identifier - SERIAL_PORT_USART1;
41 if (BIT(idx) & SERIAL_UART_MASK) {
42 return SERIALTYPE_UART;
43 } else {
44 // no other type in this range
45 return SERIALTYPE_INVALID;
48 #endif
49 #ifdef USE_LPUART
50 if (identifier >= SERIAL_PORT_LPUART1 && identifier < SERIAL_PORT_LPUART1 + SERIAL_LPUART_MAX) {
51 const unsigned idx = identifier - SERIAL_PORT_LPUART1;
52 if (BIT(idx) & SERIAL_LPUART_MASK) {
53 return SERIALTYPE_LPUART;
54 } else {
55 // no other type in this range
56 return SERIALTYPE_INVALID;
59 #endif
60 #ifdef USE_SOFTSERIAL
61 if (identifier >= SERIAL_PORT_SOFTSERIAL1 && identifier < SERIAL_PORT_SOFTSERIAL1 + SERIAL_SOFTSERIAL_MAX) {
62 // sotserials always start from 1, without holes
63 return SERIALTYPE_SOFTSERIAL;
65 #endif
66 return SERIALTYPE_INVALID;
69 static const struct SerialTypeInfo {
70 resourceOwner_e owner;
71 serialPortIdentifier_e firstId;
72 int8_t resourceOffset;
73 } serialTypeMap[] = {
74 [SERIALTYPE_USB_VCP] = { OWNER_FREE /* no owner*/, SERIAL_PORT_USB_VCP, -1 },
75 [SERIALTYPE_UART] = { OWNER_SERIAL_TX, SERIAL_PORT_USART1, RESOURCE_UART_OFFSET },
76 [SERIALTYPE_LPUART] = { OWNER_LPUART_TX, SERIAL_PORT_LPUART1, RESOURCE_LPUART_OFFSET },
77 [SERIALTYPE_SOFTSERIAL] = { OWNER_SOFTSERIAL_TX, SERIAL_PORT_SOFTSERIAL1, RESOURCE_SOFTSERIAL_OFFSET },
80 STATIC_ASSERT(ARRAYLEN(serialTypeMap) == SERIALTYPE_COUNT, "type table mismatch");
82 static const struct SerialTypeInfo* serialTypeInfo(serialPortIdentifier_e identifier)
84 const serialType_e type = serialType(identifier);
85 if (type == SERIALTYPE_INVALID) {
86 return NULL;
88 return serialTypeMap + type;
91 // resourceOwner_e for this serial (UART/LPUART/SOFTSERIAL/..)
92 // Used together with serialOwnerIndex to identify claimed resources
93 // Tx member is returned, Rx is always Tx + 1
94 // OWNER_FREE is returned for serials without owner (VCP)
95 resourceOwner_e serialOwnerTxRx(serialPortIdentifier_e identifier)
97 const struct SerialTypeInfo* inf = serialTypeInfo(identifier);
98 return inf ? inf->owner : OWNER_FREE;
101 // return index used to claim given resource. Returned value is 1 based, for IOInit and similar
102 // 0 is returned when given port is not defined or if it is singleton port (USB)
103 int serialOwnerIndex(serialPortIdentifier_e identifier)
105 const struct SerialTypeInfo* inf = serialTypeInfo(identifier);
106 if (!inf || inf->owner == OWNER_FREE) {
107 return 0;
109 return RESOURCE_INDEX(identifier - inf->firstId);
112 // map identifier into index used to store port resources:
113 // pins(RX,TX), external inversion, port DMA configuration
114 // order is UART, LPUART, SOFTSERIAL, with each group using index
115 // coresponding to port name (UART1 -> 0, UART5 -> 4, but LPUART -> 5 if
116 // there is no UART6 and higher on given target.
117 // -1 is returned if given port is not defined or is not using resources
118 // some code uses this ordering for optimizations, be carefull if reordering is necessary
119 int serialResourceIndex(serialPortIdentifier_e identifier)
121 const struct SerialTypeInfo* inf = serialTypeInfo(identifier);
122 if (!inf || inf->resourceOffset < 0) {
123 return -1;
125 return identifier - inf->firstId + inf->resourceOffset;