Updates as per iNav

This commit is contained in:
Martin Budden 2017-01-02 17:03:17 +00:00 committed by borisbstyle
parent 2aa89cf791
commit 1c08319ef9
5 changed files with 195 additions and 53 deletions

View File

@ -15,11 +15,16 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config_streamer.h"
#include <string.h>
#include "platform.h"
#include <string.h>
#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)
{

View File

@ -17,6 +17,9 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
void systemInit(void);
void delayMicroseconds(uint32_t us);
void delay(uint32_t ms);

View File

@ -23,6 +23,7 @@
#include <math.h>
#include <ctype.h>
//#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'");

View File

@ -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();
}

View File

@ -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);