Preparation for doing PG differencing in CLI

This commit is contained in:
Martin Budden 2017-01-25 10:26:25 +00:00 committed by borisbstyle
parent 9e529a28ca
commit 83343e1d86
2 changed files with 175 additions and 75 deletions

View File

@ -20,6 +20,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "build/build_config.h"
typedef uint16_t pgn_t; typedef uint16_t pgn_t;
// parameter group registry flags // parameter group registry flags
@ -54,6 +56,7 @@ static inline uint16_t pgN(const pgRegistry_t* reg) {return reg->pgn & PGR_PGN_M
static inline uint8_t pgVersion(const pgRegistry_t* reg) {return reg->pgn >> 12;} static inline uint8_t pgVersion(const pgRegistry_t* reg) {return reg->pgn >> 12;}
static inline uint16_t pgSize(const pgRegistry_t* reg) {return reg->size & PGR_SIZE_MASK;} static inline uint16_t pgSize(const pgRegistry_t* reg) {return reg->size & PGR_SIZE_MASK;}
static inline uint16_t pgIsSystem(const pgRegistry_t* reg) {return (reg->size & PGR_SIZE_PROFILE_FLAG) == 0;} static inline uint16_t pgIsSystem(const pgRegistry_t* reg) {return (reg->size & PGR_SIZE_PROFILE_FLAG) == 0;}
static inline uint16_t pgIsProfile(const pgRegistry_t* reg) {return (reg->size & PGR_SIZE_PROFILE_FLAG) == PGR_SIZE_PROFILE_FLAG;}
#define PG_PACKED __attribute__((packed)) #define PG_PACKED __attribute__((packed))
@ -100,22 +103,25 @@ extern const uint8_t __pg_resetdata_end[];
// Declare system config // Declare system config
#define PG_DECLARE(_type, _name) \ #define PG_DECLARE(_type, _name) \
extern _type _name ## _System; \ extern _type _name ## _System; \
static inline _type* _name(void) { return &_name ## _System; } \ static inline const _type* _name(void) { return &_name ## _System; }\
static inline _type* _name ## Mutable(void) { return &_name ## _System; }\
struct _dummy \ struct _dummy \
/**/ /**/
// Declare system config array // Declare system config array
#define PG_DECLARE_ARR(_type, _size, _name) \ #define PG_DECLARE_ARRAY(_type, _size, _name) \
extern _type _name ## _SystemArray[_size]; \ extern _type _name ## _SystemArray[_size]; \
static inline _type* _name(int _index) { return &_name ## _SystemArray[_index]; } \ static inline const _type* _name(int _index) { return &_name ## _SystemArray[_index]; } \
static inline _type (* _name ## _arr(void))[_size] { return &_name ## _SystemArray; } \ static inline _type* _name ## Mutable(int _index) { return &_name ## _SystemArray[_index]; } \
static inline _type (* _name ## _array(void))[_size] { return &_name ## _SystemArray; } \
struct _dummy \ struct _dummy \
/**/ /**/
// Declare profile config // Declare profile config
#define PG_DECLARE_PROFILE(_type, _name) \ #define PG_DECLARE_PROFILE(_type, _name) \
extern _type *_name ## _ProfileCurrent; \ extern _type *_name ## _ProfileCurrent; \
static inline _type* _name(void) { return _name ## _ProfileCurrent; } \ static inline const _type* _name(void) { return _name ## _ProfileCurrent; } \
static inline _type* _name ## Mutable(void) { return _name ## _ProfileCurrent; } \
struct _dummy \ struct _dummy \
/**/ /**/
@ -148,7 +154,7 @@ extern const uint8_t __pg_resetdata_end[];
/**/ /**/
// Register system config array // Register system config array
#define PG_REGISTER_ARR_I(_type, _size, _name, _pgn, _version, _reset) \ #define PG_REGISTER_ARRAY_I(_type, _size, _name, _pgn, _version, _reset) \
_type _name ## _SystemArray[_size]; \ _type _name ## _SystemArray[_size]; \
extern const pgRegistry_t _name ##_Registry; \ extern const pgRegistry_t _name ##_Registry; \
const pgRegistry_t _name ## _Registry PG_REGISTER_ATTRIBUTES = { \ const pgRegistry_t _name ## _Registry PG_REGISTER_ATTRIBUTES = { \
@ -160,20 +166,20 @@ extern const uint8_t __pg_resetdata_end[];
} \ } \
/**/ /**/
#define PG_REGISTER_ARR(_type, _size, _name, _pgn, _version) \ #define PG_REGISTER_ARRAY(_type, _size, _name, _pgn, _version) \
PG_REGISTER_ARR_I(_type, _size, _name, _pgn, _version, .reset = {.ptr = 0}) \ PG_REGISTER_ARRAY_I(_type, _size, _name, _pgn, _version, .reset = {.ptr = 0}) \
/**/ /**/
#define PG_REGISTER_ARR_WITH_RESET_FN(_type, _size, _name, _pgn, _version) \ #define PG_REGISTER_ARRAY_WITH_RESET_FN(_type, _size, _name, _pgn, _version) \
extern void pgResetFn_ ## _name(_type *); \ extern void pgResetFn_ ## _name(_type *); \
PG_REGISTER_ARR_I(_type, _size, _name, _pgn, _version, .reset = {.fn = (pgResetFunc*)&pgResetFn_ ## _name}) \ PG_REGISTER_ARRAY_I(_type, _size, _name, _pgn, _version, .reset = {.fn = (pgResetFunc*)&pgResetFn_ ## _name}) \
/**/ /**/
#if 0 #if 0
// ARRAY reset mechanism is not implemented yet, only few places in code would benefit from it - See pgResetInstance // ARRAY reset mechanism is not implemented yet, only few places in code would benefit from it - See pgResetInstance
#define PG_REGISTER_ARR_WITH_RESET_TEMPLATE(_type, _size, _name, _pgn, _version) \ #define PG_REGISTER_ARRAY_WITH_RESET_TEMPLATE(_type, _size, _name, _pgn, _version) \
extern const _type pgResetTemplate_ ## _name; \ extern const _type pgResetTemplate_ ## _name; \
PG_REGISTER_ARR_I(_type, _size, _name, _pgn, _version, .reset = {.ptr = (void*)&pgResetTemplate_ ## _name}) \ PG_REGISTER_ARRAY_I(_type, _size, _name, _pgn, _version, .reset = {.ptr = (void*)&pgResetTemplate_ ## _name}) \
/**/ /**/
#endif #endif

View File

@ -117,16 +117,6 @@ static uint8_t cliWriteBuffer[sizeof(*cliWriter) + 128];
static char cliBuffer[48]; static char cliBuffer[48];
static uint32_t bufferIndex = 0; static uint32_t bufferIndex = 0;
typedef enum {
DUMP_MASTER = (1 << 0),
DUMP_PROFILE = (1 << 1),
DUMP_RATES = (1 << 2),
DUMP_ALL = (1 << 3),
DO_DIFF = (1 << 4),
SHOW_DEFAULTS = (1 << 5),
HIDE_UNUSED = (1 << 6)
} dumpFlags_e;
static const char* const emptyName = "-"; static const char* const emptyName = "-";
#ifndef USE_QUAD_MIXER_ONLY #ifndef USE_QUAD_MIXER_ONLY
@ -452,22 +442,21 @@ static const lookupTableEntry_t lookupTables[] = {
#define VALUE_MODE_OFFSET 6 #define VALUE_MODE_OFFSET 6
typedef enum { typedef enum {
// value type // value type, bits 0-3
VAR_UINT8 = (0 << VALUE_TYPE_OFFSET), VAR_UINT8 = (0 << VALUE_TYPE_OFFSET),
VAR_INT8 = (1 << VALUE_TYPE_OFFSET), VAR_INT8 = (1 << VALUE_TYPE_OFFSET),
VAR_UINT16 = (2 << VALUE_TYPE_OFFSET), VAR_UINT16 = (2 << VALUE_TYPE_OFFSET),
VAR_INT16 = (3 << VALUE_TYPE_OFFSET), VAR_INT16 = (3 << VALUE_TYPE_OFFSET),
//VAR_UINT32 = (4 << VALUE_TYPE_OFFSET), //VAR_UINT32 = (4 << VALUE_TYPE_OFFSET),
VAR_FLOAT = (5 << VALUE_TYPE_OFFSET), VAR_FLOAT = (5 << VALUE_TYPE_OFFSET), // 0x05
// value section // value section, bits 4-5
MASTER_VALUE = (0 << VALUE_SECTION_OFFSET), MASTER_VALUE = (0 << VALUE_SECTION_OFFSET),
PROFILE_VALUE = (1 << VALUE_SECTION_OFFSET), PROFILE_VALUE = (1 << VALUE_SECTION_OFFSET),
PROFILE_RATE_VALUE = (2 << VALUE_SECTION_OFFSET), PROFILE_RATE_VALUE = (2 << VALUE_SECTION_OFFSET), // 0x20
CONTROL_RATE_VALUE = (3 << VALUE_SECTION_OFFSET),
// value mode // value mode
MODE_DIRECT = (0 << VALUE_MODE_OFFSET), MODE_DIRECT = (0 << VALUE_MODE_OFFSET), // 0x40
MODE_LOOKUP = (1 << VALUE_MODE_OFFSET) MODE_LOOKUP = (1 << VALUE_MODE_OFFSET) // 0x80
} cliValueFlag_e; } cliValueFlag_e;
#define VALUE_TYPE_MASK (0x0F) #define VALUE_TYPE_MASK (0x0F)
@ -858,6 +847,16 @@ static void cliPutp(void *p, char ch)
bufWriterAppend(p, ch); bufWriterAppend(p, ch);
} }
typedef enum {
DUMP_MASTER = (1 << 0),
DUMP_PROFILE = (1 << 1),
DUMP_RATES = (1 << 2),
DUMP_ALL = (1 << 3),
DO_DIFF = (1 << 4),
SHOW_DEFAULTS = (1 << 5),
HIDE_UNUSED = (1 << 6)
} dumpFlags_e;
static bool cliDumpPrintf(uint8_t dumpMask, bool equalsDefault, const char *format, ...) static bool cliDumpPrintf(uint8_t dumpMask, bool equalsDefault, const char *format, ...)
{ {
if (!((dumpMask & DO_DIFF) && equalsDefault)) { if (!((dumpMask & DO_DIFF) && equalsDefault)) {
@ -952,23 +951,121 @@ static void printValuePointer(const clivalue_t *var, void *valuePointer, uint32_
} }
#ifdef USE_PARAMETER_GROUPS #ifdef USE_PARAMETER_GROUPS
static void* getValuePointer(const clivalue_t *var)
{
const pgRegistry_t* rec = pgFind(var->pgn);
switch (var->type & VALUE_SECTION_MASK) { static bool valuePtrEqualsDefault(uint8_t type, const void *ptr, const void *ptrDefault)
{
bool result = false;
switch (type & VALUE_TYPE_MASK) {
case VAR_UINT8:
result = *(uint8_t *)ptr == *(uint8_t *)ptrDefault;
break;
case VAR_INT8:
result = *(int8_t *)ptr == *(int8_t *)ptrDefault;
break;
case VAR_UINT16:
result = *(uint16_t *)ptr == *(uint16_t *)ptrDefault;
break;
case VAR_INT16:
result = *(int16_t *)ptr == *(int16_t *)ptrDefault;
break;
/* not currently used
case VAR_UINT32:
result = *(uint32_t *)ptr == *(uint32_t *)ptrDefault;
break;*/
case VAR_FLOAT:
result = *(float *)ptr == *(float *)ptrDefault;
break;
}
return result;
}
typedef struct cliCurrentAndDefaultConfig_s {
const void *currentConfig; // the copy
const void *defaultConfig; // the PG value as set by default
} cliCurrentAndDefaultConfig_t;
static const cliCurrentAndDefaultConfig_t *getCurrentAndDefaultConfigs(pgn_t pgn)
{
static cliCurrentAndDefaultConfig_t ret;
switch (pgn) {
default:
ret.currentConfig = NULL;
ret.defaultConfig = NULL;
break;
}
return &ret;
}
static uint16_t getValueOffset(const clivalue_t *value)
{
switch (value->type & VALUE_SECTION_MASK) {
case MASTER_VALUE: case MASTER_VALUE:
return rec->address + var->offset;
case PROFILE_RATE_VALUE:
return rec->address + var->offset + sizeof(profile_t) * getCurrentProfile();
case CONTROL_RATE_VALUE:
return rec->address + var->offset + sizeof(controlRateConfig_t) * getCurrentControlRateProfile();
case PROFILE_VALUE: case PROFILE_VALUE:
return *rec->ptr + var->offset; return value->offset;
case PROFILE_RATE_VALUE:
return value->offset + sizeof(controlRateConfig_t) * getCurrentControlRateProfile();
}
return 0;
}
static void *getValuePointer(const clivalue_t *value)
{
const pgRegistry_t* rec = pgFind(value->pgn);
switch (value->type & VALUE_SECTION_MASK) {
case MASTER_VALUE:
case PROFILE_VALUE:
return rec->address + value->offset;
case PROFILE_RATE_VALUE:
return rec->address + value->offset + sizeof(controlRateConfig_t) * getCurrentControlRateProfile();
} }
return NULL; return NULL;
} }
static void dumpPgValue(const clivalue_t *value, uint8_t dumpMask)
{
const char *format = "set %s = ";
const cliCurrentAndDefaultConfig_t *config = getCurrentAndDefaultConfigs(value->pgn);
if (config->currentConfig == NULL || config->defaultConfig == NULL) {
// has not been set up properly
cliPrintf("VALUE %s ERROR\r\n", value->name);
return;
}
const int valueOffset = getValueOffset(value);
switch (dumpMask & (DO_DIFF | SHOW_DEFAULTS)) {
case DO_DIFF:
if (valuePtrEqualsDefault(value->type, (uint8_t*)config->currentConfig + valueOffset, (uint8_t*)config->defaultConfig + valueOffset)) {
break;
}
// drop through, since not equal to default
case 0:
case SHOW_DEFAULTS:
cliPrintf(format, value->name);
printValuePointer(value, (uint8_t*)config->currentConfig + valueOffset, 0);
cliPrint("\r\n");
break;
}
}
static void dumpAllValues(uint16_t valueSection, uint8_t dumpMask)
{
for (uint32_t i = 0; i < ARRAYLEN(valueTable); i++) {
const clivalue_t *value = &valueTable[i];
bufWriterFlush(cliWriter);
if ((value->type & VALUE_SECTION_MASK) == valueSection) {
dumpPgValue(value, dumpMask);
}
}
}
#else #else
void *getValuePointer(const clivalue_t *value) void *getValuePointer(const clivalue_t *value)
{ {
void *ptr = value->ptr; void *ptr = value->ptr;
@ -1141,9 +1238,9 @@ static void cliShowArgumentRangeError(char *name, int min, int max)
cliPrintf("%s not between %d and %d\r\n", name, min, max); cliPrintf("%s not between %d and %d\r\n", name, min, max);
} }
static char *nextArg(char *currentArg) static const char *nextArg(const char *currentArg)
{ {
char *ptr = strchr(currentArg, ' '); const char *ptr = strchr(currentArg, ' ');
while (ptr && *ptr == ' ') { while (ptr && *ptr == ' ') {
ptr++; ptr++;
} }
@ -1151,14 +1248,12 @@ static char *nextArg(char *currentArg)
return ptr; return ptr;
} }
static char *processChannelRangeArgs(char *ptr, channelRange_t *range, uint8_t *validArgumentCount) static const char *processChannelRangeArgs(const char *ptr, channelRange_t *range, uint8_t *validArgumentCount)
{ {
int val;
for (uint32_t argIndex = 0; argIndex < 2; argIndex++) { for (uint32_t argIndex = 0; argIndex < 2; argIndex++) {
ptr = nextArg(ptr); ptr = nextArg(ptr);
if (ptr) { if (ptr) {
val = atoi(ptr); int val = atoi(ptr);
val = CHANNEL_VALUE_TO_STEP(val); val = CHANNEL_VALUE_TO_STEP(val);
if (val >= MIN_MODE_RANGE_STEP && val <= MAX_MODE_RANGE_STEP) { if (val >= MIN_MODE_RANGE_STEP && val <= MAX_MODE_RANGE_STEP) {
if (argIndex == 0) { if (argIndex == 0) {
@ -1177,10 +1272,10 @@ static char *processChannelRangeArgs(char *ptr, channelRange_t *range, uint8_t *
// Check if a string's length is zero // Check if a string's length is zero
static bool isEmpty(const char *string) static bool isEmpty(const char *string)
{ {
return *string == '\0'; return (string == NULL || *string == '\0') ? true : false;
} }
static void printRxFail(uint8_t dumpMask, const rxConfig_t *rxConfig, const rxConfig_t *defaultRxConfig) static void printRxFailsafe(uint8_t dumpMask, const rxConfig_t *rxConfig, const rxConfig_t *defaultRxConfig)
{ {
// print out rxConfig failsafe settings // print out rxConfig failsafe settings
for (uint32_t channel = 0; channel < MAX_SUPPORTED_RC_CHANNEL_COUNT; channel++) { for (uint32_t channel = 0; channel < MAX_SUPPORTED_RC_CHANNEL_COUNT; channel++) {
@ -1219,7 +1314,7 @@ static void printRxFail(uint8_t dumpMask, const rxConfig_t *rxConfig, const rxCo
} }
} }
static void cliRxFail(char *cmdline) static void cliRxFailsafe(char *cmdline)
{ {
uint8_t channel; uint8_t channel;
char buf[3]; char buf[3];
@ -1227,10 +1322,10 @@ static void cliRxFail(char *cmdline)
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
// print out rxConfig failsafe settings // print out rxConfig failsafe settings
for (channel = 0; channel < MAX_SUPPORTED_RC_CHANNEL_COUNT; channel++) { for (channel = 0; channel < MAX_SUPPORTED_RC_CHANNEL_COUNT; channel++) {
cliRxFail(itoa(channel, buf, 10)); cliRxFailsafe(itoa(channel, buf, 10));
} }
} else { } else {
char *ptr = cmdline; const char *ptr = cmdline;
channel = atoi(ptr++); channel = atoi(ptr++);
if ((channel < MAX_SUPPORTED_RC_CHANNEL_COUNT)) { if ((channel < MAX_SUPPORTED_RC_CHANNEL_COUNT)) {
@ -1337,7 +1432,7 @@ static void printAux(uint8_t dumpMask, const modeActivationProfile_t *modeActiva
static void cliAux(char *cmdline) static void cliAux(char *cmdline)
{ {
int i, val = 0; int i, val = 0;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printAux(DUMP_MASTER, modeActivationProfile(), NULL); printAux(DUMP_MASTER, modeActivationProfile(), NULL);
@ -1411,12 +1506,8 @@ static void printSerial(uint8_t dumpMask, const serialConfig_t *serialConfig, co
static void cliSerial(char *cmdline) static void cliSerial(char *cmdline)
{ {
int i, val;
char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printSerial(DUMP_MASTER, serialConfig(), NULL); printSerial(DUMP_MASTER, serialConfig(), NULL);
return; return;
} }
serialPortConfig_t portConfig; serialPortConfig_t portConfig;
@ -1426,9 +1517,9 @@ static void cliSerial(char *cmdline)
uint8_t validArgumentCount = 0; uint8_t validArgumentCount = 0;
ptr = cmdline; const char *ptr = cmdline;
val = atoi(ptr++); int val = atoi(ptr++);
currentConfig = serialFindPortConfiguration(val); currentConfig = serialFindPortConfiguration(val);
if (currentConfig) { if (currentConfig) {
portConfig.identifier = val; portConfig.identifier = val;
@ -1442,7 +1533,7 @@ static void cliSerial(char *cmdline)
validArgumentCount++; validArgumentCount++;
} }
for (i = 0; i < 4; i ++) { for (int i = 0; i < 4; i ++) {
ptr = nextArg(ptr); ptr = nextArg(ptr);
if (!ptr) { if (!ptr) {
break; break;
@ -1491,7 +1582,6 @@ static void cliSerial(char *cmdline)
} }
memcpy(currentConfig, &portConfig, sizeof(portConfig)); memcpy(currentConfig, &portConfig, sizeof(portConfig));
} }
#ifndef SKIP_SERIAL_PASSTHROUGH #ifndef SKIP_SERIAL_PASSTHROUGH
@ -1609,7 +1699,7 @@ static void printAdjustmentRange(uint8_t dumpMask, const adjustmentProfile_t *ad
static void cliAdjustmentRange(char *cmdline) static void cliAdjustmentRange(char *cmdline)
{ {
int i, val = 0; int i, val = 0;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printAdjustmentRange(DUMP_MASTER, adjustmentProfile(), NULL); printAdjustmentRange(DUMP_MASTER, adjustmentProfile(), NULL);
@ -1713,7 +1803,7 @@ static void cliMotorMix(char *cmdline)
#else #else
int check = 0; int check = 0;
uint8_t len; uint8_t len;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printMotorMix(DUMP_MASTER, customMotorMixer(0), NULL); printMotorMix(DUMP_MASTER, customMotorMixer(0), NULL);
@ -1801,7 +1891,7 @@ static void printRxRange(uint8_t dumpMask, const rxConfig_t *rxConfig, const rxC
static void cliRxRange(char *cmdline) static void cliRxRange(char *cmdline)
{ {
int i, validArgumentCount = 0; int i, validArgumentCount = 0;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printRxRange(DUMP_MASTER, rxConfig(), NULL); printRxRange(DUMP_MASTER, rxConfig(), NULL);
@ -1863,7 +1953,7 @@ static void printLed(uint8_t dumpMask, const ledConfig_t *ledConfigs, const ledC
static void cliLed(char *cmdline) static void cliLed(char *cmdline)
{ {
int i; int i;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printLed(DUMP_MASTER, ledStripConfig()->ledConfigs, NULL); printLed(DUMP_MASTER, ledStripConfig()->ledConfigs, NULL);
@ -1901,7 +1991,7 @@ static void printColor(uint8_t dumpMask, const hsvColor_t *colors, const hsvColo
static void cliColor(char *cmdline) static void cliColor(char *cmdline)
{ {
int i; int i;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printColor(DUMP_MASTER, ledStripConfig()->colors, NULL); printColor(DUMP_MASTER, ledStripConfig()->colors, NULL);
@ -2179,10 +2269,8 @@ static void printServoMix(uint8_t dumpMask, const master_t *defaultConfig)
static void cliServoMix(char *cmdline) static void cliServoMix(char *cmdline)
{ {
uint8_t len;
char *ptr;
int args[8], check = 0; int args[8], check = 0;
len = strlen(cmdline); int len = strlen(cmdline);
if (len == 0) { if (len == 0) {
printServoMix(DUMP_MASTER, NULL); printServoMix(DUMP_MASTER, NULL);
@ -2193,7 +2281,7 @@ static void cliServoMix(char *cmdline)
servoProfile()->servoConf[i].reversedSources = 0; servoProfile()->servoConf[i].reversedSources = 0;
} }
} else if (strncasecmp(cmdline, "load", 4) == 0) { } else if (strncasecmp(cmdline, "load", 4) == 0) {
ptr = nextArg(cmdline); const char *ptr = nextArg(cmdline);
if (ptr) { if (ptr) {
len = strlen(ptr); len = strlen(ptr);
for (uint32_t i = 0; ; i++) { for (uint32_t i = 0; ; i++) {
@ -2211,7 +2299,7 @@ static void cliServoMix(char *cmdline)
} }
} else if (strncasecmp(cmdline, "reverse", 7) == 0) { } else if (strncasecmp(cmdline, "reverse", 7) == 0) {
enum {SERVO = 0, INPUT, REVERSE, ARGS_COUNT}; enum {SERVO = 0, INPUT, REVERSE, ARGS_COUNT};
ptr = strchr(cmdline, ' '); char *ptr = strchr(cmdline, ' ');
len = strlen(ptr); len = strlen(ptr);
if (len == 0) { if (len == 0) {
@ -2253,7 +2341,7 @@ static void cliServoMix(char *cmdline)
cliServoMix("reverse"); cliServoMix("reverse");
} else { } else {
enum {RULE = 0, TARGET, INPUT, RATE, SPEED, MIN, MAX, BOX, ARGS_COUNT}; enum {RULE = 0, TARGET, INPUT, RATE, SPEED, MIN, MAX, BOX, ARGS_COUNT};
ptr = strtok(cmdline, " "); char *ptr = strtok(cmdline, " ");
while (ptr != NULL && check < ARGS_COUNT) { while (ptr != NULL && check < ARGS_COUNT) {
args[check++] = atoi(ptr); args[check++] = atoi(ptr);
ptr = strtok(NULL, " "); ptr = strtok(NULL, " ");
@ -2427,7 +2515,7 @@ static void cliFlashRead(char *cmdline)
uint8_t buffer[32]; uint8_t buffer[32];
char *nextArg = strchr(cmdline, ' '); const char *nextArg = strchr(cmdline, ' ');
if (!nextArg) { if (!nextArg) {
cliShowParseError(); cliShowParseError();
@ -2496,7 +2584,7 @@ static void printVtx(uint8_t dumpMask, const master_t *defaultConfig)
static void cliVtx(char *cmdline) static void cliVtx(char *cmdline)
{ {
int i, val = 0; int i, val = 0;
char *ptr; const char *ptr;
if (isEmpty(cmdline)) { if (isEmpty(cmdline)) {
printVtx(DUMP_MASTER, NULL); printVtx(DUMP_MASTER, NULL);
@ -3067,7 +3155,13 @@ static void cliDumpProfile(uint8_t profileIndex, uint8_t dumpMask, const master_
cliPrintHashLine("profile"); cliPrintHashLine("profile");
cliProfile(""); cliProfile("");
cliPrint("\r\n"); cliPrint("\r\n");
#ifdef USE_PARAMETER_GROUPS
(void)(defaultConfig);
dumpAllValues(PROFILE_VALUE, dumpMask);
dumpAllValues(PROFILE_RATE_VALUE, dumpMask);
#else
dumpValues(PROFILE_VALUE, dumpMask, defaultConfig); dumpValues(PROFILE_VALUE, dumpMask, defaultConfig);
#endif
cliRateProfile(""); cliRateProfile("");
} }
@ -3688,7 +3782,7 @@ static void printConfig(char *cmdline, bool doDiff)
#endif #endif
cliPrintHashLine("rxfail"); cliPrintHashLine("rxfail");
printRxFail(dumpMask, rxConfig(), &defaultConfig.rxConfig); printRxFailsafe(dumpMask, rxConfig(), &defaultConfig.rxConfig);
cliPrintHashLine("master"); cliPrintHashLine("master");
dumpValues(MASTER_VALUE, dumpMask, &defaultConfig); dumpValues(MASTER_VALUE, dumpMask, &defaultConfig);
@ -3828,7 +3922,7 @@ const clicmd_t cmdTable[] = {
#if defined(USE_RESOURCE_MGMT) #if defined(USE_RESOURCE_MGMT)
CLI_COMMAND_DEF("resource", "show/set resources", NULL, cliResource), CLI_COMMAND_DEF("resource", "show/set resources", NULL, cliResource),
#endif #endif
CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFail), CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFailsafe),
CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange), CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange),
CLI_COMMAND_DEF("save", "save and reboot", NULL, cliSave), CLI_COMMAND_DEF("save", "save and reboot", NULL, cliSave),
#ifdef USE_SDCARD #ifdef USE_SDCARD