mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-14 11:59:58 +03:00
add left side choosable for passthrough
This commit is contained in:
parent
e3c8b1b46a
commit
b7270917c8
2 changed files with 149 additions and 69 deletions
|
@ -1235,6 +1235,20 @@ static void cbCtrlLine(void *context, uint16_t ctrl)
|
|||
}
|
||||
}
|
||||
|
||||
static int cliParseSerialMode(const char *tok)
|
||||
{
|
||||
int mode = 0;
|
||||
|
||||
if (strcasestr(tok, "rx")) {
|
||||
mode |= MODE_RX;
|
||||
}
|
||||
if (strcasestr(tok, "tx")) {
|
||||
mode |= MODE_TX;
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void cliSerialPassthrough(char *cmdline)
|
||||
{
|
||||
if (isEmpty(cmdline)) {
|
||||
|
@ -1242,12 +1256,15 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
return;
|
||||
}
|
||||
|
||||
int id = -1;
|
||||
uint32_t baud = 0;
|
||||
int port1Id = -1;
|
||||
uint32_t port1Baud = 0;
|
||||
unsigned port1Mode = 0;
|
||||
int port2Id = -1;
|
||||
uint32_t port2Baud = 0;
|
||||
int port2Mode = 0;
|
||||
bool enableBaudCb = false;
|
||||
int pinioDtr = 0;
|
||||
bool resetOnDtr = false;
|
||||
unsigned mode = 0;
|
||||
int port1PinioDtr = 0;
|
||||
bool port1ResetOnDtr = false;
|
||||
char *saveptr;
|
||||
char* tok = strtok_r(cmdline, " ", &saveptr);
|
||||
int index = 0;
|
||||
|
@ -1255,114 +1272,166 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
while (tok != NULL) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
id = atoi(tok);
|
||||
port1Id = atoi(tok);
|
||||
break;
|
||||
case 1:
|
||||
baud = atoi(tok);
|
||||
port1Baud = atoi(tok);
|
||||
break;
|
||||
case 2:
|
||||
if (strcasestr(tok, "rx")) {
|
||||
mode |= MODE_RX;
|
||||
}
|
||||
if (strcasestr(tok, "tx")) {
|
||||
mode |= MODE_TX;
|
||||
}
|
||||
port1Mode = cliParseSerialMode(tok);
|
||||
break;
|
||||
case 3:
|
||||
if (strncasecmp(tok, "reset", strlen(tok)) == 0) {
|
||||
resetOnDtr = true;
|
||||
port1ResetOnDtr = true;
|
||||
#ifdef USE_PINIO
|
||||
} else if (strncasecmp(tok, "none", strlen(tok)) == 0) {
|
||||
port1PinioDtr = 0;
|
||||
} else {
|
||||
pinioDtr = atoi(tok);
|
||||
port1PinioDtr = atoi(tok);
|
||||
#endif /* USE_PINIO */
|
||||
}
|
||||
|
||||
break;
|
||||
case 4:
|
||||
port2Id = atoi(tok);
|
||||
break;
|
||||
case 5:
|
||||
port2Baud = atoi(tok);
|
||||
break;
|
||||
case 6:
|
||||
port2Mode = cliParseSerialMode(tok);
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
tok = strtok_r(NULL, " ", &saveptr);
|
||||
}
|
||||
|
||||
if (baud == 0) {
|
||||
if (port1Baud == 0 && port2Id == -1) {
|
||||
enableBaudCb = true;
|
||||
}
|
||||
|
||||
cliPrintf("Port %d ", id);
|
||||
serialPort_t *passThroughPort;
|
||||
serialPortUsage_t *passThroughPortUsage = findSerialPortUsageByIdentifier(id);
|
||||
if (!passThroughPortUsage || passThroughPortUsage->serialPort == NULL) {
|
||||
if (enableBaudCb) {
|
||||
// Set default baud
|
||||
baud = 57600;
|
||||
}
|
||||
if (port1PinioDtr < 0 || port1PinioDtr > PINIO_COUNT) {
|
||||
cliPrintLinef("Invalid PinIO number %d", port1PinioDtr);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!mode) {
|
||||
mode = MODE_RXTX;
|
||||
}
|
||||
// Port checks
|
||||
if (findSerialPortIndexByIdentifier(port1Id) == -1) {
|
||||
cliPrintLinef("Invalid port1 %d", port1Id);
|
||||
} else {
|
||||
cliPrintLinef("Port1: %d ", port1Id);
|
||||
}
|
||||
|
||||
passThroughPort = openSerialPort(id, FUNCTION_NONE, NULL, NULL,
|
||||
baud, mode,
|
||||
SERIAL_NOT_INVERTED);
|
||||
if (!passThroughPort) {
|
||||
cliPrintLine("could not be opened.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (enableBaudCb) {
|
||||
cliPrintf("opened, default baud = %d.\r\n", baud);
|
||||
if (port2Id != -1) {
|
||||
if (findSerialPortIndexByIdentifier(port2Id) == -1) {
|
||||
cliPrintLinef("Invalid port2 %d", port2Id);
|
||||
} if (port2Id == port1Id) {
|
||||
cliPrintLinef("Port1 and port2 are same");
|
||||
return ;
|
||||
} else {
|
||||
cliPrintf("opened, baud = %d.\r\n", baud);
|
||||
cliPrintLinef("Port2: %d", port2Id);
|
||||
}
|
||||
} else {
|
||||
passThroughPort = passThroughPortUsage->serialPort;
|
||||
// If the user supplied a mode, override the port's mode, otherwise
|
||||
// leave the mode unchanged. serialPassthrough() handles one-way ports.
|
||||
// Set the baud rate if specified
|
||||
if (baud) {
|
||||
cliPrintf("already open, setting baud = %d.\n\r", baud);
|
||||
serialSetBaudRate(passThroughPort, baud);
|
||||
cliPrintLine("Port2: VCP port");
|
||||
}
|
||||
|
||||
serialPort_t *port1 = NULL;
|
||||
serialPort_t *port2 = cliPort;
|
||||
serialPort_t **passthroughPorts[2] = { &port1, &port2 };
|
||||
int portIds[2] = { port1Id, 0 };
|
||||
uint32_t bauds[2] = { port1Baud, 0 };
|
||||
unsigned modes[2] = { port1Mode, 0 };
|
||||
|
||||
if (port2Id != -1) {
|
||||
*(passthroughPorts[1]) = NULL;
|
||||
portIds[1] = port2Id;
|
||||
bauds[1] = port2Baud;
|
||||
modes[1] = port2Mode;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
serialPort_t **port = passthroughPorts[i];
|
||||
if (*port != NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int portIndex = i + 1;
|
||||
serialPortUsage_t *portUsage = findSerialPortUsageByIdentifier(portIds[i]);
|
||||
if (!portUsage || portUsage->serialPort == NULL) {
|
||||
bool isUseDefaultBaud = false;
|
||||
if (bauds[i] == 0) {
|
||||
// Set default baud
|
||||
bauds[i] = 57600;
|
||||
isUseDefaultBaud = true;
|
||||
}
|
||||
|
||||
if (!modes[i]) {
|
||||
modes[i] = MODE_RXTX;
|
||||
}
|
||||
|
||||
*port = openSerialPort(portIds[i], FUNCTION_NONE, NULL, NULL,
|
||||
bauds[i], modes[i],
|
||||
SERIAL_NOT_INVERTED);
|
||||
if (!*port) {
|
||||
cliPrintLinef("Port%d could not be opened.", portIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUseDefaultBaud) {
|
||||
cliPrintf("Port%d opened, default baud = %d.\r\n", portIndex, bauds[i]);
|
||||
} else {
|
||||
cliPrintf("Port%d opened, baud = %d.\r\n", portIndex, bauds[i]);
|
||||
}
|
||||
} else {
|
||||
cliPrintf("already open, baud = %d.\n\r", passThroughPort->baudRate);
|
||||
}
|
||||
*port = portUsage->serialPort;
|
||||
// If the user supplied a mode, override the port's mode, otherwise
|
||||
// leave the mode unchanged. serialPassthrough() handles one-way ports.
|
||||
// Set the baud rate if specified
|
||||
if (bauds[i]) {
|
||||
cliPrintf("Port%d is already open, setting baud = %d.\n\r", portIndex, bauds[i]);
|
||||
serialSetBaudRate(*port, bauds[i]);
|
||||
} else {
|
||||
cliPrintf("Port%d is already open, baud = %d.\n\r", portIndex, (*port)->baudRate);
|
||||
}
|
||||
|
||||
if (mode && passThroughPort->mode != mode) {
|
||||
cliPrintf("Mode changed from %d to %d.\r\n",
|
||||
passThroughPort->mode, mode);
|
||||
serialSetMode(passThroughPort, mode);
|
||||
}
|
||||
if (modes[i] && (*port)->mode != modes[i]) {
|
||||
cliPrintf("Port%d mode changed from %d to %d.\r\n",
|
||||
portIndex, (*port)->mode, modes[i]);
|
||||
serialSetMode(*port, modes[i]);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
passThroughPort->rxCallback = 0;
|
||||
// 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 ((*port)->rxCallback) {
|
||||
(*port)->rxCallback = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no baud rate is specified allow to be set via USB
|
||||
if (enableBaudCb) {
|
||||
cliPrintLine("Baud rate change over USB enabled.");
|
||||
cliPrintLine("Port1 baud rate change over USB enabled.");
|
||||
// Register the right side baud rate setting routine with the left side which allows setting of the UART
|
||||
// baud rate over USB without setting it using the serialpassthrough command
|
||||
serialSetBaudRateCb(cliPort, serialSetBaudRate, passThroughPort);
|
||||
serialSetBaudRateCb(*(passthroughPorts[0]), serialSetBaudRate, *(passthroughPorts[1]));
|
||||
}
|
||||
|
||||
char *resetMessage = "";
|
||||
if (resetOnDtr) {
|
||||
if (port1ResetOnDtr) {
|
||||
resetMessage = "or drop DTR ";
|
||||
}
|
||||
|
||||
cliPrintLinef("Forwarding, power cycle %sto exit.", resetMessage);
|
||||
|
||||
if (resetOnDtr
|
||||
if ((port2Id == -1) && (port1ResetOnDtr
|
||||
#ifdef USE_PINIO
|
||||
|| pinioDtr
|
||||
|| port1PinioDtr
|
||||
#endif /* USE_PINIO */
|
||||
) {
|
||||
)) {
|
||||
// Register control line state callback
|
||||
serialSetCtrlLineStateCb(cliPort, cbCtrlLine, (void *)(intptr_t)(pinioDtr));
|
||||
serialSetCtrlLineStateCb(*(passthroughPorts[0]), cbCtrlLine, (void *)(intptr_t)(port1PinioDtr));
|
||||
}
|
||||
|
||||
serialPassthrough(cliPort, passThroughPort, NULL, NULL);
|
||||
serialPassthrough(*(passthroughPorts[0]), *(passthroughPorts[1]), NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue