1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-23 08:15:26 +03:00

Merge pull request #3548 from iNavFlight/agh_settings_info

Add support for retriving setting types and listing all of them
This commit is contained in:
Alberto García Hierro 2018-07-09 23:31:45 +01:00 committed by GitHub
commit 6b6b49451b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 202 additions and 34 deletions

View file

@ -428,7 +428,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
if (IS_PRINTVALUE(p, screenRow) && p->data) {
buff[0] = '\0';
const OSD_SETTING_t *ptr = p->data;
const setting_t *var = &settingsTable[ptr->val];
const setting_t *var = settingGet(ptr->val);
int32_t value;
const void *valuePointer = settingGetValuePointer(var);
switch (SETTING_TYPE(var)) {
@ -476,13 +476,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
break;
case MODE_LOOKUP:
{
const char *str = NULL;
if (var->config.lookup.tableIndex < LOOKUP_TABLE_COUNT) {
const lookupTableEntry_t *tableEntry = &settingLookupTables[var->config.lookup.tableIndex];
if (value < tableEntry->valueCount) {
str = tableEntry->values[value];
}
}
const char *str = settingLookupValueName(var, value);
strncpy(buff, str ? str : "INVALID", sizeof(buff) - 1);
}
break;
@ -1008,7 +1002,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_Setting:
if (p->data) {
const OSD_SETTING_t *ptr = p->data;
const setting_t *var = &settingsTable[ptr->val];
const setting_t *var = settingGet(ptr->val);
setting_min_t min = settingGetMin(var);
setting_max_t max = settingGetMax(var);
float step = ptr->step ?: 1;

View file

@ -113,3 +113,7 @@
#define PG_RESERVED_FOR_TESTING_2 4094
#define PG_RESERVED_FOR_TESTING_3 4093
#define PG_ID_INVALID 0
#define PG_ID_FIRST PG_CF_START
#define PG_ID_LAST PG_INAV_END

View file

@ -352,14 +352,17 @@ static void printValuePointer(const setting_t *var, const void *valuePointer, ui
}
break;
case MODE_LOOKUP:
if (var->config.lookup.tableIndex < LOOKUP_TABLE_COUNT) {
cliPrintf(settingLookupTables[var->config.lookup.tableIndex].values[value]);
{
const char *name = settingLookupValueName(var, value);
if (name) {
cliPrintf(name);
} else {
settingGetName(var, buf);
cliPrintLinef("VALUE %s OUT OF RANGE", buf);
cliPrintLinef("VALUE %d OUT OF RANGE FOR %s", (int)value, buf);
}
break;
}
}
}
static bool valuePtrEqualsDefault(const setting_t *value, const void *ptr, const void *ptrDefault)
@ -425,8 +428,8 @@ static void dumpPgValue(const setting_t *value, uint8_t dumpMask)
static void dumpAllValues(uint16_t valueSection, uint8_t dumpMask)
{
for (uint32_t i = 0; i < SETTINGS_TABLE_COUNT; i++) {
const setting_t *value = &settingsTable[i];
for (unsigned i = 0; i < SETTINGS_TABLE_COUNT; i++) {
const setting_t *value = settingGet(i);
bufWriterFlush(cliWriter);
if (SETTING_SECTION(value) == valueSection) {
dumpPgValue(value, dumpMask);
@ -453,7 +456,7 @@ static void cliPrintVarRange(const setting_t *var)
break;
case MODE_LOOKUP:
{
const lookupTableEntry_t *tableEntry = &settingLookupTables[var->config.lookup.tableIndex];
const lookupTableEntry_t *tableEntry = settingLookupTable(var);
cliPrint("Allowed values:");
for (uint32_t i = 0; i < tableEntry->valueCount ; i++) {
if (i > 0)
@ -2256,7 +2259,7 @@ static void cliGet(char *cmdline)
char name[SETTING_MAX_NAME_LENGTH];
for (uint32_t i = 0; i < SETTINGS_TABLE_COUNT; i++) {
val = &settingsTable[i];
val = settingGet(i);
if (settingNameContains(val, name, cmdline)) {
cliPrintf("%s = ", name);
cliPrintVar(val, 0);
@ -2288,7 +2291,7 @@ static void cliSet(char *cmdline)
if (len == 0 || (len == 1 && cmdline[0] == '*')) {
cliPrintLine("Current settings:");
for (uint32_t i = 0; i < SETTINGS_TABLE_COUNT; i++) {
val = &settingsTable[i];
val = settingGet(i);
settingGetName(val, name);
cliPrintf("%s = ", name);
cliPrintVar(val, len); // when len is 1 (when * is passed as argument), it will print min/max values as well, for gui
@ -2310,7 +2313,7 @@ static void cliSet(char *cmdline)
}
for (uint32_t i = 0; i < SETTINGS_TABLE_COUNT; i++) {
val = &settingsTable[i];
val = settingGet(i);
// ensure exact match when setting to prevent setting variables with shorter names
if (settingNameIsExactMatch(val, name, cmdline, variableNameLength)) {
const setting_type_e type = SETTING_TYPE(val);
@ -2341,7 +2344,7 @@ static void cliSet(char *cmdline)
}
break;
case MODE_LOOKUP: {
const lookupTableEntry_t *tableEntry = &settingLookupTables[settingsTable[i].config.lookup.tableIndex];
const lookupTableEntry_t *tableEntry = settingLookupTable(val);
bool matched = false;
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->valueCount && !matched; tableValueIndex++) {
matched = sl_strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0;

View file

@ -35,6 +35,8 @@
#include "common/time.h"
#include "common/utils.h"
#include "config/parameter_group_ids.h"
#include "drivers/accgyro/accgyro.h"
#include "drivers/bus_i2c.h"
#include "drivers/compass/compass.h"
@ -2549,9 +2551,10 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
return MSP_RESULT_ACK;
}
static const setting_t *mspReadSettingName(sbuf_t *src)
static const setting_t *mspReadSetting(sbuf_t *src)
{
char name[SETTING_MAX_NAME_LENGTH];
uint16_t id;
uint8_t c;
size_t s = 0;
while (1) {
@ -2560,6 +2563,14 @@ static const setting_t *mspReadSettingName(sbuf_t *src)
}
name[s++] = c;
if (c == '\0') {
if (s == 1) {
// Payload starts with a zero, setting index
// as uint16_t follows
if (sbufReadU16Safe(&id, src)) {
return settingGet(id);
}
return NULL;
}
break;
}
if (s == SETTING_MAX_NAME_LENGTH) {
@ -2572,7 +2583,7 @@ static const setting_t *mspReadSettingName(sbuf_t *src)
static bool mspSettingCommand(sbuf_t *dst, sbuf_t *src)
{
const setting_t *setting = mspReadSettingName(src);
const setting_t *setting = mspReadSetting(src);
if (!setting) {
return false;
}
@ -2587,7 +2598,7 @@ static bool mspSetSettingCommand(sbuf_t *dst, sbuf_t *src)
{
UNUSED(dst);
const setting_t *setting = mspReadSettingName(src);
const setting_t *setting = mspReadSetting(src);
if (!setting) {
return false;
}
@ -2679,6 +2690,94 @@ static bool mspSetSettingCommand(sbuf_t *dst, sbuf_t *src)
return true;
}
static bool mspSettingInfoCommand(sbuf_t *dst, sbuf_t *src)
{
const setting_t *setting = mspReadSetting(src);
if (!setting) {
return false;
}
// Parameter Group ID
sbufWriteU16(dst, settingGetPgn(setting));
// Type, section and mode
sbufWriteU8(dst, SETTING_TYPE(setting));
sbufWriteU8(dst, SETTING_SECTION(setting));
sbufWriteU8(dst, SETTING_MODE(setting));
// Min as int32_t
int32_t min = settingGetMin(setting);
sbufWriteU32(dst, (uint32_t)min);
// Max as uint32_t
uint32_t max = settingGetMax(setting);
sbufWriteU32(dst, max);
// Absolute setting index
sbufWriteU16(dst, settingGetIndex(setting));
// If the setting is profile based, send the current one
// and the count, both as uint8_t. For MASTER_VALUE, we
// send two zeroes, so the MSP client can assume there
// will always be two bytes.
switch (SETTING_SECTION(setting)) {
case MASTER_VALUE:
sbufWriteU8(dst, 0);
sbufWriteU8(dst, 0);
break;
case PROFILE_VALUE:
FALLTHROUGH;
case CONTROL_RATE_VALUE:
sbufWriteU8(dst, getConfigProfile());
sbufWriteU8(dst, MAX_PROFILE_COUNT);
break;
case BATTERY_CONFIG_VALUE:
sbufWriteU8(dst, getConfigBatteryProfile());
sbufWriteU8(dst, MAX_BATTERY_PROFILE_COUNT);
break;
}
// If the setting uses a table, send each possible string (null terminated)
if (SETTING_MODE(setting) == MODE_LOOKUP) {
for (int ii = (int)min; ii <= (int)max; ii++) {
const char *name = settingLookupValueName(setting, ii);
sbufWriteDataSafe(dst, name, strlen(name) + 1);
}
}
// Finally, include the setting value. This way resource constrained callers
// (e.g. a script in the radio) don't need to perform another call to retrieve
// the value.
const void *ptr = settingGetValuePointer(setting);
size_t size = settingGetValueSize(setting);
sbufWriteDataSafe(dst, ptr, size);
return true;
}
static bool mspParameterGroupsCommand(sbuf_t *dst, sbuf_t *src)
{
uint16_t first;
uint16_t last;
uint16_t start;
uint16_t end;
if (sbufReadU16Safe(&first, src)) {
last = first;
} else {
first = PG_ID_FIRST;
last = PG_ID_LAST;
}
for (int ii = first; ii <= last; ii++) {
if (settingsGetParameterGroupIndexes(ii, &start, &end)) {
sbufWriteU16(dst, ii);
sbufWriteU16(dst, start);
sbufWriteU16(dst, end);
}
}
return true;
}
bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResult_e *ret)
{
switch (cmdMSP) {
@ -2705,6 +2804,14 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
*ret = mspSetSettingCommand(dst, src) ? MSP_RESULT_ACK : MSP_RESULT_ERROR;
break;
case MSP2_COMMON_SETTING_INFO:
*ret = mspSettingInfoCommand(dst, src) ? MSP_RESULT_ACK : MSP_RESULT_ERROR;
break;
case MSP2_COMMON_PG_LIST:
*ret = mspParameterGroupsCommand(dst, src) ? MSP_RESULT_ACK : MSP_RESULT_ERROR;
break;
#if defined(USE_OSD)
case MSP2_INAV_OSD_LAYOUTS:
if (sbufBytesRemaining(src) >= 1) {

View file

@ -77,6 +77,16 @@ const setting_t *settingFind(const char *name)
return NULL;
}
const setting_t *settingGet(unsigned index)
{
return index < SETTINGS_TABLE_COUNT ? &settingsTable[index] : NULL;
}
unsigned settingGetIndex(const setting_t *val)
{
return val - settingsTable;
}
size_t settingGetValueSize(const setting_t *val)
{
switch (SETTING_TYPE(val)) {
@ -154,6 +164,23 @@ setting_max_t settingGetMax(const setting_t *val)
return settingMinMaxTable[SETTING_INDEXES_GET_MAX(val)];
}
const lookupTableEntry_t * settingLookupTable(const setting_t *val)
{
if (SETTING_MODE(val) == MODE_LOOKUP && val->config.lookup.tableIndex < LOOKUP_TABLE_COUNT) {
return &settingLookupTables[val->config.lookup.tableIndex];
}
return NULL;
}
const char * settingLookupValueName(const setting_t *val, unsigned v)
{
const lookupTableEntry_t *table = settingLookupTable(val);
if (table && v < table->valueCount) {
return table->values[v];
}
return NULL;
}
const char * settingGetString(const setting_t *val)
{
if (SETTING_TYPE(val) == VAR_STRING) {
@ -180,3 +207,21 @@ setting_max_t settingGetStringMaxLength(const setting_t *val)
}
return 0;
}
bool settingsGetParameterGroupIndexes(pgn_t pg, uint16_t *start, uint16_t *end)
{
unsigned acc = 0;
for (int ii = 0; ii < SETTINGS_PGN_COUNT; ii++) {
if (settingsPgn[ii] == pg) {
if (start) {
*start = acc;
}
if (end) {
*end = acc + settingsPgnCounts[ii] - 1;
}
return true;
}
acc += settingsPgnCounts[ii];
}
return false;
}

View file

@ -13,8 +13,6 @@ typedef struct lookupTableEntry_s {
const uint8_t valueCount;
} lookupTableEntry_t;
extern const lookupTableEntry_t settingLookupTables[];
#define SETTING_TYPE_OFFSET 0
#define SETTING_SECTION_OFFSET 4
#define SETTING_MODE_OFFSET 6
@ -69,8 +67,6 @@ typedef struct {
} __attribute__((packed)) setting_t;
extern const setting_t settingsTable[];
static inline setting_type_e SETTING_TYPE(const setting_t *s) { return s->type & SETTING_TYPE_MASK; }
static inline setting_section_e SETTING_SECTION(const setting_t *s) { return s->type & SETTING_SECTION_MASK; }
static inline setting_mode_e SETTING_MODE(const setting_t *s) { return s->type & SETTING_MODE_MASK; }
@ -81,6 +77,11 @@ bool settingNameIsExactMatch(const setting_t *val, char *buf, const char *cmdlin
// Returns a setting_t with the exact name (case sensitive), or
// NULL if no setting with that name exists.
const setting_t *settingFind(const char *name);
// Returns the setting at the given index, or NULL if
// the index is greater than the total count.
const setting_t *settingGet(unsigned index);
// Returns the setting index for the given setting.
unsigned settingGetIndex(const setting_t *val);
// Returns the size in bytes of the setting value.
size_t settingGetValueSize(const setting_t *val);
pgn_t settingGetPgn(const setting_t *val);
@ -100,6 +101,13 @@ setting_min_t settingGetMin(const setting_t *val);
// depends on the target and build options, but will always be an unsigned
// integer (e.g. uintxx_t,)
setting_max_t settingGetMax(const setting_t *val);
// Returns the lookup table for the given setting. If the setting mode
// is not MODE_LOOKUP, it returns NULL;
const lookupTableEntry_t * settingLookupTable(const setting_t *val);
// Returns the string in the table which corresponds to the value v
// for the given setting. If the setting mode is not MODE_LOOKUP or
// if the value is out of range, it returns NULL.
const char * settingLookupValueName(const setting_t *val, unsigned v);
// Returns the setting value as a const char * iff the setting is of type
// VAR_STRING. Otherwise it returns NULL.
const char * settingGetString(const setting_t *val);
@ -109,4 +117,8 @@ const char * settingGetString(const setting_t *val);
void settingSetString(const setting_t *val, const char *s, size_t size);
// Returns the max string length (without counting the '\0' terminator)
// for setting of type VAR_STRING. Otherwise it returns 0.
setting_max_t settingGetStringMaxLength(const setting_t *val);
setting_max_t settingGetStringMaxLength(const setting_t *val);
// Retrieve the setting indexes for the given PG. If the PG is not
// found, these function returns false.
bool settingsGetParameterGroupIndexes(pgn_t pg, uint16_t *start, uint16_t *end);

View file

@ -15,10 +15,13 @@
* along with INAV. If not, see <http://www.gnu.org/licenses/>.
*/
#define MSP2_COMMON_TZ 0x1001 //out message Gets the TZ offset for the local time (returns: minutes(i16))
#define MSP2_COMMON_SET_TZ 0x1002 //in message Sets the TZ offset for the local time (args: minutes(i16))
#define MSP2_COMMON_SETTING 0x1003 //in/out message Returns the value for a setting
#define MSP2_COMMON_SET_SETTING 0x1004 //in message Sets the value for a setting
#define MSP2_COMMON_TZ 0x1001 //out message Gets the TZ offset for the local time (returns: minutes(i16))
#define MSP2_COMMON_SET_TZ 0x1002 //in message Sets the TZ offset for the local time (args: minutes(i16))
#define MSP2_COMMON_SETTING 0x1003 //in/out message Returns the value for a setting
#define MSP2_COMMON_SET_SETTING 0x1004 //in message Sets the value for a setting
#define MSP2_COMMON_MOTOR_MIXER 0x1005
#define MSP2_COMMON_SET_MOTOR_MIXER 0x1006
#define MSP2_COMMON_SETTING_INFO 0x1007 //in/out message Returns info about a setting (PG, type, flags, min/max, etc..).
#define MSP2_COMMON_PG_LIST 0x1008 //in/out message Returns a list of the PG ids used by the settings

View file

@ -468,7 +468,7 @@ class Generator
buf << "};\n"
end
buf << "const lookupTableEntry_t settingLookupTables[] = {\n"
buf << "static const lookupTableEntry_t settingLookupTables[] = {\n"
table_names.each do |name|
vn = table_variable_name(name)
buf << "\t{ #{vn}, sizeof(#{vn}) / sizeof(char*) },\n"
@ -476,7 +476,7 @@ class Generator
buf << "};\n"
# Write min/max values table
buf << "const uint32_t settingMinMaxTable[] = {\n"
buf << "static const uint32_t settingMinMaxTable[] = {\n"
@value_encoder.values.each do |v|
buf << "\t#{v},\n"
end
@ -492,7 +492,7 @@ class Generator
end
# Write setting_t values
buf << "const setting_t settingsTable[] = {\n"
buf << "static const setting_t settingsTable[] = {\n"
last_group = nil
foreach_enabled_member do |group, member|