From 31bd403446961b89d98e0e5577f2c46e9f83e0a1 Mon Sep 17 00:00:00 2001 From: Jay Blackman Date: Sat, 28 Dec 2024 16:55:15 +1100 Subject: [PATCH] Adding support for UART0 (#14094) --- src/main/cli/cli.c | 54 ++++++++++++++++++++++------------ src/main/drivers/serial_pinconfig.c | 3 ++ src/main/drivers/serial_tcp.c | 20 +++++++++---- src/main/drivers/serial_uart.c | 7 +++++ src/main/drivers/serial_uart_impl.h | 7 +++++ src/main/io/displayport_msp.c | 3 +- src/main/io/serial.c | 17 +++++++++-- src/main/io/serial.h | 25 +++++++++------- src/main/io/serial_resource.c | 5 ++-- src/main/msp/msp.c | 2 -- src/main/pg/serial_uart.c | 3 ++ src/main/target/common_defaults_post.h | 9 ++++++ src/test/unit/cli_unittest.cc | 21 ++++++++++--- 13 files changed, 129 insertions(+), 47 deletions(-) diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 46e2f9e32..a174fe8cf 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -210,6 +210,7 @@ static bool signatureUpdated = false; #endif // USE_BOARD_INFO static const char* const emptyName = "-"; +static const char* const invalidName = "INVALID"; #define MAX_CHANGESET_ID_LENGTH 8 #define MAX_DATE_LENGTH 20 @@ -1275,7 +1276,7 @@ static void cliAux(const char *cmdName, char *cmdline) static void printSerial(dumpFlags_t dumpMask, const serialConfig_t *serialConfig, const serialConfig_t *serialConfigDefault, const char *headingStr) { - const char *format = "serial %d %d %ld %ld %ld %ld"; + const char *format = "serial %s %d %ld %ld %ld %ld"; headingStr = cliPrintSectionHeading(dumpMask, false, headingStr); for (unsigned i = 0; i < ARRAYLEN(serialConfig->portConfigs); i++) { if (!serialIsPortAvailable(serialConfig->portConfigs[i].identifier)) { @@ -1286,7 +1287,7 @@ static void printSerial(dumpFlags_t dumpMask, const serialConfig_t *serialConfig equalsDefault = !memcmp(&serialConfig->portConfigs[i], &serialConfigDefault->portConfigs[i], sizeof(serialConfig->portConfigs[i])); headingStr = cliPrintSectionHeading(dumpMask, !equalsDefault, headingStr); cliDefaultPrintLinef(dumpMask, equalsDefault, format, - serialConfigDefault->portConfigs[i].identifier, + serialName(serialConfigDefault->portConfigs[i].identifier, invalidName), serialConfigDefault->portConfigs[i].functionMask, baudRates[serialConfigDefault->portConfigs[i].msp_baudrateIndex], baudRates[serialConfigDefault->portConfigs[i].gps_baudrateIndex], @@ -1295,7 +1296,7 @@ static void printSerial(dumpFlags_t dumpMask, const serialConfig_t *serialConfig ); } cliDumpPrintLinef(dumpMask, equalsDefault, format, - serialConfig->portConfigs[i].identifier, + serialName(serialConfig->portConfigs[i].identifier, invalidName), serialConfig->portConfigs[i].functionMask, baudRates[serialConfig->portConfigs[i].msp_baudrateIndex], baudRates[serialConfig->portConfigs[i].gps_baudrateIndex], @@ -1307,40 +1308,58 @@ static void printSerial(dumpFlags_t dumpMask, const serialConfig_t *serialConfig static void cliSerial(const char *cmdName, char *cmdline) { - const char *format = "serial %d %d %ld %ld %ld %ld"; + const char *format = "serial %s %d %ld %ld %ld %ld"; if (isEmpty(cmdline)) { printSerial(DUMP_MASTER, serialConfig(), NULL, NULL); return; } + serialPortConfig_t portConfig; memset(&portConfig, 0 , sizeof(portConfig)); uint8_t validArgumentCount = 0; - const char *ptr = cmdline; + char *ptr = cmdline; + char *tok = strsep(&ptr, " "); + serialPortIdentifier_e identifier = findSerialPortByName(tok, strcasecmp); + if (identifier == SERIAL_PORT_NONE) { + char *eptr; + identifier = strtoul(tok, &eptr, 10); + if (*eptr) { + // parsing ended before end of token indicating an invalid identifier + identifier = SERIAL_PORT_NONE; + } else { + // correction for legacy configuration where UART1 == 0 + if (identifier >= SERIAL_PORT_LEGACY_START_IDENTIFIER && identifier < SERIAL_PORT_START_IDENTIFIER) { + identifier += SERIAL_PORT_UART1; + } + } + } - int val = atoi(ptr++); - serialPortConfig_t *currentConfig = serialFindPortConfigurationMutable(val); + serialPortConfig_t *currentConfig = serialFindPortConfigurationMutable(identifier); - if (currentConfig) { - portConfig.identifier = val; - validArgumentCount++; + if (!currentConfig) { + cliShowParseError(cmdName); + return; } - ptr = nextArg(ptr); - if (ptr) { - val = strtoul(ptr, NULL, 10); + portConfig.identifier = identifier; + validArgumentCount++; + + tok = strsep(&ptr, " "); + if (tok) { + int val = strtoul(tok, NULL, 10); portConfig.functionMask = val; validArgumentCount++; } for (int i = 0; i < 4; i ++) { - ptr = nextArg(ptr); - if (!ptr) { + tok = strsep(&ptr, " "); + if (!tok) { break; } - val = atoi(ptr); + int val = atoi(tok); uint8_t baudRateIndex = lookupBaudRateIndex(val); if (baudRates[baudRateIndex] != (uint32_t) val) { @@ -1385,14 +1404,13 @@ static void cliSerial(const char *cmdName, char *cmdline) memcpy(currentConfig, &portConfig, sizeof(portConfig)); cliDumpPrintLinef(0, false, format, - portConfig.identifier, + serialName(portConfig.identifier, invalidName), portConfig.functionMask, baudRates[portConfig.msp_baudrateIndex], baudRates[portConfig.gps_baudrateIndex], baudRates[portConfig.telemetry_baudrateIndex], baudRates[portConfig.blackbox_baudrateIndex] ); - } #if defined(USE_SERIAL_PASSTHROUGH) diff --git a/src/main/drivers/serial_pinconfig.c b/src/main/drivers/serial_pinconfig.c index 71a1bf57e..d72c8dbbf 100644 --- a/src/main/drivers/serial_pinconfig.c +++ b/src/main/drivers/serial_pinconfig.c @@ -40,6 +40,9 @@ typedef struct serialDefaultPin_s { } serialDefaultPin_t; static const serialDefaultPin_t serialDefaultPin[] = { +#ifdef USE_UART0 + { SERIAL_PORT_UART0, IO_TAG(UART0_RX_PIN), IO_TAG(UART0_TX_PIN), IO_TAG(INVERTER_PIN_UART0) }, +#endif #ifdef USE_UART1 { SERIAL_PORT_USART1, IO_TAG(UART1_RX_PIN), IO_TAG(UART1_TX_PIN), IO_TAG(INVERTER_PIN_UART1) }, #endif diff --git a/src/main/drivers/serial_tcp.c b/src/main/drivers/serial_tcp.c index 6ffa2e386..bc6f6d37f 100644 --- a/src/main/drivers/serial_tcp.c +++ b/src/main/drivers/serial_tcp.c @@ -44,15 +44,18 @@ static const struct serialPortVTable tcpVTable; // Forward static tcpPort_t tcpSerialPorts[SERIAL_PORT_COUNT]; static bool tcpPortInitialized[SERIAL_PORT_COUNT]; static bool tcpStart = false; + bool tcpIsStart(void) { return tcpStart; } + static void onData(dyad_Event *e) { tcpPort_t* s = (tcpPort_t*)(e->udata); tcpDataIn(s, (uint8_t*)e->data, e->size); } + static void onClose(dyad_Event *e) { tcpPort_t* s = (tcpPort_t*)(e->udata); @@ -63,6 +66,7 @@ static void onClose(dyad_Event *e) s->connected = false; } } + static void onAccept(dyad_Event *e) { tcpPort_t* s = (tcpPort_t*)(e->udata); @@ -81,6 +85,7 @@ static void onAccept(dyad_Event *e) dyad_addListener(e->remote, DYAD_EVENT_DATA, onData, e->udata); dyad_addListener(e->remote, DYAD_EVENT_CLOSE, onClose, e->udata); } + static tcpPort_t* tcpReconfigure(tcpPort_t *s, int id) { if (tcpPortInitialized[id]) { @@ -93,6 +98,7 @@ static tcpPort_t* tcpReconfigure(tcpPort_t *s, int id) // TODO: clean up & re-init return NULL; } + if (pthread_mutex_init(&s->rxLock, NULL) != 0) { fprintf(stderr, "RX mutex init failed - %d\n", errno); // TODO: clean up & re-init @@ -118,17 +124,19 @@ static tcpPort_t* tcpReconfigure(tcpPort_t *s, int id) return s; } -serialPort_t *serTcpOpen(int id, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baudRate, portMode_e mode, portOptions_e options) +serialPort_t *serTcpOpen(serialPortIdentifier_e identifier, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baudRate, portMode_e mode, portOptions_e options) { tcpPort_t *s = NULL; -#if defined(USE_UART1) || defined(USE_UART2) || defined(USE_UART3) || defined(USE_UART4) || defined(USE_UART5) || defined(USE_UART6) || defined(USE_UART7) || defined(USE_UART8) - if (id >= 0 && id < SERIAL_PORT_COUNT) { - s = tcpReconfigure(&tcpSerialPorts[id], id); + int id = findSerialPortIndexByIdentifier(identifier); + + if (id >= 0 && id < (int)ARRAYLEN(tcpSerialPorts)) { + s = tcpReconfigure(&tcpSerialPorts[id], id); } -#endif - if (!s) + + if (!s) { return NULL; + } s->port.vTable = &tcpVTable; diff --git a/src/main/drivers/serial_uart.c b/src/main/drivers/serial_uart.c index 24bfb66c8..d4c530d88 100644 --- a/src/main/drivers/serial_uart.c +++ b/src/main/drivers/serial_uart.c @@ -71,6 +71,10 @@ UART_BUFFER(UART_RX_BUFFER_ATTRIBUTE, n, R); struct dummy_s \ /**/ +#ifdef USE_UART0 +UART_BUFFERS(0); +#endif + #ifdef USE_UART1 UART_BUFFERS(1); #endif @@ -136,6 +140,9 @@ uartDeviceIdx_e uartDeviceIdxFromIdentifier(serialPortIdentifier_e identifier) // table is for UART only to save space (LPUART is handled separately) #define _R(id, dev) [id] = (dev) + 1 static const uartDeviceIdx_e uartMap[] = { +#ifdef USE_UART0 + _R(SERIAL_PORT_UART0, UARTDEV_0), +#endif #ifdef USE_UART1 _R(SERIAL_PORT_USART1, UARTDEV_1), #endif diff --git a/src/main/drivers/serial_uart_impl.h b/src/main/drivers/serial_uart_impl.h index e6b15d27a..94b679e50 100644 --- a/src/main/drivers/serial_uart_impl.h +++ b/src/main/drivers/serial_uart_impl.h @@ -132,6 +132,9 @@ // compressed index of UART/LPUART. Direct index into uartDevice[] typedef enum { UARTDEV_INVALID = -1, +#ifdef USE_UART0 + UARTDEV_0, +#endif #ifdef USE_UART1 UARTDEV_1, #endif @@ -285,6 +288,10 @@ void uartTxMonitor(uartPort_t *s); UART_BUFFER(extern, n, T); struct dummy_s \ /**/ +#ifdef USE_UART0 +UART_BUFFERS_EXTERN(0); +#endif + #ifdef USE_UART1 UART_BUFFERS_EXTERN(1); #endif diff --git a/src/main/io/displayport_msp.c b/src/main/io/displayport_msp.c index 3e7ea3889..08f46491e 100644 --- a/src/main/io/displayport_msp.c +++ b/src/main/io/displayport_msp.c @@ -220,7 +220,8 @@ displayPort_t *displayPortMspInit(void) return &mspDisplayPort; } -void displayPortMspSetSerial(serialPortIdentifier_e serialPort) { +void displayPortMspSetSerial(serialPortIdentifier_e serialPort) +{ displayPortSerial = serialPort; } diff --git a/src/main/io/serial.c b/src/main/io/serial.c index 325d6ec15..a97d8260a 100644 --- a/src/main/io/serial.c +++ b/src/main/io/serial.c @@ -70,6 +70,9 @@ const serialPortIdentifier_e serialPortIdentifiers[SERIAL_PORT_COUNT] = { #ifdef USE_VCP SERIAL_PORT_USB_VCP, #endif +#ifdef USE_UART0 + SERIAL_PORT_UART0, +#endif #ifdef USE_UART1 SERIAL_PORT_USART1, #endif @@ -115,6 +118,9 @@ const char* serialPortNames[SERIAL_PORT_COUNT] = { #ifdef USE_VCP "VCP", #endif +#ifdef USE_UART0 + "UART0", +#endif #ifdef USE_UART1 "UART1", #endif @@ -156,17 +162,24 @@ const char* serialPortNames[SERIAL_PORT_COUNT] = { #endif }; -const uint32_t baudRates[] = {0, 9600, 19200, 38400, 57600, 115200, 230400, 250000, - 400000, 460800, 500000, 921600, 1000000, 1500000, 2000000, 2470000}; // see baudRate_e +const uint32_t baudRates[BAUD_COUNT] = { + 0, 9600, 19200, 38400, 57600, 115200, 230400, 250000, + 400000, 460800, 500000, 921600, 1000000, 1500000, 2000000, 2470000 +}; // see baudRate_e static serialPortConfig_t* findInPortConfigs_identifier(const serialPortConfig_t cfgs[], size_t count, serialPortIdentifier_e identifier) { + if (identifier == SERIAL_PORT_NONE || identifier == SERIAL_PORT_ALL) { + return NULL; + } + for (unsigned i = 0; i < count; i++) { if (cfgs[i].identifier == identifier) { // drop const on return - wrapper function will add it back if necessary return (serialPortConfig_t*)&cfgs[i]; } } + return NULL; } diff --git a/src/main/io/serial.h b/src/main/io/serial.h index af10830fa..4943597ea 100644 --- a/src/main/io/serial.h +++ b/src/main/io/serial.h @@ -77,18 +77,29 @@ typedef enum { BAUD_COUNT } baudRate_e; -extern const uint32_t baudRates[]; +extern const uint32_t baudRates[BAUD_COUNT]; // serial port identifiers are now fixed, these values are used by MSP commands. typedef enum { SERIAL_PORT_ALL = -2, SERIAL_PORT_NONE = -1, - // prepare for transition to SERIAL_PORT_UART0 - SERIAL_PORT_UART_FIRST = 0, + SERIAL_PORT_LEGACY_START_IDENTIFIER = 0, + SERIAL_PORT_START_IDENTIFIER = 20, + SERIAL_PORT_USB_VCP = 20, + + SERIAL_PORT_SOFTSERIAL_FIRST = 30, + SERIAL_PORT_SOFTSERIAL1 = SERIAL_PORT_SOFTSERIAL_FIRST, + SERIAL_PORT_SOFTSERIAL2, + + SERIAL_PORT_LPUART_FIRST = 40, + SERIAL_PORT_LPUART1 = SERIAL_PORT_LPUART_FIRST, + #if SERIAL_UART_FIRST_INDEX == 0 + SERIAL_PORT_UART_FIRST = 50, SERIAL_PORT_UART0 = SERIAL_PORT_UART_FIRST, SERIAL_PORT_USART1, #else + SERIAL_PORT_UART_FIRST = 51, SERIAL_PORT_USART1 = SERIAL_PORT_UART_FIRST, #endif SERIAL_PORT_UART1 = SERIAL_PORT_USART1, @@ -108,14 +119,6 @@ typedef enum { SERIAL_PORT_USART10, SERIAL_PORT_UART10 = SERIAL_PORT_USART10, - SERIAL_PORT_USB_VCP = 20, - - SERIAL_PORT_SOFTSERIAL_FIRST = 30, - SERIAL_PORT_SOFTSERIAL1 = SERIAL_PORT_SOFTSERIAL_FIRST, - SERIAL_PORT_SOFTSERIAL2, - - SERIAL_PORT_LPUART_FIRST = 40, - SERIAL_PORT_LPUART1 = SERIAL_PORT_LPUART_FIRST, } serialPortIdentifier_e; // use value from target serial port normalization diff --git a/src/main/io/serial_resource.c b/src/main/io/serial_resource.c index 962e0d7d2..878968d0b 100644 --- a/src/main/io/serial_resource.c +++ b/src/main/io/serial_resource.c @@ -60,9 +60,8 @@ serialType_e serialType(serialPortIdentifier_e identifier) } #endif #ifdef USE_SOFTSERIAL - if (identifier >= SERIAL_PORT_SOFTSERIAL_FIRST - && identifier < SERIAL_PORT_SOFTSERIAL_FIRST + SERIAL_SOFTSERIAL_MAX) { - // sotserials always start from first index, without holes + if (identifier >= SERIAL_PORT_SOFTSERIAL_FIRST && identifier < SERIAL_PORT_SOFTSERIAL_FIRST + SERIAL_SOFTSERIAL_MAX) { + // sotserials always start from 1, without holes return SERIALTYPE_SOFTSERIAL; } #endif diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c index 31ff012e6..f41866de0 100644 --- a/src/main/msp/msp.c +++ b/src/main/msp/msp.c @@ -3889,7 +3889,6 @@ static mspResult_e mspProcessInCommand(mspDescriptor_t srcDesc, int16_t cmdMSP, return MSP_RESULT_ERROR; } - portConfig->identifier = identifier; portConfig->functionMask = sbufReadU16(src); portConfig->msp_baudrateIndex = sbufReadU8(src); portConfig->gps_baudrateIndex = sbufReadU8(src); @@ -3917,7 +3916,6 @@ static mspResult_e mspProcessInCommand(mspDescriptor_t srcDesc, int16_t cmdMSP, return MSP_RESULT_ERROR; } - portConfig->identifier = identifier; portConfig->functionMask = sbufReadU32(src); portConfig->msp_baudrateIndex = sbufReadU8(src); portConfig->gps_baudrateIndex = sbufReadU8(src); diff --git a/src/main/pg/serial_uart.c b/src/main/pg/serial_uart.c index 355d28170..3bec1a380 100644 --- a/src/main/pg/serial_uart.c +++ b/src/main/pg/serial_uart.c @@ -46,6 +46,9 @@ typedef struct uartDmaopt_s { } uartDmaopt_t; static const uartDmaopt_t uartDmaopt[] = { +#ifdef USE_UART0 + { SERIAL_PORT_UART0, UART0_TX_DMA_OPT, UART0_RX_DMA_OPT }, +#endif #ifdef USE_UART1 { SERIAL_PORT_USART1, UART1_TX_DMA_OPT, UART1_RX_DMA_OPT }, #endif diff --git a/src/main/target/common_defaults_post.h b/src/main/target/common_defaults_post.h index 18ac19fd5..820eba067 100644 --- a/src/main/target/common_defaults_post.h +++ b/src/main/target/common_defaults_post.h @@ -211,6 +211,15 @@ #endif #endif +#ifdef USE_UART0 +#ifndef UART0_TX_DMA_OPT +#define UART0_TX_DMA_OPT (DMA_OPT_UNUSED) +#endif +#ifndef UART0_RX_DMA_OPT +#define UART0_RX_DMA_OPT (DMA_OPT_UNUSED) +#endif +#endif + #ifdef USE_UART1 #ifndef UART1_TX_DMA_OPT #define UART1_TX_DMA_OPT (DMA_OPT_UNUSED) diff --git a/src/test/unit/cli_unittest.cc b/src/test/unit/cli_unittest.cc index 63362e630..c756929c8 100644 --- a/src/test/unit/cli_unittest.cc +++ b/src/test/unit/cli_unittest.cc @@ -63,7 +63,7 @@ extern "C" { void cliSet(const char *cmdName, char *cmdline); int cliGetSettingIndex(char *name, uint8_t length); void *cliGetValuePointer(const clivalue_t *value); - + const clivalue_t valueTable[] = { { .name = "array_unit_test", .type = VAR_INT8 | MODE_ARRAY | MASTER_VALUE, .config = { .array = { .length = 3}}, .pgn = PG_RESERVED_FOR_TESTING_1, .offset = 0 }, { .name = "str_unit_test", .type = VAR_UINT8 | MODE_STRING | MASTER_VALUE, .config = { .string = { 0, 16, 0 }}, .pgn = PG_RESERVED_FOR_TESTING_1, .offset = 0 }, @@ -132,7 +132,7 @@ TEST(CLIUnittest, TestCliSetArray) TEST(CLIUnittest, TestCliSetStringNoFlags) { - char *str = (char *)"str_unit_test = SAMPLE"; + char *str = (char *)"str_unit_test = SAMPLE"; cliSet("", str); const uint16_t index = cliGetSettingIndex(str, 13); @@ -160,8 +160,8 @@ TEST(CLIUnittest, TestCliSetStringNoFlags) TEST(CLIUnittest, TestCliSetStringWriteOnce) { - char *str1 = (char *)"wos_unit_test = SAMPLE"; - char *str2 = (char *)"wos_unit_test = ELPMAS"; + char *str1 = (char *)"wos_unit_test = SAMPLE"; + char *str2 = (char *)"wos_unit_test = ELPMAS"; cliSet("", str1); const uint16_t index = cliGetSettingIndex(str1, 13); @@ -370,6 +370,19 @@ void generateLedConfig(ledConfig_t *, char *, size_t) {} void serialSetCtrlLineStateDtrPin(serialPort_t *, ioTag_t ) {} void serialSetCtrlLineState(serialPort_t *, uint16_t ) {} +serialPortIdentifier_e findSerialPortByName(const char* portName, int (*cmp)(const char *portName, const char *candidate)) +{ + UNUSED(portName); + UNUSED(cmp); + return SERIAL_PORT_NONE; +} + +const char* serialName(serialPortIdentifier_e identifier, const char* notFound) +{ + UNUSED(identifier); + return notFound; +} + //void serialSetBaudRateCb(serialPort_t *, void (*)(serialPort_t *context, uint32_t baud), serialPort_t *) {} void rescheduleTask(taskId_e, timeDelta_t){} void schedulerSetNextStateTime(timeDelta_t ){} -- 2.11.4.GIT