Added support for array variables to CLI.
This commit is contained in:
parent
1388c3ee82
commit
a5b428ae4f
|
@ -293,33 +293,44 @@ static void cliPrintLinef(const char *format, ...)
|
||||||
|
|
||||||
static void printValuePointer(const clivalue_t *var, const void *valuePointer, bool full)
|
static void printValuePointer(const clivalue_t *var, const void *valuePointer, bool full)
|
||||||
{
|
{
|
||||||
int value = 0;
|
if ((var->type & VALUE_MODE_MASK) == MODE_ARRAY) {
|
||||||
|
for (int i = 0; i < var->config.array.length; i++) {
|
||||||
|
uint8_t value = ((uint8_t *)valuePointer)[i];
|
||||||
|
|
||||||
switch (var->type & VALUE_TYPE_MASK) {
|
cliPrintf("%d", value);
|
||||||
case VAR_UINT8:
|
if (i < var->config.array.length - 1) {
|
||||||
value = *(uint8_t *)valuePointer;
|
cliPrint(", ");
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
case VAR_INT8:
|
} else {
|
||||||
value = *(int8_t *)valuePointer;
|
int value = 0;
|
||||||
break;
|
|
||||||
|
switch (var->type & VALUE_TYPE_MASK) {
|
||||||
case VAR_UINT16:
|
case VAR_UINT8:
|
||||||
case VAR_INT16:
|
value = *(uint8_t *)valuePointer;
|
||||||
value = *(int16_t *)valuePointer;
|
break;
|
||||||
break;
|
|
||||||
}
|
case VAR_INT8:
|
||||||
|
value = *(int8_t *)valuePointer;
|
||||||
switch(var->type & VALUE_MODE_MASK) {
|
break;
|
||||||
case MODE_DIRECT:
|
|
||||||
cliPrintf("%d", value);
|
case VAR_UINT16:
|
||||||
if (full) {
|
case VAR_INT16:
|
||||||
cliPrintf(" %d %d", var->config.minmax.min, var->config.minmax.max);
|
value = *(int16_t *)valuePointer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(var->type & VALUE_MODE_MASK) {
|
||||||
|
case MODE_DIRECT:
|
||||||
|
cliPrintf("%d", value);
|
||||||
|
if (full) {
|
||||||
|
cliPrintf(" %d %d", var->config.minmax.min, var->config.minmax.max);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_LOOKUP:
|
||||||
|
cliPrint(lookupTables[var->config.lookup.tableIndex].values[value]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case MODE_LOOKUP:
|
|
||||||
cliPrint(lookupTables[var->config.lookup.tableIndex].values[value]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,14 +388,15 @@ static void dumpPgValue(const clivalue_t *value, uint8_t dumpMask)
|
||||||
const char *defaultFormat = "#set %s = ";
|
const char *defaultFormat = "#set %s = ";
|
||||||
const int valueOffset = getValueOffset(value);
|
const int valueOffset = getValueOffset(value);
|
||||||
const bool equalsDefault = valuePtrEqualsDefault(value->type, pg->copy + valueOffset, pg->address + valueOffset);
|
const bool equalsDefault = valuePtrEqualsDefault(value->type, pg->copy + valueOffset, pg->address + valueOffset);
|
||||||
|
|
||||||
if (((dumpMask & DO_DIFF) == 0) || !equalsDefault) {
|
if (((dumpMask & DO_DIFF) == 0) || !equalsDefault) {
|
||||||
if (dumpMask & SHOW_DEFAULTS && !equalsDefault) {
|
if (dumpMask & SHOW_DEFAULTS && !equalsDefault) {
|
||||||
cliPrintf(defaultFormat, value->name);
|
cliPrintf(defaultFormat, value->name);
|
||||||
printValuePointer(value, (uint8_t*)pg->address + valueOffset, 0);
|
printValuePointer(value, (uint8_t*)pg->address + valueOffset, false);
|
||||||
cliPrintLinefeed();
|
cliPrintLinefeed();
|
||||||
}
|
}
|
||||||
cliPrintf(format, value->name);
|
cliPrintf(format, value->name);
|
||||||
printValuePointer(value, pg->copy + valueOffset, 0);
|
printValuePointer(value, pg->copy + valueOffset, false);
|
||||||
cliPrintLinefeed();
|
cliPrintLinefeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,26 +436,31 @@ static void cliPrintVarRange(const clivalue_t *var)
|
||||||
}
|
}
|
||||||
cliPrintLinefeed();
|
cliPrintLinefeed();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case (MODE_ARRAY): {
|
||||||
|
cliPrintLinef("Array length: %d", var->config.array.length);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cliSetVar(const clivalue_t *var, const cliVar_t value)
|
static void cliSetVar(const clivalue_t *var, const int16_t value)
|
||||||
{
|
{
|
||||||
void *ptr = getValuePointer(var);
|
void *ptr = getValuePointer(var);
|
||||||
|
|
||||||
switch (var->type & VALUE_TYPE_MASK) {
|
switch (var->type & VALUE_TYPE_MASK) {
|
||||||
case VAR_UINT8:
|
case VAR_UINT8:
|
||||||
*(uint8_t *)ptr = value.uint8;
|
*(uint8_t *)ptr = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_INT8:
|
case VAR_INT8:
|
||||||
*(int8_t *)ptr = value.int8;
|
*(int8_t *)ptr = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_UINT16:
|
case VAR_UINT16:
|
||||||
case VAR_INT16:
|
case VAR_INT16:
|
||||||
*(int16_t *)ptr = value.int16;
|
*(int16_t *)ptr = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2507,18 +2524,34 @@ static void cliGet(char *cmdline)
|
||||||
cliPrintLine("Invalid name");
|
cliPrintLine("Invalid name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *skipSpace(char *buffer)
|
||||||
|
{
|
||||||
|
while (*(buffer) == ' ') {
|
||||||
|
buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t getWordLength(char *bufBegin, char *bufEnd)
|
||||||
|
{
|
||||||
|
while (*(bufEnd - 1) == ' ') {
|
||||||
|
bufEnd--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufEnd - bufBegin;
|
||||||
|
}
|
||||||
|
|
||||||
static void cliSet(char *cmdline)
|
static void cliSet(char *cmdline)
|
||||||
{
|
{
|
||||||
uint32_t len;
|
const uint32_t len = strlen(cmdline);
|
||||||
const clivalue_t *val;
|
char *eqptr;
|
||||||
char *eqptr = NULL;
|
|
||||||
|
|
||||||
len = strlen(cmdline);
|
|
||||||
|
|
||||||
if (len == 0 || (len == 1 && cmdline[0] == '*')) {
|
if (len == 0 || (len == 1 && cmdline[0] == '*')) {
|
||||||
cliPrintLine("Current settings: ");
|
cliPrintLine("Current settings: ");
|
||||||
|
|
||||||
for (uint32_t i = 0; i < valueTableEntryCount; i++) {
|
for (uint32_t i = 0; i < valueTableEntryCount; i++) {
|
||||||
val = &valueTable[i];
|
const clivalue_t *val = &valueTable[i];
|
||||||
cliPrintf("%s = ", valueTable[i].name);
|
cliPrintf("%s = ", valueTable[i].name);
|
||||||
cliPrintVar(val, len); // when len is 1 (when * is passed as argument), it will print min/max values as well, for gui
|
cliPrintVar(val, len); // when len is 1 (when * is passed as argument), it will print min/max values as well, for gui
|
||||||
cliPrintLinefeed();
|
cliPrintLinefeed();
|
||||||
|
@ -2526,52 +2559,81 @@ static void cliSet(char *cmdline)
|
||||||
} else if ((eqptr = strstr(cmdline, "=")) != NULL) {
|
} else if ((eqptr = strstr(cmdline, "=")) != NULL) {
|
||||||
// has equals
|
// has equals
|
||||||
|
|
||||||
char *lastNonSpaceCharacter = eqptr;
|
uint8_t variableNameLength = getWordLength(cmdline, eqptr);
|
||||||
while (*(lastNonSpaceCharacter - 1) == ' ') {
|
|
||||||
lastNonSpaceCharacter--;
|
|
||||||
}
|
|
||||||
uint8_t variableNameLength = lastNonSpaceCharacter - cmdline;
|
|
||||||
|
|
||||||
// skip the '=' and any ' ' characters
|
// skip the '=' and any ' ' characters
|
||||||
eqptr++;
|
eqptr++;
|
||||||
while (*(eqptr) == ' ') {
|
eqptr = skipSpace(eqptr);
|
||||||
eqptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < valueTableEntryCount; i++) {
|
for (uint32_t i = 0; i < valueTableEntryCount; i++) {
|
||||||
val = &valueTable[i];
|
const clivalue_t *val = &valueTable[i];
|
||||||
// ensure exact match when setting to prevent setting variables with shorter names
|
// ensure exact match when setting to prevent setting variables with shorter names
|
||||||
if (strncasecmp(cmdline, valueTable[i].name, strlen(valueTable[i].name)) == 0 && variableNameLength == strlen(valueTable[i].name)) {
|
if (strncasecmp(cmdline, valueTable[i].name, strlen(valueTable[i].name)) == 0 && variableNameLength == strlen(valueTable[i].name)) {
|
||||||
|
|
||||||
bool changeValue = false;
|
bool valueChanged = false;
|
||||||
cliVar_t value = { .int16 = 0 };
|
int16_t value = 0;
|
||||||
switch (valueTable[i].type & VALUE_MODE_MASK) {
|
switch (valueTable[i].type & VALUE_MODE_MASK) {
|
||||||
case MODE_DIRECT: {
|
case MODE_DIRECT: {
|
||||||
value.int16 = atoi(eqptr);
|
int16_t value = atoi(eqptr);
|
||||||
|
|
||||||
if (value.int16 >= valueTable[i].config.minmax.min && value.int16 <= valueTable[i].config.minmax.max) {
|
if (value >= valueTable[i].config.minmax.min && value <= valueTable[i].config.minmax.max) {
|
||||||
changeValue = true;
|
cliSetVar(val, value);
|
||||||
}
|
valueChanged = true;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case MODE_LOOKUP: {
|
case MODE_LOOKUP: {
|
||||||
const lookupTableEntry_t *tableEntry = &lookupTables[valueTable[i].config.lookup.tableIndex];
|
const lookupTableEntry_t *tableEntry = &lookupTables[valueTable[i].config.lookup.tableIndex];
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->valueCount && !matched; tableValueIndex++) {
|
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->valueCount && !matched; tableValueIndex++) {
|
||||||
matched = strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0;
|
matched = strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0;
|
||||||
|
|
||||||
if (matched) {
|
if (matched) {
|
||||||
value.int16 = tableValueIndex;
|
value = tableValueIndex;
|
||||||
changeValue = true;
|
|
||||||
}
|
cliSetVar(val, value);
|
||||||
|
valueChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MODE_ARRAY: {
|
||||||
|
const uint8_t arrayLength = valueTable[i].config.array.length;
|
||||||
|
char *valPtr = eqptr;
|
||||||
|
uint8_t array[256];
|
||||||
|
char curVal[4];
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
valPtr = skipSpace(valPtr);
|
||||||
|
char *valEnd = strstr(valPtr, ",");
|
||||||
|
if ((valEnd != NULL) && (i < arrayLength - 1)) {
|
||||||
|
uint8_t varLength = getWordLength(valPtr, valEnd);
|
||||||
|
if (varLength <= 3) {
|
||||||
|
strncpy(curVal, valPtr, getWordLength(valPtr, valEnd));
|
||||||
|
curVal[varLength] = '\0';
|
||||||
|
array[i] = (uint8_t)atoi((const char *)curVal);
|
||||||
|
valPtr = valEnd + 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if ((valEnd == NULL) && (i == arrayLength - 1)) {
|
||||||
|
array[i] = atoi(valPtr);
|
||||||
|
|
||||||
|
uint8_t *ptr = getValuePointer(val);
|
||||||
|
memcpy(ptr, array, arrayLength);
|
||||||
|
valueChanged = true;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeValue) {
|
if (valueChanged) {
|
||||||
cliSetVar(val, value);
|
|
||||||
|
|
||||||
cliPrintf("%s set to ", valueTable[i].name);
|
cliPrintf("%s set to ", valueTable[i].name);
|
||||||
cliPrintVar(val, 0);
|
cliPrintVar(val, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -69,34 +69,31 @@ typedef struct lookupTableEntry_s {
|
||||||
|
|
||||||
|
|
||||||
#define VALUE_TYPE_OFFSET 0
|
#define VALUE_TYPE_OFFSET 0
|
||||||
#define VALUE_SECTION_OFFSET 4
|
#define VALUE_SECTION_OFFSET 2
|
||||||
#define VALUE_MODE_OFFSET 6
|
#define VALUE_MODE_OFFSET 4
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
// value type, bits 0-3
|
// value type, bits 0-1
|
||||||
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),
|
||||||
|
|
||||||
// value section, bits 4-5
|
// value section, bits 2-3
|
||||||
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), // 0x20
|
PROFILE_RATE_VALUE = (2 << VALUE_SECTION_OFFSET),
|
||||||
// value mode
|
|
||||||
MODE_DIRECT = (0 << VALUE_MODE_OFFSET), // 0x40
|
// value mode, bits 4-5
|
||||||
MODE_LOOKUP = (1 << VALUE_MODE_OFFSET) // 0x80
|
MODE_DIRECT = (0 << VALUE_MODE_OFFSET),
|
||||||
|
MODE_LOOKUP = (1 << VALUE_MODE_OFFSET),
|
||||||
|
MODE_ARRAY = (2 << VALUE_MODE_OFFSET)
|
||||||
} cliValueFlag_e;
|
} cliValueFlag_e;
|
||||||
|
|
||||||
#define VALUE_TYPE_MASK (0x0F)
|
|
||||||
#define VALUE_SECTION_MASK (0x30)
|
|
||||||
#define VALUE_MODE_MASK (0xC0)
|
|
||||||
|
|
||||||
typedef union {
|
#define VALUE_TYPE_MASK (0x03)
|
||||||
int8_t int8;
|
#define VALUE_SECTION_MASK (0x0c)
|
||||||
uint8_t uint8;
|
#define VALUE_MODE_MASK (0x30)
|
||||||
int16_t int16;
|
|
||||||
} cliVar_t;
|
|
||||||
|
|
||||||
typedef struct cliMinMaxConfig_s {
|
typedef struct cliMinMaxConfig_s {
|
||||||
const int16_t min;
|
const int16_t min;
|
||||||
|
@ -107,9 +104,14 @@ typedef struct cliLookupTableConfig_s {
|
||||||
const lookupTableIndex_e tableIndex;
|
const lookupTableIndex_e tableIndex;
|
||||||
} cliLookupTableConfig_t;
|
} cliLookupTableConfig_t;
|
||||||
|
|
||||||
|
typedef struct cliArrayLengthConfig_s {
|
||||||
|
const uint8_t length;
|
||||||
|
} cliArrayLengthConfig_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
cliLookupTableConfig_t lookup;
|
cliLookupTableConfig_t lookup;
|
||||||
cliMinMaxConfig_t minmax;
|
cliMinMaxConfig_t minmax;
|
||||||
|
cliArrayLengthConfig_t array;
|
||||||
} cliValueConfig_t;
|
} cliValueConfig_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue