1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-14 20:10:18 +03:00

Add cli parameter bit setting type

Adds a new parameter mode `MODE_BITSET` that allows associating a cli parameter with a specific bit in a stored value. Bit packed values can be exposed with individual cli parameters for each bit as needed. Supports UINT8, UINT16 and newly added UINT32 data types (UINT32 not supported for other modes at this time).
This commit is contained in:
Bruce Luckcuck 2018-05-06 13:37:36 -04:00
parent 851ed5f597
commit aa4a8c7ec1
2 changed files with 94 additions and 24 deletions

View file

@ -371,6 +371,9 @@ static void printValuePointer(const clivalue_t *var, const void *valuePointer, b
case VAR_INT16:
value = *(int16_t *)valuePointer;
break;
case VAR_UINT32:
value = *(uint32_t *)valuePointer;
break;
}
switch (var->type & VALUE_MODE_MASK) {
@ -383,6 +386,12 @@ static void printValuePointer(const clivalue_t *var, const void *valuePointer, b
case MODE_LOOKUP:
cliPrint(lookupTables[var->config.lookup.tableIndex].values[value]);
break;
case MODE_BITSET:
if (value & 1 << var->config.bitpos) {
cliPrintf("ON");
} else {
cliPrintf("OFF");
}
}
}
}
@ -392,14 +401,18 @@ static bool valuePtrEqualsDefault(const clivalue_t *var, const void *ptr, const
{
bool result = true;
int elementCount = 1;
uint32_t mask = 0xffffffff;
if ((var->type & VALUE_MODE_MASK) == MODE_ARRAY) {
elementCount = var->config.array.length;
}
if ((var->type & VALUE_MODE_MASK) == MODE_BITSET) {
mask = 1 << var->config.bitpos;
}
for (int i = 0; i < elementCount; i++) {
switch (var->type & VALUE_TYPE_MASK) {
case VAR_UINT8:
result = result && ((uint8_t *)ptr)[i] == ((uint8_t *)ptrDefault)[i];
result = result && (((uint8_t *)ptr)[i] & mask) == (((uint8_t *)ptrDefault)[i] & mask);
break;
case VAR_INT8:
@ -407,9 +420,14 @@ static bool valuePtrEqualsDefault(const clivalue_t *var, const void *ptr, const
break;
case VAR_UINT16:
result = result && (((int16_t *)ptr)[i] & mask) == (((int16_t *)ptrDefault)[i] & mask);
break;
case VAR_INT16:
result = result && ((int16_t *)ptr)[i] == ((int16_t *)ptrDefault)[i];
break;
case VAR_UINT32:
result = result && (((uint32_t *)ptr)[i] & mask) == (((uint32_t *)ptrDefault)[i] & mask);
break;
}
}
@ -512,7 +530,10 @@ static void cliPrintVarRange(const clivalue_t *var)
case (MODE_ARRAY): {
cliPrintLinef("Array length: %d", var->config.array.length);
}
break;
case (MODE_BITSET): {
cliPrintLinef("Allowed values: OFF, ON");
}
break;
}
}
@ -520,7 +541,43 @@ static void cliPrintVarRange(const clivalue_t *var)
static void cliSetVar(const clivalue_t *var, const int16_t value)
{
void *ptr = cliGetValuePointer(var);
uint32_t workValue;
uint32_t mask;
if ((var->type & VALUE_MODE_MASK) == MODE_BITSET) {
switch (var->type & VALUE_TYPE_MASK) {
case VAR_UINT8:
mask = (1 << var->config.bitpos) & 0xff;
if (value) {
workValue = *(uint8_t *)ptr | mask;
} else {
workValue = *(uint8_t *)ptr & ~mask;
}
*(uint8_t *)ptr = workValue;
break;
case VAR_UINT16:
mask = (1 << var->config.bitpos) & 0xffff;
if (value) {
workValue = *(uint16_t *)ptr | mask;
} else {
workValue = *(uint16_t *)ptr & ~mask;
}
*(uint16_t *)ptr = workValue;
break;
case VAR_UINT32:
mask = 1 << var->config.bitpos;
if (value) {
workValue = *(uint32_t *)ptr | mask;
} else {
workValue = *(uint32_t *)ptr & ~mask;
}
*(uint32_t *)ptr = workValue;
break;
}
} else {
switch (var->type & VALUE_TYPE_MASK) {
case VAR_UINT8:
*(uint8_t *)ptr = value;
@ -536,6 +593,7 @@ static void cliSetVar(const clivalue_t *var, const int16_t value)
break;
}
}
}
#if defined(USE_RESOURCE_MGMT) && !defined(MINIMAL_CLI)
static void cliRepeat(char ch, uint8_t len)
@ -3032,8 +3090,15 @@ STATIC_UNIT_TESTED void cliSet(char *cmdline)
}
break;
case MODE_LOOKUP: {
const lookupTableEntry_t *tableEntry = &lookupTables[val->config.lookup.tableIndex];
case MODE_LOOKUP:
case MODE_BITSET: {
int tableIndex;
if ((val->type & VALUE_MODE_MASK) == MODE_BITSET) {
tableIndex = TABLE_OFF_ON;
} else {
tableIndex = val->config.lookup.tableIndex;
}
const lookupTableEntry_t *tableEntry = &lookupTables[tableIndex];
bool matched = false;
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->valueCount && !matched; tableValueIndex++) {
matched = tableEntry->values[tableValueIndex] && strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0;
@ -3048,6 +3113,7 @@ STATIC_UNIT_TESTED void cliSet(char *cmdline)
}
break;
case MODE_ARRAY: {
const uint8_t arrayLength = val->config.array.length;
char *valPtr = eqptr;
@ -3111,6 +3177,7 @@ STATIC_UNIT_TESTED void cliSet(char *cmdline)
valueChanged = true;
break;
}
if (valueChanged) {

View file

@ -104,31 +104,33 @@ typedef struct lookupTableEntry_s {
#define VALUE_TYPE_OFFSET 0
#define VALUE_SECTION_OFFSET 2
#define VALUE_MODE_OFFSET 4
#define VALUE_SECTION_OFFSET 3
#define VALUE_MODE_OFFSET 5
typedef enum {
// value type, bits 0-1
// value type, bits 0-2
VAR_UINT8 = (0 << VALUE_TYPE_OFFSET),
VAR_INT8 = (1 << VALUE_TYPE_OFFSET),
VAR_UINT16 = (2 << VALUE_TYPE_OFFSET),
VAR_INT16 = (3 << VALUE_TYPE_OFFSET),
VAR_UINT32 = (4 << VALUE_TYPE_OFFSET),
// value section, bits 2-3
// value section, bits 3-4
MASTER_VALUE = (0 << VALUE_SECTION_OFFSET),
PROFILE_VALUE = (1 << VALUE_SECTION_OFFSET),
PROFILE_RATE_VALUE = (2 << VALUE_SECTION_OFFSET),
// value mode, bits 4-5
// value mode, bits 5-6
MODE_DIRECT = (0 << VALUE_MODE_OFFSET),
MODE_LOOKUP = (1 << VALUE_MODE_OFFSET),
MODE_ARRAY = (2 << VALUE_MODE_OFFSET)
MODE_ARRAY = (2 << VALUE_MODE_OFFSET),
MODE_BITSET = (3 << VALUE_MODE_OFFSET)
} cliValueFlag_e;
#define VALUE_TYPE_MASK (0x03)
#define VALUE_SECTION_MASK (0x0c)
#define VALUE_MODE_MASK (0x30)
#define VALUE_TYPE_MASK (0x07)
#define VALUE_SECTION_MASK (0x18)
#define VALUE_MODE_MASK (0x60)
typedef struct cliMinMaxConfig_s {
const int16_t min;
@ -147,6 +149,7 @@ typedef union {
cliLookupTableConfig_t lookup;
cliMinMaxConfig_t minmax;
cliArrayLengthConfig_t array;
uint8_t bitpos;
} cliValueConfig_t;
typedef struct clivalue_s {