diff --git a/src/main/config/config_streamer.c b/src/main/config/config_streamer.c
index cd48ea9f72..e63363f22d 100644
--- a/src/main/config/config_streamer.c
+++ b/src/main/config/config_streamer.c
@@ -15,11 +15,16 @@
* along with Cleanflight. If not, see .
*/
-#include "config_streamer.h"
+#include
#include "platform.h"
-#include
+#include "drivers/system.h"
+
+#include "config/config_streamer.h"
+
+extern uint8_t __config_start; // configured via linker script when building binaries.
+extern uint8_t __config_end;
#if !defined(FLASH_PAGE_SIZE)
# if defined(STM32F10X_MD)
@@ -32,6 +37,8 @@
# define FLASH_PAGE_SIZE ((uint32_t)0x20000)
# elif defined (STM32F411xE)
# define FLASH_PAGE_SIZE ((uint32_t)0x20000)
+# elif defined(STM32F427_437xx)
+# define FLASH_PAGE_SIZE ((uint32_t)0x20000) // 128K sectors
# elif defined(STM32F745xx)
# define FLASH_PAGE_SIZE ((uint32_t)0x40000)
# elif defined(STM32F746xx)
@@ -79,61 +86,134 @@ void config_streamer_start(config_streamer_t *c, uintptr_t base, int size)
}
#if defined(STM32F7)
+/*
+Sector 0 0x08000000 - 0x08007FFF 32 Kbytes
+Sector 1 0x08008000 - 0x0800FFFF 32 Kbytes
+Sector 2 0x08010000 - 0x08017FFF 32 Kbytes
+Sector 3 0x08018000 - 0x0801FFFF 32 Kbytes
+Sector 4 0x08020000 - 0x0803FFFF 128 Kbytes
+Sector 5 0x08040000 - 0x0807FFFF 256 Kbytes
+Sector 6 0x08080000 - 0x080BFFFF 256 Kbytes
+Sector 7 0x080C0000 - 0x080FFFFF 256 Kbytes
+*/
+
+static uint32_t getFLASHSectorForEEPROM(void)
+{
+ if ((uint32_t)&__config_start <= 0x08007FFF)
+ return FLASH_SECTOR_0;
+ if ((uint32_t)&__config_start <= 0x0800FFFF)
+ return FLASH_SECTOR_1;
+ if ((uint32_t)&__config_start <= 0x08017FFF)
+ return FLASH_SECTOR_2;
+ if ((uint32_t)&__config_start <= 0x0801FFFF)
+ return FLASH_SECTOR_3;
+ if ((uint32_t)&__config_start <= 0x0803FFFF)
+ return FLASH_SECTOR_4;
+ if ((uint32_t)&__config_start <= 0x0807FFFF)
+ return FLASH_SECTOR_5;
+ if ((uint32_t)&__config_start <= 0x080BFFFF)
+ return FLASH_SECTOR_6;
+ if ((uint32_t)&__config_start <= 0x080FFFFF)
+ return FLASH_SECTOR_7;
+
+ // Not good
+ while (1) {
+ failureMode(FAILURE_FLASH_WRITE_FAILED);
+ }
+}
+
+#elif defined(STM32F4)
+/*
+Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
+Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
+Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
+Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
+Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
+Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
+Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
+Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
+Sector 8 0x08080000 - 0x0809FFFF 128 Kbytes
+Sector 9 0x080A0000 - 0x080BFFFF 128 Kbytes
+Sector 10 0x080C0000 - 0x080DFFFF 128 Kbytes
+Sector 11 0x080E0000 - 0x080FFFFF 128 Kbytes
+*/
+
+static uint32_t getFLASHSectorForEEPROM(void)
+{
+ if ((uint32_t)&__config_start <= 0x08003FFF)
+ return FLASH_Sector_0;
+ if ((uint32_t)&__config_start <= 0x08007FFF)
+ return FLASH_Sector_1;
+ if ((uint32_t)&__config_start <= 0x0800BFFF)
+ return FLASH_Sector_2;
+ if ((uint32_t)&__config_start <= 0x0800FFFF)
+ return FLASH_Sector_3;
+ if ((uint32_t)&__config_start <= 0x0801FFFF)
+ return FLASH_Sector_4;
+ if ((uint32_t)&__config_start <= 0x0803FFFF)
+ return FLASH_Sector_5;
+ if ((uint32_t)&__config_start <= 0x0805FFFF)
+ return FLASH_Sector_6;
+ if ((uint32_t)&__config_start <= 0x0807FFFF)
+ return FLASH_Sector_7;
+ if ((uint32_t)&__config_start <= 0x0809FFFF)
+ return FLASH_Sector_8;
+ if ((uint32_t)&__config_start <= 0x080DFFFF)
+ return FLASH_Sector_9;
+ if ((uint32_t)&__config_start <= 0x080BFFFF)
+ return FLASH_Sector_10;
+ if ((uint32_t)&__config_start <= 0x080FFFFF)
+ return FLASH_Sector_11;
+
+ // Not good
+ while (1) {
+ failureMode(FAILURE_FLASH_WRITE_FAILED);
+ }
+}
+#endif
+
static int write_word(config_streamer_t *c, uint32_t value)
{
if (c->err != 0) {
return c->err;
}
-
- HAL_StatusTypeDef status;
+#if defined(STM32F7)
if (c->address % FLASH_PAGE_SIZE == 0) {
- FLASH_EraseInitTypeDef EraseInitStruct = {0};
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
- EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 2.7-3.6V
- EraseInitStruct.Sector = (FLASH_SECTOR_TOTAL-1);
- EraseInitStruct.NbSectors = 1;
+ FLASH_EraseInitTypeDef EraseInitStruct = {
+ .TypeErase = FLASH_TYPEERASE_SECTORS,
+ .VoltageRange = FLASH_VOLTAGE_RANGE_3, // 2.7-3.6V
+ .NbSectors = 1
+ };
+ EraseInitStruct.Sector = getFLASHSectorForEEPROM();
uint32_t SECTORError;
- status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
+ const HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
if (status != HAL_OK){
return -1;
}
}
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, c->address, value);
+ const HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, c->address, value);
if (status != HAL_OK) {
return -2;
}
- c->address += sizeof(value);
- return 0;
-}
#else
-static int write_word(config_streamer_t *c, uint32_t value)
-{
- if (c->err != 0) {
- return c->err;
- }
-
- FLASH_Status status;
-
if (c->address % FLASH_PAGE_SIZE == 0) {
-#if defined(STM32F40_41xxx)
- status = FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); //0x08080000 to 0x080A0000
-#elif defined (STM32F411xE)
- status = FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); //0x08060000 to 0x08080000
+#if defined(STM32F4)
+ const FLASH_Status status = FLASH_EraseSector(getFLASHSectorForEEPROM(), VoltageRange_3); //0x08080000 to 0x080A0000
#else
- status = FLASH_ErasePage(c->address);
+ const FLASH_Status status = FLASH_ErasePage(c->address);
#endif
if (status != FLASH_COMPLETE) {
return -1;
}
}
- status = FLASH_ProgramWord(c->address, value);
+ const FLASH_Status status = FLASH_ProgramWord(c->address, value);
if (status != FLASH_COMPLETE) {
return -2;
}
+#endif
c->address += sizeof(value);
return 0;
}
-#endif
int config_streamer_write(config_streamer_t *c, const uint8_t *p, uint32_t size)
{
diff --git a/src/main/drivers/system.h b/src/main/drivers/system.h
index 87af44df54..5ac340c31e 100644
--- a/src/main/drivers/system.h
+++ b/src/main/drivers/system.h
@@ -17,6 +17,9 @@
#pragma once
+#include
+#include
+
void systemInit(void);
void delayMicroseconds(uint32_t us);
void delay(uint32_t ms);
diff --git a/src/main/fc/cli.c b/src/main/fc/cli.c
index 7155658ffd..c641ca7f35 100755
--- a/src/main/fc/cli.c
+++ b/src/main/fc/cli.c
@@ -23,6 +23,7 @@
#include
#include
+//#define USE_PARAMETER_GROUPS
#include "platform.h"
// FIXME remove this for targets that don't need a CLI. Perhaps use a no-op macro when USE_CLI is not enabled
@@ -48,6 +49,9 @@ uint8_t cliMode = 0;
#include "config/config_master.h"
#include "config/feature.h"
+#include "config/parameter_group.h"
+#include "config/parameter_group_ids.h"
+
#include "drivers/accgyro.h"
#include "drivers/buf_writer.h"
#include "drivers/bus_i2c.h"
@@ -460,6 +464,7 @@ typedef enum {
MASTER_VALUE = (0 << VALUE_SECTION_OFFSET),
PROFILE_VALUE = (1 << VALUE_SECTION_OFFSET),
PROFILE_RATE_VALUE = (2 << VALUE_SECTION_OFFSET),
+ CONTROL_RATE_VALUE = (3 << VALUE_SECTION_OFFSET),
// value mode
MODE_DIRECT = (0 << VALUE_MODE_OFFSET),
MODE_LOOKUP = (1 << VALUE_MODE_OFFSET)
@@ -483,6 +488,22 @@ typedef union {
cliMinMaxConfig_t minmax;
} cliValueConfig_t;
+#ifdef USE_PARAMETER_GROUPS
+typedef struct {
+ const char *name;
+ const uint8_t type; // see cliValueFlag_e
+ const cliValueConfig_t config;
+
+ pgn_t pgn;
+ uint16_t offset;
+} __attribute__((packed)) clivalue_t;
+
+static const clivalue_t valueTable[] = {
+ { "dummy", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, 255 }, 0, 0 }
+};
+
+#else
+
typedef struct {
const char *name;
const uint8_t type; // see cliValueFlag_e
@@ -490,7 +511,7 @@ typedef struct {
const cliValueConfig_t config;
} clivalue_t;
-const clivalue_t valueTable[] = {
+static const clivalue_t valueTable[] = {
#ifndef SKIP_TASK_STATISTICS
{ "task_statistics", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.task_statistics, .config.lookup = { TABLE_OFF_ON } },
#endif
@@ -811,8 +832,7 @@ const clivalue_t valueTable[] = {
{ "displayport_max7456_row_adjust", VAR_INT8 | MASTER_VALUE, &displayPortProfileMax7456()->rowAdjust, .config.minmax = { -3, 0 } },
#endif
};
-
-#define VALUE_COUNT (sizeof(valueTable) / sizeof(clivalue_t))
+#endif
static void cliPrint(const char *str)
{
@@ -931,6 +951,24 @@ static void printValuePointer(const clivalue_t *var, void *valuePointer, uint32_
}
}
+#ifdef USE_PARAMETER_GROUPS
+static void* getValuePointer(const clivalue_t *var)
+{
+ const pgRegistry_t* rec = pgFind(var->pgn);
+
+ switch (var->type & VALUE_SECTION_MASK) {
+ 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:
+ return *rec->ptr + var->offset;
+ }
+ return NULL;
+}
+#else
void *getValuePointer(const clivalue_t *value)
{
void *ptr = value->ptr;
@@ -945,6 +983,7 @@ void *getValuePointer(const clivalue_t *value)
return ptr;
}
+#endif
static void *getDefaultPointer(void *valuePointer, const master_t *defaultConfig)
{
@@ -1006,7 +1045,7 @@ static void cliPrintVarDefault(const clivalue_t *var, uint32_t full, const maste
static void dumpValues(uint16_t valueSection, uint8_t dumpMask, const master_t *defaultConfig)
{
const clivalue_t *value;
- for (uint32_t i = 0; i < VALUE_COUNT; i++) {
+ for (uint32_t i = 0; i < ARRAYLEN(valueTable); i++) {
value = &valueTable[i];
if ((value->type & VALUE_SECTION_MASK) != valueSection) {
@@ -1053,13 +1092,7 @@ typedef union {
static void cliSetVar(const clivalue_t *var, const int_float_value_t value)
{
- void *ptr = var->ptr;
- if ((var->type & VALUE_SECTION_MASK) == PROFILE_VALUE) {
- ptr = ((uint8_t *)ptr) + (sizeof(profile_t) * masterConfig.current_profile_index);
- }
- if ((var->type & VALUE_SECTION_MASK) == PROFILE_RATE_VALUE) {
- ptr = ((uint8_t *)ptr) + (sizeof(profile_t) * masterConfig.current_profile_index) + (sizeof(controlRateConfig_t) * getCurrentControlRateProfile());
- }
+ void *ptr = getValuePointer(var);
switch (var->type & VALUE_TYPE_MASK) {
case VAR_UINT8:
@@ -3074,7 +3107,7 @@ static void cliGet(char *cmdline)
const clivalue_t *val;
int matchedCommands = 0;
- for (uint32_t i = 0; i < VALUE_COUNT; i++) {
+ for (uint32_t i = 0; i < ARRAYLEN(valueTable); i++) {
if (strstr(valueTable[i].name, cmdline)) {
val = &valueTable[i];
cliPrintf("%s = ", valueTable[i].name);
@@ -3105,7 +3138,7 @@ static void cliSet(char *cmdline)
if (len == 0 || (len == 1 && cmdline[0] == '*')) {
cliPrint("Current settings: \r\n");
- for (uint32_t i = 0; i < VALUE_COUNT; i++) {
+ for (uint32_t i = 0; i < ARRAYLEN(valueTable); i++) {
val = &valueTable[i];
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
@@ -3126,7 +3159,7 @@ static void cliSet(char *cmdline)
eqptr++;
}
- for (uint32_t i = 0; i < VALUE_COUNT; i++) {
+ for (uint32_t i = 0; i < ARRAYLEN(valueTable); i++) {
val = &valueTable[i];
// 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)) {
@@ -3541,6 +3574,18 @@ static void cliResource(char *cmdline)
}
#endif /* USE_RESOURCE_MGMT */
+#ifdef USE_PARAMETER_GROUPS
+static void backupConfigs(void)
+{
+ // make copies of configs to do differencing
+
+}
+
+static void restoreConfigs(void)
+{
+}
+#endif
+
static void printConfig(char *cmdline, bool doDiff)
{
uint8_t dumpMask = DUMP_MASTER;
@@ -3557,13 +3602,21 @@ static void printConfig(char *cmdline, bool doDiff)
options = cmdline;
}
- static master_t defaultConfig;
if (doDiff) {
dumpMask = dumpMask | DO_DIFF;
}
+ static master_t defaultConfig;
createDefaultConfig(&defaultConfig);
+#ifdef USE_PARAMETER_GROUPS
+ backupConfigs();
+ // reset all configs to defaults to do differencing
+ resetConfigs();
+#if defined(TARGET_CONFIG)
+ targetConfiguration(&defaultConfig);
+#endif
+#endif
if (checkCommand(options, "showdefaults")) {
dumpMask = dumpMask | SHOW_DEFAULTS; // add default values as comments for changed values
}
@@ -3686,6 +3739,10 @@ static void printConfig(char *cmdline, bool doDiff)
if (dumpMask & DUMP_RATES) {
cliDumpRateProfile(currentProfile->activeRateProfile, dumpMask, &defaultConfig);
}
+#ifdef USE_PARAMETER_GROUPS
+ // restore configs from copies
+ restoreConfigs();
+#endif
}
static void cliDump(char *cmdline)
@@ -3812,13 +3869,11 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("vtx", "vtx channels on switch", NULL, cliVtx),
#endif
};
-#define CMD_COUNT (sizeof(cmdTable) / sizeof(clicmd_t))
-
static void cliHelp(char *cmdline)
{
UNUSED(cmdline);
- for (uint32_t i = 0; i < CMD_COUNT; i++) {
+ for (uint32_t i = 0; i < ARRAYLEN(cmdTable); i++) {
cliPrint(cmdTable[i].name);
#ifndef MINIMAL_CLI
if (cmdTable[i].description) {
@@ -3847,7 +3902,7 @@ void cliProcess(void)
// do tab completion
const clicmd_t *cmd, *pstart = NULL, *pend = NULL;
uint32_t i = bufferIndex;
- for (cmd = cmdTable; cmd < cmdTable + CMD_COUNT; cmd++) {
+ for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if (bufferIndex && (strncasecmp(cliBuffer, cmd->name, bufferIndex) != 0))
continue;
if (!pstart)
@@ -3908,12 +3963,12 @@ void cliProcess(void)
const clicmd_t *cmd;
char *options;
- for (cmd = cmdTable; cmd < cmdTable + CMD_COUNT; cmd++) {
+ for (cmd = cmdTable; cmd < cmdTable + ARRAYLEN(cmdTable); cmd++) {
if ((options = checkCommand(cliBuffer, cmd->name))) {
break;
- }
+ }
}
- if(cmd < cmdTable + CMD_COUNT)
+ if(cmd < cmdTable + ARRAYLEN(cmdTable))
cmd->func(options);
else
cliPrint("Unknown command, try 'help'");
diff --git a/src/main/fc/config.c b/src/main/fc/config.c
index e65ef76b22..e66c6e1395 100755
--- a/src/main/fc/config.c
+++ b/src/main/fc/config.c
@@ -872,11 +872,14 @@ void createDefaultConfig(master_t *config)
}
}
-static void resetConf(void)
+void resetConfigs(void)
{
createDefaultConfig(&masterConfig);
+ pgResetAll(MAX_PROFILE_COUNT);
+ pgActivateProfile(0);
setProfile(0);
+ setControlRateProfile(0);
#ifdef LED_STRIP
reevaluateLedConfig();
@@ -1173,7 +1176,7 @@ void ensureEEPROMContainsValidData(void)
void resetEEPROM(void)
{
- resetConf();
+ resetConfigs();
writeEEPROM();
}
diff --git a/src/main/fc/config.h b/src/main/fc/config.h
index 62841f5fd3..6466507e61 100644
--- a/src/main/fc/config.h
+++ b/src/main/fc/config.h
@@ -91,6 +91,7 @@ bool canSoftwareSerialBeUsed(void);
uint16_t getCurrentMinthrottle(void);
+void resetConfigs(void);
struct master_s;
void targetConfiguration(struct master_s *config);
void targetValidateConfiguration(struct master_s *config);