Skip to content

Commit

Permalink
Merge pull request #10271 from MUSTARDTIGERFPV/serialpassthrough-modes
Browse files Browse the repository at this point in the history
Allow serialpassthrough to set parity & stop bits
  • Loading branch information
mmosca authored Aug 1, 2024
2 parents 265cd57 + 81bed95 commit 3cc11ce
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/Cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ While connected to the CLI, all Logical Switches are temporarily disabled (5.1.0
| `save` | Save and reboot |
| `sd_info` | Sdcard info |
| `serial` | Configure serial ports. [Usage](Serial.md) |
| `serialpassthrough` | Passthrough serial data to port, with `<id> <baud> <mode>`, where `id` is the zero based port index, `baud` is a standard baud rate, and mode is `rx`, `tx`, or both (`rxtx`) |
| `serialpassthrough` | Passthrough serial data to port, with `<id> <baud> <mode> <options>`, where `id` is the zero based port index, `baud` is a standard baud rate, mode is `rx`, `tx`, or both (`rxtx`), and options is a short string like `8N1` or `8E2` |
| `servo` | Configure servos |
| `set` | Change setting with name=value or blank or * for list |
| `smix` | Custom servo mixer |
Expand Down
5 changes: 5 additions & 0 deletions src/main/drivers/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ void serialSetMode(serialPort_t *instance, portMode_t mode)
instance->vTable->setMode(instance, mode);
}

void serialSetOptions(serialPort_t *instance, portOptions_t options)
{
instance->vTable->setOptions(instance, options);
}

void serialWriteBufShim(void *instance, const uint8_t *data, int count)
{
serialWriteBuf((serialPort_t *)instance, data, count);
Expand Down
3 changes: 3 additions & 0 deletions src/main/drivers/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ struct serialPortVTable {

void (*setMode)(serialPort_t *instance, portMode_t mode);

void (*setOptions)(serialPort_t *instance, portOptions_t options);

void (*writeBuf)(serialPort_t *instance, const void *data, int count);

bool (*isConnected)(const serialPort_t *instance);
Expand All @@ -113,6 +115,7 @@ void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count);
uint8_t serialRead(serialPort_t *instance);
void serialSetBaudRate(serialPort_t *instance, uint32_t baudRate);
void serialSetMode(serialPort_t *instance, portMode_t mode);
void serialSetOptions(serialPort_t *instance, portOptions_t options);
bool isSerialTransmitBufferEmpty(const serialPort_t *instance);
void serialPrint(serialPort_t *instance, const char *str);
uint32_t serialGetBaudRate(serialPort_t *instance);
Expand Down
6 changes: 6 additions & 0 deletions src/main/drivers/serial_softserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,11 @@ void softSerialSetMode(serialPort_t *instance, portMode_t mode)
instance->mode = mode;
}

void softSerialSetOptions(serialPort_t *instance, portOptions_t options)
{
instance->options = options;
}

