1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-24 00:35:34 +03:00
inav/src/main/fc/settings.c
Alberto García Hierro aa8e46b2de Use new setting accessor functions for retriving settings
This reduces flash usage by 96 bytes, making the cost of the whole
PR around 300 bytes.
Also, the settings tables in settings_generated.c are now made
static to make sure no code outside of settings.c can reference
them.
2018-07-09 22:36:01 +01:00

227 lines
5.1 KiB
C

#include <string.h>
#include <stdint.h>
#include "common/string_light.h"
#include "common/utils.h"
#include "settings_generated.h"
#include "fc/settings.h"
#include "settings_generated.c"
void settingGetName(const setting_t *val, char *buf)
{
uint8_t bpos = 0;
uint16_t n = 0;
#ifndef SETTING_ENCODED_NAME_USES_BYTE_INDEXING
uint8_t shift = 0;
#endif
for (uint8_t ii = 0; ii < SETTING_ENCODED_NAME_MAX_BYTES; ii++) {
#ifdef SETTING_ENCODED_NAME_USES_BYTE_INDEXING
n = val->encoded_name[ii];
#else
// Decode a variable size uint
uint16_t b = val->encoded_name[ii];
if (b >= 0x80) {
// More bytes follow
n |= (b&0x7f) << shift;
shift += 7;
continue;
}
// Final byte
n |= b << shift;
#endif
const char *word = settingNamesWords[n];
if (!word) {
// No more words
break;
}
if (bpos > 0) {
// Word separator
buf[bpos++] = '_';
}
strcpy(&buf[bpos], word);
bpos += strlen(word);
#ifndef SETTING_ENCODED_NAME_USES_BYTE_INDEXING
// Reset shift and n
shift = 0;
n = 0;
#endif
}
buf[bpos] = '\0';
}
bool settingNameContains(const setting_t *val, char *buf, const char *cmdline)
{
settingGetName(val, buf);
return strstr(buf, cmdline) != NULL;
}
bool settingNameIsExactMatch(const setting_t *val, char *buf, const char *cmdline, uint8_t var_name_length)
{
settingGetName(val, buf);
return sl_strncasecmp(cmdline, buf, strlen(buf)) == 0 && var_name_length == strlen(buf);
}
const setting_t *settingFind(const char *name)
{
char buf[SETTING_MAX_NAME_LENGTH];
for (int ii = 0; ii < SETTINGS_TABLE_COUNT; ii++) {
const setting_t *setting = &settingsTable[ii];
settingGetName(setting, buf);
if (strcmp(buf, name) == 0) {
return setting;
}
}
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)) {
case VAR_UINT8:
FALLTHROUGH;
case VAR_INT8:
return 1;
case VAR_UINT16:
FALLTHROUGH;
case VAR_INT16:
return 2;
case VAR_UINT32:
FALLTHROUGH;
case VAR_FLOAT:
return 4;
case VAR_STRING:
return settingGetMax(val);
}
return 0; // Unreachable
}
pgn_t settingGetPgn(const setting_t *val)
{
uint16_t pos = val - (const setting_t *)settingsTable;
uint16_t acc = 0;
for (uint8_t ii = 0; ii < SETTINGS_PGN_COUNT; ii++) {
acc += settingsPgnCounts[ii];
if (acc > pos) {
return settingsPgn[ii];
}
}
return -1;
}
static uint16_t getValueOffset(const setting_t *value)
{
switch (SETTING_SECTION(value)) {
case MASTER_VALUE:
return value->offset;
case PROFILE_VALUE:
return value->offset + sizeof(pidProfile_t) * getConfigProfile();
case CONTROL_RATE_VALUE:
return value->offset + sizeof(controlRateConfig_t) * getConfigProfile();
case BATTERY_CONFIG_VALUE:
return value->offset + sizeof(batteryProfile_t) * getConfigBatteryProfile();
}
return 0;
}
void *settingGetValuePointer(const setting_t *val)
{
const pgRegistry_t *pg = pgFind(settingGetPgn(val));
return pg->address + getValueOffset(val);
}
const void * settingGetCopyValuePointer(const setting_t *val)
{
const pgRegistry_t *pg = pgFind(settingGetPgn(val));
return pg->copy + getValueOffset(val);
}
setting_min_t settingGetMin(const setting_t *val)
{
if (SETTING_MODE(val) == MODE_LOOKUP) {
return 0;
}
return settingMinMaxTable[SETTING_INDEXES_GET_MIN(val)];
}
setting_max_t settingGetMax(const setting_t *val)
{
if (SETTING_MODE(val) == MODE_LOOKUP) {
return settingLookupTables[val->config.lookup.tableIndex].valueCount - 1;
}
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) {
return settingGetValuePointer(val);
}
return NULL;
}
void settingSetString(const setting_t *val, const char *s, size_t size)
{
if (SETTING_TYPE(val) == VAR_STRING) {
char *p = settingGetValuePointer(val);
size_t copySize = MIN(size, settingGetMax(val));
memcpy(p, s, copySize);
p[copySize] = '\0';
}
}
setting_max_t settingGetStringMaxLength(const setting_t *val)
{
if (SETTING_TYPE(val) == VAR_STRING) {
// Max string length is stored as its max
return settingGetMax(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;
}