1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-13 19:40:31 +03:00

CLI parser for vtxtable

This commit is contained in:
jflyper 2018-12-19 23:08:24 +09:00
parent fa11287e8d
commit 96fc6dc934
9 changed files with 633 additions and 0 deletions

View file

@ -87,6 +87,7 @@ extern uint8_t __config_end;
#include "drivers/transponder_ir.h"
#include "drivers/usb_msc.h"
#include "drivers/vtx_common.h"
#include "drivers/vtx_table.h"
#include "fc/board_info.h"
#include "fc/config.h"
@ -140,6 +141,7 @@ extern uint8_t __config_end;
#include "pg/sdio.h"
#include "pg/timerio.h"
#include "pg/usb.h"
#include "pg/vtx_table.h"
#include "rx/rx.h"
#include "rx/spektrum.h"
@ -2336,6 +2338,348 @@ static void cliVtx(char *cmdline)
#endif // VTX_CONTROL
#ifdef USE_VTX_TABLE
static char *formatVtxTableBandFrequency(const uint16_t *frequency, int channels)
{
static char freqbuf[5 * VTX_TABLE_MAX_CHANNELS + 1];
char freqtmp[5 + 1];
freqbuf[0] = 0;
for (int channel = 0; channel < channels; channel++) {
tfp_sprintf(freqtmp, " %4d", frequency[channel]);
strcat(freqbuf, freqtmp);
}
return freqbuf;
}
static void printVtxTableBand(uint8_t dumpMask, int band, const vtxTableConfig_t *currentConfig, const vtxTableConfig_t *defaultConfig)
{
char *fmt = "vtxtable band %d %s %c%s";
bool equalsDefault = false;
if (defaultConfig) {
equalsDefault = true;
if (strcasecmp(currentConfig->bandNames[band], defaultConfig->bandNames[band])) {
equalsDefault = false;
}
if (currentConfig->bandLetters[band] != defaultConfig->bandLetters[band]) {
equalsDefault = false;
}
for (int channel = 0; channel < VTX_TABLE_MAX_CHANNELS; channel++) {
if (currentConfig->frequency[band][channel] != defaultConfig->frequency[band][channel]) {
equalsDefault = false;
}
}
char *freqbuf = formatVtxTableBandFrequency(defaultConfig->frequency[band], defaultConfig->channels);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, band + 1, defaultConfig->bandNames[band], defaultConfig->bandLetters[band], freqbuf);
}
char *freqbuf = formatVtxTableBandFrequency(currentConfig->frequency[band], currentConfig->channels);
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, band + 1, currentConfig->bandNames[band], currentConfig->bandLetters[band], freqbuf);
}
static char *formatVtxTablePowerValues(const uint16_t *levels, int count)
{
// (max 4 digit + 1 space) per level
static char pwrbuf[5 * VTX_TABLE_MAX_POWER_LEVELS + 1];
char pwrtmp[5 + 1];
pwrbuf[0] = 0;
for (int pwrindex = 0; pwrindex < count; pwrindex++) {
tfp_sprintf(pwrtmp, " %d", levels[pwrindex]);
strcat(pwrbuf, pwrtmp);
}
return pwrbuf;
}
static void printVtxTablePowerValues(uint8_t dumpMask, const vtxTableConfig_t *currentConfig, const vtxTableConfig_t *defaultConfig)
{
char *fmt = "vtxtable powervalues %s";
bool equalsDefault = false;
if (defaultConfig) {
equalsDefault = true;
for (int pwrindex = 0; pwrindex < VTX_TABLE_MAX_POWER_LEVELS; pwrindex++) {
if (defaultConfig->powerValues[pwrindex] != currentConfig->powerValues[pwrindex]) {
equalsDefault = false;
}
}
char *pwrbuf = formatVtxTablePowerValues(defaultConfig->powerValues, VTX_TABLE_MAX_POWER_LEVELS);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, pwrbuf);
}
char *pwrbuf = formatVtxTablePowerValues(currentConfig->powerValues, currentConfig->powerLevels);
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, pwrbuf);
}
static char *formatVtxTablePowerLabels(const char labels[VTX_TABLE_MAX_POWER_LEVELS][VTX_TABLE_POWER_LABEL_LENGTH + 1], int count)
{
static char pwrbuf[(VTX_TABLE_POWER_LABEL_LENGTH + 1) * VTX_TABLE_MAX_POWER_LEVELS + 1];
char pwrtmp[(VTX_TABLE_POWER_LABEL_LENGTH + 1) + 1];
pwrbuf[0] = 0;
for (int pwrindex = 0; pwrindex < count; pwrindex++) {
strcat(pwrbuf, " ");
strcpy(pwrtmp, labels[pwrindex]);
// trim trailing space
char *sp;
while ((sp = strchr(pwrtmp, ' '))) {
*sp = 0;
}
strcat(pwrbuf, pwrtmp);
}
return pwrbuf;
}
static void printVtxTablePowerLabels(uint8_t dumpMask, const vtxTableConfig_t *currentConfig, const vtxTableConfig_t *defaultConfig)
{
char *fmt = "vtxtable powerlabels%s";
bool equalsDefault = false;
if (defaultConfig) {
equalsDefault = true;
for (int pwrindex = 0; pwrindex < VTX_TABLE_MAX_POWER_LEVELS; pwrindex++) {
if (strcasecmp(defaultConfig->powerLabels[pwrindex], currentConfig->powerLabels[pwrindex])) {
equalsDefault = false;
}
}
char *pwrbuf = formatVtxTablePowerLabels(defaultConfig->powerLabels, VTX_TABLE_MAX_POWER_LEVELS);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, pwrbuf);
}
char *pwrbuf = formatVtxTablePowerLabels(currentConfig->powerLabels, currentConfig->powerLevels);
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, pwrbuf);
}
static void printVtxTable(uint8_t dumpMask, const vtxTableConfig_t *currentConfig, const vtxTableConfig_t *defaultConfig)
{
bool equalsDefault;
char *fmt;
// bands
equalsDefault = false;
fmt = "vtxtable bands %d";
if (defaultConfig) {
equalsDefault = (defaultConfig->bands == currentConfig->bands);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, defaultConfig->bands);
}
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, currentConfig->bands);
// channels
equalsDefault = false;
fmt = "vtxtable channels %d";
if (defaultConfig) {
equalsDefault = (defaultConfig->channels == currentConfig->channels);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, defaultConfig->channels);
}
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, currentConfig->channels);
// band
for (int band = 0; band < currentConfig->bands; band++) {
printVtxTableBand(dumpMask, band, currentConfig, defaultConfig);
}
// powerlevels
equalsDefault = false;
fmt = "vtxtable powerlevels %d";
if (defaultConfig) {
equalsDefault = (defaultConfig->powerLevels == currentConfig->powerLevels);
cliDefaultPrintLinef(dumpMask, equalsDefault, fmt, defaultConfig->powerLevels);
}
cliDumpPrintLinef(dumpMask, equalsDefault, fmt, currentConfig->powerLevels);
// powervalues
// powerlabels
printVtxTablePowerValues(dumpMask, currentConfig, defaultConfig);
printVtxTablePowerLabels(dumpMask, currentConfig, defaultConfig);
}
static void cliVtxTable(char *cmdline)
{
char *tok;
char *saveptr;
// Band number or nothing
tok = strtok_r(cmdline, " ", &saveptr);
if (!tok) {
printVtxTable(DUMP_MASTER | HIDE_UNUSED, vtxTableConfigMutable(), NULL);
return;
}
if (strcasecmp(tok, "bands") == 0) {
tok = strtok_r(NULL, " ", &saveptr);
int bands = atoi(tok);
if (bands < 0 || bands > VTX_TABLE_MAX_BANDS) {
cliPrintErrorLinef("INVALID BAND COUNT (SHOULD BE BETWEEN 0 AND %d)", VTX_TABLE_MAX_BANDS);
return;
}
if (bands < vtxTableConfigMutable()->bands) {
for (int i = bands; i < vtxTableConfigMutable()->bands; i++) {
vtxTableConfigClearBand(vtxTableConfigMutable(), i);
}
}
vtxTableConfigMutable()->bands = bands;
} else if (strcasecmp(tok, "channels") == 0) {
tok = strtok_r(NULL, " ", &saveptr);
int channels = atoi(tok);
if (channels < 0 || channels > VTX_TABLE_MAX_BANDS) {
cliPrintErrorLinef("INVALID CHANNEL COUNT (SHOULD BE BETWEEN 0 AND %d)", VTX_TABLE_MAX_CHANNELS);
return;
}
if (channels < vtxTableConfigMutable()->channels) {
for (int i = 0; i < VTX_TABLE_MAX_BANDS; i++) {
vtxTableConfigClearChannels(vtxTableConfigMutable(), i, channels);
}
}
vtxTableConfigMutable()->channels = channels;
} else if (strcasecmp(tok, "powerlevels") == 0) {
// Number of power levels
tok = strtok_r(NULL, " ", &saveptr);
if (tok) {
int levels = atoi(tok);
if (levels < 0 || levels > VTX_TABLE_MAX_POWER_LEVELS) {
cliPrintErrorLinef("INVALID POWER LEVEL COUNT (SHOULD BE BETWEEN 0 AND %d)", VTX_TABLE_MAX_POWER_LEVELS);
} else {
if (levels < vtxTableConfigMutable()->powerLevels) {
vtxTableConfigClearPowerValues(vtxTableConfigMutable(), levels);
vtxTableConfigClearPowerLabels(vtxTableConfigMutable(), levels);
}
vtxTableConfigMutable()->powerLevels = levels;
}
} else {
// XXX Show current level count?
}
return;
} else if (strcasecmp(tok, "powervalues") == 0) {
// Power values
uint16_t power[VTX_TABLE_MAX_POWER_LEVELS];
int count;
int levels = vtxTableConfigMutable()->powerLevels;
memset(power, 0, sizeof(power));
for (count = 0; count < levels && (tok = strtok_r(NULL, " ", &saveptr)); count++) {
int value = atoi(tok);
power[count] = value;
}
// Check remaining tokens
if (count < levels) {
cliPrintErrorLinef("NOT ENOUGH VALUES (EXPECTED %d)", levels);
return;
} else if ((tok = strtok_r(NULL, " ", &saveptr))) {
cliPrintErrorLinef("TOO MANY VALUES (EXPECTED %d)", levels);
return;
}
for (int i = 0; i < VTX_TABLE_MAX_POWER_LEVELS; i++) {
vtxTableConfigMutable()->powerValues[i] = power[i];
}
} else if (strcasecmp(tok, "powerlabels") == 0) {
// Power labels
char label[VTX_TABLE_MAX_POWER_LEVELS][VTX_TABLE_POWER_LABEL_LENGTH + 1];
int levels = vtxTableConfigMutable()->powerLevels;
int count;
for (count = 0; count < levels && (tok = strtok_r(NULL, " ", &saveptr)); count++) {
strncpy(label[count], tok, VTX_TABLE_POWER_LABEL_LENGTH);
for (unsigned i = 0; i < strlen(label[count]); i++) {
label[count][i] = toupper(label[count][i]);
}
}
// Check remaining tokens
if (count < levels) {
cliPrintErrorLinef("NOT ENOUGH LABELS (EXPECTED %d)", levels);
return;
} else if ((tok = strtok_r(NULL, " ", &saveptr))) {
cliPrintErrorLinef("TOO MANY LABELS (EXPECTED %d)", levels);
return;
}
for (int i = 0; i < count; i++) {
vtxTableStrncpyWithPad(vtxTableConfigMutable()->powerLabels[i], label[i], VTX_TABLE_POWER_LABEL_LENGTH);
}
} else if (strcasecmp(tok, "band") == 0) {
int bands = vtxTableConfigMutable()->bands;
tok = strtok_r(NULL, " ", &saveptr);
if (!tok) {
return;
}
int band = atoi(tok);
--band;
if (band < 0 || band >= bands) {
cliPrintErrorLinef("INVALID BAND NUMBER %s (EXPECTED 1-%d)", tok, bands);
return;
}
// Band name
tok = strtok_r(NULL, " ", &saveptr);
if (!tok) {
return;
}
char bandname[VTX_TABLE_BAND_NAME_LENGTH + 1];
memset(bandname, 0, VTX_TABLE_BAND_NAME_LENGTH + 1);
strncpy(bandname, tok, VTX_TABLE_BAND_NAME_LENGTH);
for (unsigned i = 0; i < strlen(bandname); i++) {
bandname[i] = toupper(bandname[i]);
}
// Band letter
tok = strtok_r(NULL, " ", &saveptr);
if (!tok) {
return;
}
char bandletter = toupper(tok[0]);
uint16_t bandfreq[VTX_TABLE_MAX_CHANNELS];
int channel = 0;
int channels = vtxTableConfigMutable()->channels;
for (channel = 0; channel < channels && (tok = strtok_r(NULL, " ", &saveptr)); channel++) {
int freq = atoi(tok);
if (freq < 0) {
cliPrintErrorLinef("INVALID FREQUENCY %s", tok);
return;
}
bandfreq[channel] = freq;
}
if (channel < channels) {
cliPrintErrorLinef("NOT ENOUGH FREQUENCIES (EXPECTED %d)", channels);
return;
} else if ((tok = strtok_r(NULL, " ", &saveptr))) {
cliPrintErrorLinef("TOO MANY FREQUENCIES (EXPECTED %d)", channels);
return;
}
vtxTableStrncpyWithPad(vtxTableConfigMutable()->bandNames[band], bandname, VTX_TABLE_BAND_NAME_LENGTH);
vtxTableConfigMutable()->bandLetters[band] = bandletter;
for (int i = 0; i < channel; i++) {
vtxTableConfigMutable()->frequency[band][i] = bandfreq[i];
}
} else {
// Bad subcommand
cliPrintErrorLinef("INVALID SUBCOMMAND %s", tok);
}
}
#endif // USE_VTX_TABLE
#ifdef USE_OSD
static void printDisplayName(uint8_t dumpMask, const pilotConfig_t *pilotConfig)
{
@ -4762,6 +5106,11 @@ static void printConfig(char *cmdline, bool doDiff)
printVtx(dumpMask, &vtxConfig_Copy, vtxConfig());
#endif
#ifdef USE_VTX_TABLE
cliPrintHashLine("vtxtable");
printVtxTable(dumpMask, &vtxTableConfig_Copy, vtxTableConfig());
#endif
cliPrintHashLine("rxfail");
printRxFailsafe(dumpMask, rxFailsafeChannelConfigs_CopyArray, rxFailsafeChannelConfigs(0));
@ -5013,6 +5362,9 @@ const clicmd_t cmdTable[] = {
#ifdef USE_VTX_CONTROL
CLI_COMMAND_DEF("vtx", "vtx channels on switch", NULL, cliVtx),
#endif
#ifdef USE_VTX_TABLE
CLI_COMMAND_DEF("vtxtable", "vtx frequency able", "<band> <bandname> <bandletter> <freq> ... <freq>\r\n", cliVtxTable),
#endif
};
static void cliHelp(char *cmdline)