bool isSoftSerialTransmitBufferEmpty(const serialPort_t *instance)
{
return instance->txBufferHead == instance->txBufferTail;
Expand All @@ -636,6 +641,7 @@ static const struct serialPortVTable softSerialVTable = {
.serialSetBaudRate = softSerialSetBaudRate,
.isSerialTransmitBufferEmpty = isSoftSerialTransmitBufferEmpty,
.setMode = softSerialSetMode,
.setOptions = softSerialSetOptions,
.isConnected = NULL,
.writeBuf = NULL,
.beginWrite = NULL,
Expand Down
7 changes: 7 additions & 0 deletions src/main/drivers/serial_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ void tcpSetMode(serialPort_t *instance, portMode_t mode)
UNUSED(mode);
}

void tcpSetOptions(serialPort_t *instance, portOptions_t options)
{
UNUSED(instance);
UNUSED(options);
}

static const struct serialPortVTable tcpVTable[] = {
{
.serialWrite = tcpWrite,
Expand All @@ -326,6 +332,7 @@ static const struct serialPortVTable tcpVTable[] = {
.serialSetBaudRate = tcpSetBaudRate,
.isSerialTransmitBufferEmpty = isTcpTransmitBufferEmpty,
.setMode = tcpSetMode,
.setOptions = tcpSetOptions,
.isConnected = tcpIsConnected,
.writeBuf = tcpWritBuf,
.beginWrite = NULL,
Expand Down
8 changes: 8 additions & 0 deletions src/main/drivers/serial_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ void uartSetMode(serialPort_t *instance, portMode_t mode)
uartReconfigure(uartPort);
}

void uartSetOptions(serialPort_t *instance, portOptions_t options)
{
uartPort_t *uartPort = (uartPort_t *)instance;
uartPort->port.options = options;
uartReconfigure(uartPort);
}

uint32_t uartTotalRxBytesWaiting(const serialPort_t *instance)
{
const uartPort_t *s = (const uartPort_t*)instance;
Expand Down Expand Up @@ -255,6 +262,7 @@ const struct serialPortVTable uartVTable[] = {
.serialSetBaudRate = uartSetBaudRate,
.isSerialTransmitBufferEmpty = isUartTransmitBufferEmpty,
.setMode = uartSetMode,
.setOptions = uartSetOptions,
.isConnected = NULL,
.writeBuf = NULL,
.beginWrite = NULL,
Expand Down
8 changes: 8 additions & 0 deletions src/main/drivers/serial_uart_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ void uartSetMode(serialPort_t *instance, portMode_t mode)
uartReconfigure(uartPort);
}

void uartSetOptions(serialPort_t *instance, portOptions_t options)
{
uartPort_t *uartPort = (uartPort_t *)instance;
uartPort->port.options = options;
uartReconfigure(uartPort);
}

uint32_t uartTotalRxBytesWaiting(const serialPort_t *instance)
{
uartPort_t *s = (uartPort_t*)instance;
Expand Down Expand Up @@ -266,6 +273,7 @@ const struct serialPortVTable uartVTable[] = {
.serialSetBaudRate = uartSetBaudRate,
.isSerialTransmitBufferEmpty = isUartTransmitBufferEmpty,
.setMode = uartSetMode,
.setOptions = uartSetOptions,
.isConnected = NULL,
.writeBuf = NULL,
.beginWrite = NULL,
Expand Down
8 changes: 8 additions & 0 deletions src/main/drivers/serial_uart_hal_at32f43x.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ void uartSetMode(serialPort_t *instance, portMode_t mode)
uartReconfigure(uartPort);
}

void uartSetOptions(serialPort_t *instance, portOptions_t options)
{
uartPort_t *uartPort = (uartPort_t *)instance;
uartPort->port.options = options;
uartReconfigure(uartPort);
}

uint32_t uartTotalRxBytesWaiting(const serialPort_t *instance)
{
const uartPort_t *s = (const uartPort_t*)instance;
Expand Down Expand Up @@ -260,6 +267,7 @@ const struct serialPortVTable uartVTable[] = {
.serialSetBaudRate = uartSetBaudRate,
.isSerialTransmitBufferEmpty = isUartTransmitBufferEmpty,
.setMode = uartSetMode,
.setOptions = uartSetOptions,
.isConnected = NULL,
.writeBuf = NULL,
.beginWrite = NULL,
Expand Down
9 changes: 9 additions & 0 deletions src/main/drivers/serial_usb_vcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ static void usbVcpSetMode(serialPort_t *instance, portMode_t mode)
// TODO implement
}

static void usbVcpSetOptions(serialPort_t *instance, portOptions_t options)
{
UNUSED(instance);
UNUSED(options);

// TODO implement
}

static bool isUsbVcpTransmitBufferEmpty(const serialPort_t *instance)
{
UNUSED(instance);
Expand Down Expand Up @@ -184,6 +192,7 @@ static const struct serialPortVTable usbVTable[] = {
.serialSetBaudRate = usbVcpSetBaudRate,
.isSerialTransmitBufferEmpty = isUsbVcpTransmitBufferEmpty,
.setMode = usbVcpSetMode,
.setOptions = usbVcpSetOptions,
.isConnected = usbVcpIsConnected,
.writeBuf = usbVcpWriteBuf,
.beginWrite = usbVcpBeginWrite,
Expand Down
7 changes: 7 additions & 0 deletions src/main/drivers/serial_usb_vcp_at32f43x.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ static void usbVcpSetMode(serialPort_t *instance, portMode_t mode)
UNUSED(mode);
}

static void usbVcpSetOptions(serialPort_t *instance, portOptions_t options)
{
UNUSED(instance);
UNUSED(options);
}

static bool isUsbVcpTransmitBufferEmpty(const serialPort_t *instance)
{
UNUSED(instance);
Expand Down Expand Up @@ -434,6 +440,7 @@ static const struct serialPortVTable usbVTable[] = {
.serialSetBaudRate = usbVcpSetBaudRate,
.isSerialTransmitBufferEmpty = isUsbVcpTransmitBufferEmpty,
.setMode = usbVcpSetMode,
.setOptions = usbVcpSetOptions,
.isConnected = usbVcpIsConnected,
.writeBuf = usbVcpWriteBuf,
.beginWrite = usbVcpBeginWrite,
Expand Down
49 changes: 47 additions & 2 deletions src/main/fc/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,42 @@ static void cliSerial(char *cmdline)
}

#ifdef USE_SERIAL_PASSTHROUGH

portOptions_t constructPortOptions(char *options) {
if (strlen(options) != 3 || options[0] != '8') {
// Invalid format
return -1;
}

portOptions_t result = 0;

switch (options[1]) {
case 'N':
result |= SERIAL_PARITY_NO;
break;
case 'E':
result |= SERIAL_PARITY_EVEN;
break;
default:
// Invalid format
return -1;
}

switch (options[2]) {
case '1':
result |= SERIAL_STOPBITS_1;
break;
case '2':
result |= SERIAL_STOPBITS_2;
break;
default:
// Invalid format
return -1;
}

return result;
}

static void cliSerialPassthrough(char *cmdline)
{
char * saveptr;
Expand All @@ -926,6 +962,7 @@ static void cliSerialPassthrough(char *cmdline)
int id = -1;
uint32_t baud = 0;
unsigned mode = 0;
portOptions_t options = SERIAL_NOT_INVERTED;
char* tok = strtok_r(cmdline, " ", &saveptr);
int index = 0;

Expand All @@ -943,6 +980,9 @@ static void cliSerialPassthrough(char *cmdline)
if (strstr(tok, "tx") || strstr(tok, "TX"))
mode |= MODE_TX;
break;
case 3:
options |= constructPortOptions(tok);
break;
}
index++;
tok = strtok_r(NULL, " ", &saveptr);
Expand All @@ -960,7 +1000,7 @@ static void cliSerialPassthrough(char *cmdline)

passThroughPort = openSerialPort(id, FUNCTION_NONE, NULL, NULL,
baud, mode,
SERIAL_NOT_INVERTED);
options);
if (!passThroughPort) {
tfp_printf("Port %d could not be opened.\r\n", id);
return;
Expand All @@ -976,6 +1016,11 @@ static void cliSerialPassthrough(char *cmdline)
passThroughPort->mode, mode);
serialSetMode(passThroughPort, mode);
}
if (options && passThroughPort->options != options) {
tfp_printf("Adjusting options from %d to %d.\r\n",
passThroughPort->options, options);
serialSetOptions(passThroughPort, options);
}
// If this port has a rx callback associated we need to remove it now.
// Otherwise no data will be pushed in the serial port buffer!
if (passThroughPort->rxCallback) {
Expand Down Expand Up @@ -4515,7 +4560,7 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("save", "save and reboot", NULL, cliSave),
CLI_COMMAND_DEF("serial", "configure serial ports", NULL, cliSerial),
#ifdef USE_SERIAL_PASSTHROUGH
CLI_COMMAND_DEF("serialpassthrough", "passthrough serial data to port", "<id> [baud] [mode] : passthrough to serial", cliSerialPassthrough),
CLI_COMMAND_DEF("serialpassthrough", "passthrough serial data to port", "<id> [baud] [mode] [options]: passthrough to serial", cliSerialPassthrough),
#endif
CLI_COMMAND_DEF("servo", "configure servos", NULL, cliServo),
#ifdef USE_PROGRAMMING_FRAMEWORK
Expand Down

0 comments on commit 3cc11ce

Please sign in to comment.