1
0
Fork 0
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:
SteveCEvans 2018-03-21 10:17:31 +00:00 committed by Michael Keller
parent 46291a8374
commit 5558174d33
23 changed files with 347 additions and 33 deletions

View file

@ -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),