|
|
@ -5,44 +5,86 @@ |
|
|
|
extern uint8_t cliMode; |
|
|
|
static void cliExit(char *cmdline); |
|
|
|
static void cliHelp(char *cmdline); |
|
|
|
static void cliMixer(char *cmdline); |
|
|
|
static void cliRMode(char *cmdline); |
|
|
|
static void cliSet(char *cmdline); |
|
|
|
static void cliVersion(char *cmdline); |
|
|
|
|
|
|
|
// buffer |
|
|
|
char cliBuffer[32]; |
|
|
|
uint8_t bufferIndex = 0; |
|
|
|
static char cliBuffer[32]; |
|
|
|
static uint8_t bufferIndex = 0; |
|
|
|
static bool unsaved = false; |
|
|
|
|
|
|
|
const char *mixerNames[] = { |
|
|
|
"TRI", "QUADP", "QUADX", "BI", |
|
|
|
"GIMBAL", "Y6", "HEX6", |
|
|
|
"FLYING_WING", "Y4", "HEX6X", "OCTOX8", "OCTOFLATP", "OCTOFLATX", |
|
|
|
"AIRPLANE", "HELI_120_CCPM", "HELI_90_DEG", "VTAIL4" |
|
|
|
}; |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
char *name; |
|
|
|
char *param; |
|
|
|
void (*func)(char *cmdline); |
|
|
|
} cliCmd; |
|
|
|
} clicmd_t; |
|
|
|
|
|
|
|
// should be sorted a..z for bsearch() |
|
|
|
const cliCmd cmdTable[] = { |
|
|
|
const clicmd_t cmdTable[] = { |
|
|
|
{ "exit", "", cliExit }, |
|
|
|
{ "help", "", cliHelp }, |
|
|
|
{ "mixer", "mixer name", cliMixer }, |
|
|
|
{ "rmode", "pwm / ppm", cliRMode }, |
|
|
|
{ "set", "name=value", cliSet }, |
|
|
|
{ "version", "", cliVersion }, |
|
|
|
}; |
|
|
|
#define CMD_COUNT (sizeof cmdTable / sizeof cmdTable[0]) |
|
|
|
#define CMD_COUNT (sizeof(cmdTable) / sizeof(cmdTable[0])) |
|
|
|
|
|
|
|
typedef enum { |
|
|
|
VAR_BOOL, // yes/no true/false 1/0 type stuff |
|
|
|
VAR_UINT8, |
|
|
|
VAR_INT8, |
|
|
|
VAR_UINT16, |
|
|
|
VAR_INT16 |
|
|
|
} vartype_e; |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
const char *name; |
|
|
|
const uint8_t type; // vartype_e |
|
|
|
void *ptr; |
|
|
|
const int32_t min; |
|
|
|
const int32_t max; |
|
|
|
} clivalue_t; |
|
|
|
|
|
|
|
const clivalue_t valueTable[] = { |
|
|
|
{ "deadband", VAR_UINT8, &cfg.deadband, 0, 32 }, |
|
|
|
{ "midrc", VAR_UINT16, &cfg.midrc, 1200, 1700 }, |
|
|
|
{ "minthrottle", VAR_UINT16, &cfg.minthrottle, 0, 2000 }, |
|
|
|
{ "maxthrottle", VAR_UINT16, &cfg.maxthrottle, 0, 2000 }, |
|
|
|
{ "mincommand", VAR_UINT16, &cfg.mincommand, 0, 2000 }, |
|
|
|
{ "yaw_direction", VAR_INT8, &cfg.yaw_direction, -1, 1 }, |
|
|
|
{ "wing_left_mid", VAR_UINT16, &cfg.wing_left_mid, 0, 2000 }, |
|
|
|
{ "wing_right_mid", VAR_UINT16, &cfg.wing_right_mid, 0, 2000 }, |
|
|
|
{ "tri_yaw_middle", VAR_UINT16, &cfg.tri_yaw_middle, 0, 2000 }, |
|
|
|
{ "tilt_pitch_prop", VAR_INT8, &cfg.tilt_pitch_prop, -100, 100 }, |
|
|
|
{ "tilt_roll_prop", VAR_INT8, &cfg.tilt_roll_prop, -100, 100 }, |
|
|
|
}; |
|
|
|
|
|
|
|
#define VALUE_COUNT (sizeof(valueTable) / sizeof(valueTable[0])) |
|
|
|
|
|
|
|
static void cliPrompt(void) |
|
|
|
{ |
|
|
|
uartPrint("\r\n# "); |
|
|
|
memset(cliBuffer, 0, sizeof(cliBuffer)); |
|
|
|
bufferIndex = 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int cliCompare(const void *a, const void *b) |
|
|
|
{ |
|
|
|
const cliCmd *ca = a, *cb = b; |
|
|
|
const clicmd_t *ca = a, *cb = b; |
|
|
|
return strncasecmp(ca->name, cb->name, strlen(cb->name)); |
|
|
|
} |
|
|
|
|
|
|
|
static void cliExit(char *cmdline) |
|
|
|
{ |
|
|
|
uartPrint("Leaving CLI mode...\r\n"); |
|
|
|
uartPrint("\r\nLeaving CLI mode...\r\n"); |
|
|
|
memset(cliBuffer, 0, sizeof(cliBuffer)); |
|
|
|
bufferIndex = 0; |
|
|
|
cliMode = 0; |
|
|
@ -62,6 +104,12 @@ static void cliHelp(char *cmdline) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void cliMixer(char *cmdline) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
static void cliRMode(char *cmdline) |
|
|
|
{ |
|
|
|
if (strncasecmp(cmdline, "pwm", 3) == 0) { |
|
|
@ -71,31 +119,78 @@ static void cliRMode(char *cmdline) |
|
|
|
uartPrint("PPM Mode"); |
|
|
|
featureSet(FEATURE_PPM); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cliExit(cmdline); |
|
|
|
writeParams(); |
|
|
|
systemReset(false); |
|
|
|
} |
|
|
|
|
|
|
|
static void cliSet(char *cmdline) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
static void cliVersion(char *cmdline) |
|
|
|
{ |
|
|
|
uartPrint("Afro32 CLI version 2.0-pre1"); |
|
|
|
uartPrint("Afro32 CLI version 2.0-pre3"); |
|
|
|
} |
|
|
|
|
|
|
|
void cliProcess(void) |
|
|
|
{ |
|
|
|
if (!cliMode) { |
|
|
|
cliMode = 1; |
|
|
|
uartPrint("\r\nEntering CLI Mode, type 'exit' to return, or 'help'\r\n"); |
|
|
|
cliPrompt(); |
|
|
|
} |
|
|
|
|
|
|
|
while (uartAvailable()) { |
|
|
|
uint8_t c = uartRead(); |
|
|
|
|
|
|
|
cliBuffer[bufferIndex++] = c; |
|
|
|
if (bufferIndex == sizeof(cliBuffer)) { |
|
|
|
bufferIndex--; |
|
|
|
c = '\n'; |
|
|
|
} |
|
|
|
|
|
|
|
if (bufferIndex && (c == '\n' || c == '\r')) { |
|
|
|
if (c == '\t' || c == '?') { |
|
|
|
const clicmd_t *cmd, *pstart = NULL, *pend = NULL; |
|
|
|
int i = bufferIndex; |
|
|
|
for (cmd = cmdTable;cmd < cmdTable + CMD_COUNT;cmd++) { |
|
|
|
if (bufferIndex && (strncasecmp(cliBuffer, cmd->name, bufferIndex) != 0)) |
|
|
|
continue; |
|
|
|
if (!pstart) |
|
|
|
pstart = cmd; |
|
|
|
pend = cmd; |
|
|
|
} |
|
|
|
if (pstart) { /* Buffer matches one or more commands */ |
|
|
|
for (;;bufferIndex++) { |
|
|
|
if (pstart->name[bufferIndex] != pend->name[bufferIndex]) |
|
|
|
break; |
|
|
|
if (!pstart->name[bufferIndex]) { |
|
|
|
/* Unambiguous -- append a space */ |
|
|
|
cliBuffer[bufferIndex++] = ' '; |
|
|
|
break; |
|
|
|
} |
|
|
|
cliBuffer[bufferIndex] = pstart->name[bufferIndex]; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!bufferIndex || pstart != pend) { |
|
|
|
/* Print list of ambiguous matches */ |
|
|
|
uartPrint("\r\033[K"); |
|
|
|
for (cmd = pstart;cmd <= pend;cmd++) { |
|
|
|
uartPrint(cmd->name); |
|
|
|
uartWrite('\t'); |
|
|
|
} |
|
|
|
cliPrompt(); |
|
|
|
i = 0; /* Redraw prompt */ |
|
|
|
} |
|
|
|
for (;i < bufferIndex;i++) |
|
|
|
uartWrite(cliBuffer[i]); |
|
|
|
} else if (!bufferIndex && c == 4) { |
|
|
|
cliExit(cliBuffer); |
|
|
|
return; |
|
|
|
} else if (c == 12) { |
|
|
|
uartPrint("\033[2J\033[1;1H"); |
|
|
|
cliPrompt(); |
|
|
|
} else if (bufferIndex && (c == '\n' || c == '\r')) { |
|
|
|
// enter pressed |
|
|
|
cliCmd *cmd = NULL; |
|
|
|
cliCmd target; |
|
|
|
clicmd_t *cmd = NULL; |
|
|
|
clicmd_t target; |
|
|
|
uartPrint("\r\n"); |
|
|
|
cliBuffer[bufferIndex] = 0; // null terminate |
|
|
|
|
|
|
@ -108,25 +203,23 @@ void cliProcess(void) |
|
|
|
else |
|
|
|
uartPrint("ERR: Unknown command, try 'HELP'"); |
|
|
|
|
|
|
|
// 'exit' will reset this flag, so we don't need to print prompt again |
|
|
|
if (cliMode) |
|
|
|
cliPrompt(); |
|
|
|
memset(cliBuffer, 0, sizeof(cliBuffer)); |
|
|
|
bufferIndex = 0; |
|
|
|
|
|
|
|
// 'exit' will reset this flag, so we don't need to print prompt again |
|
|
|
if (!cliMode) |
|
|
|
return; |
|
|
|
cliPrompt(); |
|
|
|
} else if (c == 127) { |
|
|
|
// backspace |
|
|
|
if (bufferIndex > 1) { |
|
|
|
cliBuffer[bufferIndex - 2] = 0; |
|
|
|
uartPrint("\r# "); |
|
|
|
uartPrint(cliBuffer); |
|
|
|
uartWrite(' '); |
|
|
|
uartPrint("\r# "); |
|
|
|
uartPrint(cliBuffer); |
|
|
|
bufferIndex -= 2; |
|
|
|
if (bufferIndex) { |
|
|
|
cliBuffer[--bufferIndex] = 0; |
|
|
|
uartPrint("\010 \010"); |
|
|
|
} |
|
|
|
} else if (c < 32 || c > 126) { |
|
|
|
// non-printable ascii |
|
|
|
bufferIndex--; |
|
|
|
} else { |
|
|
|
} else if (bufferIndex < sizeof(cliBuffer) && c >= 32 && c <= 126) { |
|
|
|
if (!bufferIndex && c == 32) |
|
|
|
continue; |
|
|
|
cliBuffer[bufferIndex++] = c; |
|
|
|
uartWrite(c); |
|
|
|
} |
|
|
|
} |
|
|
|