mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-14 20:10:18 +03:00
Support programming of Arduino devices in serial passthrough mode (#5129)
* Support DTR in serial passthrough mode to enable programming of Arduino based devices such as MinimOSD. Use 'serialpassthrough 5 57600 rxtx 56' and then use Ardino to program MinimOSD Use 'serialpassthrough 5 115200' and then use MWOSD configurator to setup * Fix comment for CDC_SetCtrlLineStateCb routine * Handle F7 CDC interface * Use strToPin() to allow easy port/pin specification * Fix use of CDC_SetCtrlLineStateCb for all processor types * Only set baud when specified * Fix unit tests for cli * Only register callback if needed * Fix white space * Provide implementation of IOConfigGPIO in SITL * Update serialpassthrough help text * DTR handling through serial drivers * Fix F3, F7 and SITL builds * If serialpassthrough command specifies baud rate of 0, set baud rate over USB. MWOSD configurator can now access config and reflash MinimOSD without rebooting and changing baud rate. * Fix F3 build * Fix failing unit tests * Use resources to declare DTR pin assignment * Don't assert DTR during normal operation as MW_OSD doesn't like it * MW_OSD must be built with MAX_SOFTRESET defined in order to support DTR resets * Minimise changes after dropping DTR pin param from serialpassthrough cmd * Remove DTR pin param from serialpassthrough cmd * Treat ioDtrTag as boolean in conditional statements * Tidy buffer check * Check buffer size in CDC_Itf_Control * Fix unit test * Add documentation for DTR * Add note on MAX_SOFTRESET to documentation * Remove superfluous function definitions * Fix tabs * Fix tabs * Removed superfluous entried from vtable * Backout whitespace changes unrelated to this PR * Pass true/false to IOWrite() * Fix line coding packing * Add LINE_CODING structure defintion * Revise serial documentation * Prevent tx buffer overflow in serialPassthrough() * Revert change unrelated to PR * Review feedback from ledvinap * Fix unit test * Use PINIO to drive DTR * Fix unit test * Remove change unrelated to PR * Fix SITL build * Use shifted bits for mask definition * Fix serialpassthrough documentation * Only compile PINIO functionality if USE_PINIO defined * IOConfigGPIO not needed * Move cbCtrlLine callback to cli.c * serialPassthrough params changed * Check packed structure size * Fix unit test * Tidy up baud rate handling
This commit is contained in:
parent
46291a8374
commit
5558174d33
23 changed files with 347 additions and 33 deletions
|
@ -917,6 +917,15 @@ static void cliSerial(char *cmdline)
|
|||
}
|
||||
|
||||
#ifndef SKIP_SERIAL_PASSTHROUGH
|
||||
#ifdef USE_PINIO
|
||||
static void cbCtrlLine(void *context, uint16_t ctrl)
|
||||
{
|
||||
int pinioDtr = (int)(long)context;
|
||||
|
||||
pinioSet(pinioDtr, !(ctrl & CTRL_LINE_STATE_DTR));
|
||||
}
|
||||
#endif /* USE_PINIO */
|
||||
|
||||
static void cliSerialPassthrough(char *cmdline)
|
||||
{
|
||||
if (isEmpty(cmdline)) {
|
||||
|
@ -926,6 +935,10 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
|
||||
int id = -1;
|
||||
uint32_t baud = 0;
|
||||
bool enableBaudCb = false;
|
||||
#ifdef USE_PINIO
|
||||
int pinioDtr = 0;
|
||||
#endif /* USE_PINIO */
|
||||
unsigned mode = 0;
|
||||
char *saveptr;
|
||||
char* tok = strtok_r(cmdline, " ", &saveptr);
|
||||
|
@ -945,21 +958,32 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
if (strstr(tok, "tx") || strstr(tok, "TX"))
|
||||
mode |= MODE_TX;
|
||||
break;
|
||||
#ifdef USE_PINIO
|
||||
case 3:
|
||||
pinioDtr = atoi(tok);
|
||||
break;
|
||||
#endif /* USE_PINIO */
|
||||
}
|
||||
index++;
|
||||
tok = strtok_r(NULL, " ", &saveptr);
|
||||
}
|
||||
|
||||
if (baud == 0) {
|
||||
enableBaudCb = true;
|
||||
}
|
||||
|
||||
cliPrintf("Port %d ", id);
|
||||
serialPort_t *passThroughPort;
|
||||
serialPortUsage_t *passThroughPortUsage = findSerialPortUsageByIdentifier(id);
|
||||
if (!passThroughPortUsage || passThroughPortUsage->serialPort == NULL) {
|
||||
if (!baud) {
|
||||
cliPrintLine("closed, specify baud.");
|
||||
return;
|
||||
if (enableBaudCb) {
|
||||
// Set default baud
|
||||
baud = 57600;
|
||||
}
|
||||
if (!mode)
|
||||
|
||||
if (!mode) {
|
||||
mode = MODE_RXTX;
|
||||
}
|
||||
|
||||
passThroughPort = openSerialPort(id, FUNCTION_NONE, NULL, NULL,
|
||||
baud, mode,
|
||||
|
@ -968,17 +992,30 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
cliPrintLine("could not be opened.");
|
||||
return;
|
||||
}
|
||||
cliPrintf("opened, baud = %d.\r\n", baud);
|
||||
|
||||
if (enableBaudCb) {
|
||||
cliPrintf("opened, default baud = %d.\r\n", baud);
|
||||
} else {
|
||||
cliPrintf("opened, baud = %d.\r\n", baud);
|
||||
}
|
||||
} 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.
|
||||
cliPrintLine("already open.");
|
||||
// Set the baud rate if specified
|
||||
if (baud) {
|
||||
cliPrintf("already open, setting baud = %d.\n\r", baud);
|
||||
serialSetBaudRate(passThroughPort, baud);
|
||||
} else {
|
||||
cliPrintf("already open, baud = %d.\n\r", passThroughPort->baudRate);
|
||||
}
|
||||
|
||||
if (mode && passThroughPort->mode != mode) {
|
||||
cliPrintf("mode changed from %d to %d.\r\n",
|
||||
cliPrintf("Mode changed from %d to %d.\r\n",
|
||||
passThroughPort->mode, mode);
|
||||
serialSetMode(passThroughPort, mode);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -986,8 +1023,23 @@ static void cliSerialPassthrough(char *cmdline)
|
|||
}
|
||||
}
|
||||
|
||||
// If no baud rate is specified allow to be set via USB
|
||||
if (enableBaudCb) {
|
||||
cliPrintLine("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);
|
||||
}
|
||||
|
||||
cliPrintLine("Forwarding, power cycle to exit.");
|
||||
|
||||
#ifdef USE_PINIO
|
||||
// Register control line state callback
|
||||
if (pinioDtr) {
|
||||
serialSetCtrlLineStateCb(cliPort, cbCtrlLine, (void *)(intptr_t)(pinioDtr - 1));
|
||||
}
|
||||
#endif /* USE_PINIO */
|
||||
|
||||
serialPassthrough(cliPort, passThroughPort, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
@ -3753,7 +3805,7 @@ const clicmd_t cmdTable[] = {
|
|||
#endif
|
||||
CLI_COMMAND_DEF("serial", "configure serial ports", NULL, cliSerial),
|
||||
#ifndef SKIP_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] [DTR PINIO]: passthrough to serial", cliSerialPassthrough),
|
||||
#endif
|
||||
#ifdef USE_SERVOS
|
||||
CLI_COMMAND_DEF("servo", "configure servos", NULL, cliServo),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue