Merge pull request #8437 from opentx/raphaelcoeffic/fix-startup

2.4: empty SD card startup fixes and clean-up
This commit is contained in:
Bertrand Songis
2021-04-09 16:49:56 +02:00
committed by GitHub
25 changed files with 334 additions and 252 deletions
+1
View File
@@ -419,6 +419,7 @@ set(SRC
stamp.cpp
timers.cpp
trainer.cpp
model_init.cpp
)
if(GUI)
+2 -2
View File
@@ -550,9 +550,9 @@ typedef uint8_t swarnenable_t;
#elif defined(COLORLCD)
#include "gui/colorlcd/layout.h"
#include "gui/colorlcd/topbar.h"
#define LAYOUT_NAME_LEN 10
#define LAYOUT_ID_LEN 10
PACK(struct CustomScreenData {
char layoutName[LAYOUT_NAME_LEN];
char LayoutId[LAYOUT_ID_LEN];
Layout::PersistentData layoutData;
});
#define CUSTOM_SCREENS_DATA \
+2 -2
View File
@@ -75,7 +75,7 @@ void loadDefaultLayout()
auto& screenData = g_model.screenData[0];
if (screen == nullptr && defaultLayout != nullptr) {
strcpy(screenData.layoutName, defaultLayout->getName());
strcpy(screenData.LayoutId, defaultLayout->getId());
screen = defaultLayout->create(&screenData.layoutData);
if (screen) {
screen->attach(ViewMain::instance());
@@ -88,7 +88,7 @@ void loadCustomScreens()
for (unsigned int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
auto& screen = customScreens[i];
screen = loadLayout(g_model.screenData[i].layoutName,
screen = loadLayout(g_model.screenData[i].LayoutId,
&g_model.screenData[i].layoutData);
if (screen) {
+45 -8
View File
@@ -286,14 +286,7 @@ class ModelCategoryPageBody: public FormWindow {
update(); // modelslist.getModelIndex(modelCell));
});
}
menu->addLine(STR_CREATE_MODEL, [=]() {
storageCheck(true);
modelslist.setCurrentModel(modelslist.addModel(category, createModel()));
#if defined(LUA)
// chainMenu(menuModelWizard);
#endif
update(category->size() - 1);
});
menu->addLine(STR_CREATE_MODEL, getCreateModelAction());
menu->addLine(STR_DUPLICATE_MODEL, [=]() {
char duplicatedFilename[LEN_MODEL_FILENAME + 1];
memcpy(duplicatedFilename, model->modelFilename, sizeof(duplicatedFilename));
@@ -342,11 +335,55 @@ class ModelCategoryPageBody: public FormWindow {
}
setInnerHeight(y);
if (category->empty()) {
setFocus();
}
}
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override
{
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
Menu * menu = new Menu(this);
menu->addLine(STR_CREATE_MODEL, getCreateModelAction());
//TODO: create category?
}
else {
FormWindow::onEvent(event);
}
}
#endif
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override
{
if (category->empty()) {
// use Window::setFocus() to avoid forwarding focus to nowhere
// this crashes currently in libopenui
Window::setFocus(flag, from);
}
else {
FormWindow::setFocus(flag, from);
}
}
protected:
ModelsCategory * category;
ModelSelectFooter * footer;
std::function<void(void)> getCreateModelAction()
{
return [=]() {
storageCheck(true);
modelslist.setCurrentModel(modelslist.addModel(category, createModel()));
#if defined(LUA)
// chainMenu(menuModelWizard);
#endif
update(category->size() - 1);
};
}
};
class ModelCategoryPage: public PageTab {
+5 -2
View File
@@ -276,8 +276,11 @@ void RadioCalibrationPage::nextStep()
g_eeGeneral.chkSum = evalChkSum();
storageDirty(EE_GENERAL);
menuCalibrationState = CALIB_FINISHED;
// initial calibration completed
// -> exit
if (initial)
text->getParent()->getParent()->deleteLater();
deleteLater();
break;
default:
@@ -289,5 +292,5 @@ void RadioCalibrationPage::nextStep()
void startCalibration()
{
new RadioCalibrationPage();
new RadioCalibrationPage(true);
}
+6 -4
View File
@@ -69,7 +69,7 @@ void ScreenAddPage::build(FormWindow * window)
const LayoutFactory * factory = getRegisteredLayouts().front();
screen = factory->create(&screenData.layoutData);
strncpy(screenData.layoutName, factory->getId(), sizeof(screenData.layoutName));
strncpy(screenData.LayoutId, factory->getId(), sizeof(screenData.LayoutId));
auto tab = new ScreenSetupPage(menu, screen, screenData);
std::string title(STR_MAIN_VIEW_X);
@@ -257,8 +257,10 @@ class SetupWidgetsPage: public FormWindow
#if defined(HARDWARE_TOUCH)
Keyboard::hide();
#endif
// give it back to its old parent before it gets deleted
screen->attach(oldParent);
if (oldParent) {
// give it back to its old parent before it gets deleted
screen->attach(oldParent);
}
FormWindow::deleteLater(detach, trash);
}
@@ -299,7 +301,7 @@ void ScreenSetupPage::build(FormWindow * window)
layoutChoice = new LayoutChoice(window, layoutSlot, GET_VALUE(screen->getFactory()), [=](const LayoutFactory *factory) {
delete screen;
screen = factory->create(&screenData.layoutData);
strncpy(screenData.layoutName, factory->getId(), sizeof(CustomScreenData::layoutName));
strncpy(screenData.LayoutId, factory->getId(), sizeof(CustomScreenData::LayoutId));
SET_DIRTY();
updateLayoutOptions();
});
+3 -1
View File
@@ -23,6 +23,7 @@
#include "opentx.h"
#include "lua_api.h"
#include "timers.h"
#include "model_init.h"
/*luadoc
@function model.getInfo()
@@ -664,7 +665,8 @@ Set all inputs to defaults
*/
static int luaModelDefaultInputs(lua_State *L)
{
defaultInputs();
clearInputs();
setDefaultInputs();
return 0;
}
+145
View File
@@ -0,0 +1,145 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
void clearInputs()
{
memset(g_model.expoData, 0, sizeof(g_model.expoData));
}
void setDefaultInputs()
{
for (int i=0; i<NUM_STICKS; i++) {
uint8_t stick_index = channelOrder(i+1);
ExpoData *expo = expoAddress(i);
expo->srcRaw = MIXSRC_Rud - 1 + stick_index;
expo->curve.type = CURVE_REF_EXPO;
expo->chn = i;
expo->weight = 100;
expo->mode = 3; // TODO constant
for (int c = 0; c < 3; c++) {
g_model.inputNames[i][c] = STR_VSRCRAW[2 + 4 * stick_index + c];
}
#if LEN_INPUT_NAME > 3
g_model.inputNames[i][3] = '\0';
#endif
}
storageDirty(EE_MODEL);
}
void clearMixes()
{
memset(g_model.mixData, 0, sizeof(g_model.mixData));
}
void setDefaultMixes()
{
for (int i=0; i<NUM_STICKS; i++) {
MixData * mix = mixAddress(i);
mix->destCh = i;
mix->weight = 100;
mix->srcRaw = i+1;
}
storageDirty(EE_MODEL);
}
void setDefaultModelRegistrationID()
{
memcpy(g_model.modelRegistrationID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID);
}
void setDefaultGVars()
{
#if defined(FLIGHT_MODES) && defined(GVARS)
for (int fmIdx = 1; fmIdx < MAX_FLIGHT_MODES; fmIdx++) {
for (int gvarIdx = 0; gvarIdx < MAX_GVARS; gvarIdx++) {
g_model.flightModeData[fmIdx].gvars[gvarIdx] = GVAR_MAX + 1;
}
}
#endif
}
void setVendorSpecificModelDefaults()
{
#if defined(FRSKY_RELEASE)
g_model.moduleData[INTERNAL_MODULE].type = IS_PXX2_INTERNAL_ENABLED() ? MODULE_TYPE_ISRM_PXX2 : MODULE_TYPE_XJT_PXX1;
g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);
#if defined(EEPROM)
g_model.header.modelId[INTERNAL_MODULE] = findNextUnusedModelId(id, INTERNAL_MODULE);
modelHeaders[id].modelId[INTERNAL_MODULE] = g_model.header.modelId[INTERNAL_MODULE];
#endif
#endif
// TODO: we should probably have some default trainer mode
// per radio, depending on what is supported
//
#if defined(PCBXLITE)
g_model.trainerData.mode = TRAINER_MODE_MASTER_BLUETOOTH;
#endif
#if defined(RADIOMASTER_RTF_RELEASE)
// Those settings are for headless radio
g_model.trainerData.mode = TRAINER_MODE_SLAVE;
g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_MULTIMODULE;
g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D8;
g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
#endif
}
void applyDefaultTemplate()
{
setDefaultInputs();
setDefaultMixes();
setDefaultGVars();
setDefaultModelRegistrationID();
#if defined(COLORLCD)
//TODO: not sure yet we need it here
loadDefaultLayout();
// enable switch warnings
for (int i = 0; i < NUM_SWITCHES; i++) {
g_model.switchWarningState |= (1 << (3*i));
}
#endif
// TODO: what about switch warnings in non-color LCD radios?
}
void setModelDefaults(uint8_t id)
{
memset(&g_model, 0, sizeof(g_model));
applyDefaultTemplate();
setVendorSpecificModelDefaults();
strAppendUnsigned(strAppend(g_model.header.name, STR_MODEL), id + 1, 2);
#if defined(LUA) && defined(PCBTARANIS) // Horus uses menuModelWizard() for wizard
if (isFileAvailable(WIZARD_PATH "/" WIZARD_NAME)) {
f_chdir(WIZARD_PATH);
luaExec(WIZARD_NAME);
}
#endif
}
+6 -177
View File
@@ -23,7 +23,7 @@
#if defined(LIBOPENUI)
// #include "shutdown_animation.h"
// #include "radio_calibration.h"
#include "radio_calibration.h"
#include "view_main.h"
#endif
@@ -364,178 +364,6 @@ uint16_t evalChkSum()
return sum;
}
void clearInputs()
{
memset(g_model.expoData, 0, sizeof(g_model.expoData)); // clear all expos
}
void defaultInputs()
{
clearInputs();
for (int i=0; i<NUM_STICKS; i++) {
uint8_t stick_index = channelOrder(i+1);
ExpoData *expo = expoAddress(i);
expo->srcRaw = MIXSRC_Rud - 1 + stick_index;
expo->curve.type = CURVE_REF_EXPO;
expo->chn = i;
expo->weight = 100;
expo->mode = 3; // TODO constant
for (int c = 0; c < 3; c++) {
g_model.inputNames[i][c] = STR_VSRCRAW[2 + 4 * stick_index + c];
}
#if LEN_INPUT_NAME > 3
g_model.inputNames[i][3] = '\0';
#endif
}
storageDirty(EE_MODEL);
}
void applyDefaultTemplate()
{
defaultInputs(); // calls storageDirty internally
for (int i=0; i<NUM_STICKS; i++) {
MixData * mix = mixAddress(i);
mix->destCh = i;
mix->weight = 100;
mix->srcRaw = i+1;
}
}
#if defined(EEPROM)
void checkModelIdUnique(uint8_t index, uint8_t module)
{
if (isModuleXJTD8(module))
return;
uint8_t modelId = g_model.header.modelId[module];
uint8_t additionalOnes = 0;
char * name = reusableBuffer.moduleSetup.msg;
memset(reusableBuffer.moduleSetup.msg, 0, sizeof(reusableBuffer.moduleSetup.msg));
if (modelId != 0) {
for (uint8_t i = 0; i < MAX_MODELS; i++) {
if (i != index) {
if (modelId == modelHeaders[i].modelId[module]) {
if ((WARNING_LINE_LEN - 4 - (name - reusableBuffer.moduleSetup.msg)) > (signed)(modelHeaders[i].name[0] ? zlen(modelHeaders[i].name, LEN_MODEL_NAME) : sizeof(TR_MODEL) + 2)) { // you cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 (-2 for the ",")
if (reusableBuffer.moduleSetup.msg[0] != '\0') {
name = strAppend(name, ", ");
}
if (modelHeaders[i].name[0] == 0) {
name = strAppend(name, STR_MODEL);
name = strAppendUnsigned(name+strlen(name), i + 1, 2);
}
else {
name += zchar2str(name, modelHeaders[i].name, LEN_MODEL_NAME);
}
}
else {
additionalOnes++;
}
}
}
}
}
if (additionalOnes) {
name = strAppend(name, " (+");
name = strAppendUnsigned(name, additionalOnes);
strAppend(name, ")");
}
if (reusableBuffer.moduleSetup.msg[0]) {
POPUP_WARNING(STR_MODELIDUSED, reusableBuffer.moduleSetup.msg);
}
}
uint8_t findNextUnusedModelId(uint8_t index, uint8_t module)
{
uint8_t usedModelIds[(MAX_RXNUM + 7) / 8];
memset(usedModelIds, 0, sizeof(usedModelIds));
for (uint8_t modelIndex = 0; modelIndex < MAX_MODELS; modelIndex++) {
if (modelIndex == index)
continue;
uint8_t id = modelHeaders[modelIndex].modelId[module];
if (id == 0)
continue;
uint8_t mask = 1u << (id & 7u);
usedModelIds[id >> 3u] |= mask;
}
for (uint8_t id = 1; id <= getMaxRxNum(module); id++) {
uint8_t mask = 1u << (id & 7u);
if (!(usedModelIds[id >> 3u] & mask)) {
// found free ID
return id;
}
}
// failed finding something...
return 0;
}
#endif
void modelDefault(uint8_t id)
{
memset(&g_model, 0, sizeof(g_model));
applyDefaultTemplate();
memcpy(g_model.modelRegistrationID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID);
#if defined(LUA) && defined(PCBTARANIS) // Horus uses menuModelWizard() for wizard
if (isFileAvailable(WIZARD_PATH "/" WIZARD_NAME)) {
f_chdir(WIZARD_PATH);
luaExec(WIZARD_NAME);
}
#endif
#if defined(FRSKY_RELEASE)
g_model.moduleData[INTERNAL_MODULE].type = IS_PXX2_INTERNAL_ENABLED() ? MODULE_TYPE_ISRM_PXX2 : MODULE_TYPE_XJT_PXX1;
g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);
#if defined(EEPROM)
g_model.header.modelId[INTERNAL_MODULE] = findNextUnusedModelId(id, INTERNAL_MODULE);
modelHeaders[id].modelId[INTERNAL_MODULE] = g_model.header.modelId[INTERNAL_MODULE];
#endif
#endif
#if defined(PCBXLITE)
g_model.trainerData.mode = TRAINER_MODE_MASTER_BLUETOOTH;
#endif
#if defined(FLIGHT_MODES) && defined(GVARS)
for (int fmIdx = 1; fmIdx < MAX_FLIGHT_MODES; fmIdx++) {
for (int gvarIdx = 0; gvarIdx < MAX_GVARS; gvarIdx++) {
g_model.flightModeData[fmIdx].gvars[gvarIdx] = GVAR_MAX + 1;
}
}
#endif
strAppendUnsigned(strAppend(g_model.header.name, STR_MODEL), id + 1, 2);
#if defined(COLORLCD)
loadDefaultLayout();
// enable switch warnings
for (int i = 0; i < NUM_SWITCHES; i++) {
g_model.switchWarningState |= (1 << (3*i));
}
#endif
#if defined(RADIOMASTER_RTF_RELEASE)
// Those settings are for headless radio
g_model.trainerData.mode = TRAINER_MODE_SLAVE;
g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_MULTIMODULE;
g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D8;
g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
#endif
}
bool isInputRecursive(int index)
{
@@ -1632,8 +1460,7 @@ void opentxStart(const uint8_t startOptions = OPENTX_START_DEFAULT_ARGS)
#if defined(GUI)
if (calibration_needed) {
#if defined(LIBOPENUI)
#warning "TODO add a startCalibration function"
// startCalibration();
startCalibration();
#else
chainMenu(menuFirstCalib);
#endif
@@ -1927,8 +1754,10 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
void opentxInit()
{
TRACE("opentxInit");
#if defined(GUI) && !defined(LIBOPENUI)
#if defined(LIBOPENUI)
// create ViewMain
ViewMain::instance();
#elif defined(GUI)
// TODO add a function for this (duplicated)
menuHandlers[0] = menuMainView;
#if MENUS_LOCK != 2/*no menus*/
-12
View File
@@ -665,12 +665,6 @@ inline void resumeMixerCalculations()
void setDefaultOwnerId();
void generalDefault();
void modelDefault(uint8_t id);
#if defined(EEPROM)
void checkModelIdUnique(uint8_t index, uint8_t module);
uint8_t findNextUnusedModelId(uint8_t index, uint8_t module);
#endif
uint32_t hash(const void * ptr, uint32_t size);
@@ -786,12 +780,6 @@ inline void getGVarIncDecRange(int16_t & valMin, int16_t & valMax)
}
#endif
void clearInputs();
void defaultInputs();
void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx=0, int16_t ovwrValue=0);
int16_t applyLimits(uint8_t channel, int32_t value);
@@ -323,7 +323,7 @@ void convertModelData_218_to_219(ModelData &model)
for (int screen=0; screen<MAX_CUSTOM_SCREENS; screen++) {
CustomScreenData& screenData = g_model.screenData[screen];
if (screenData.layoutName[0] == '\0')
if (screenData.LayoutId[0] == '\0')
continue;
for (int zone=0; zone<MAX_LAYOUT_ZONES; zone++) {
Layout::ZonePersistentData * zoneData = &screenData.layoutData.zones[zone];
@@ -397,7 +397,7 @@ PACK(struct TelemetrySensor_218 {
#if defined(PCBHORUS)
PACK(struct CustomScreenData_v218 {
char layoutName[10];
char LayoutId[10];
Layout::PersistentData layoutData;
});
#define VIEW_DATA \
+78 -2
View File
@@ -23,6 +23,7 @@
#include <string.h>
#include "opentx.h"
#include "timers.h"
#include "model_init.h"
void eeLoadModel(uint8_t index)
{
@@ -45,7 +46,7 @@ void eeLoadModel(uint8_t index)
bool alarms = true;
if (size < EEPROM_MIN_MODEL_SIZE) { // if not loaded a fair amount
modelDefault(index) ;
setModelDefaults(index);
storageCheck(true);
alarms = false;
}
@@ -131,7 +132,7 @@ void storageEraseAll(bool warn)
TRACE("storageEraseAll");
generalDefault();
modelDefault(0);
setModelDefault(0);
if (warn) {
ALERT(STR_STORAGE_WARNING, STR_BAD_RADIO_DATA, AU_BAD_RADIODATA);
@@ -143,3 +144,78 @@ void storageEraseAll(bool warn)
storageDirty(EE_GENERAL|EE_MODEL);
storageCheck(true);
}
void checkModelIdUnique(uint8_t index, uint8_t module)
{
if (isModuleXJTD8(module))
return;
uint8_t modelId = g_model.header.modelId[module];
uint8_t additionalOnes = 0;
char * name = reusableBuffer.moduleSetup.msg;
memset(reusableBuffer.moduleSetup.msg, 0, sizeof(reusableBuffer.moduleSetup.msg));
if (modelId != 0) {
for (uint8_t i = 0; i < MAX_MODELS; i++) {
if (i != index) {
if (modelId == modelHeaders[i].modelId[module]) {
if ((WARNING_LINE_LEN - 4 - (name - reusableBuffer.moduleSetup.msg)) > (signed)(modelHeaders[i].name[0] ? zlen(modelHeaders[i].name, LEN_MODEL_NAME) : sizeof(TR_MODEL) + 2)) { // you cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 (-2 for the ",")
if (reusableBuffer.moduleSetup.msg[0] != '\0') {
name = strAppend(name, ", ");
}
if (modelHeaders[i].name[0] == 0) {
name = strAppend(name, STR_MODEL);
name = strAppendUnsigned(name+strlen(name), i + 1, 2);
}
else {
name += zchar2str(name, modelHeaders[i].name, LEN_MODEL_NAME);
}
}
else {
additionalOnes++;
}
}
}
}
}
if (additionalOnes) {
name = strAppend(name, " (+");
name = strAppendUnsigned(name, additionalOnes);
strAppend(name, ")");
}
if (reusableBuffer.moduleSetup.msg[0]) {
POPUP_WARNING(STR_MODELIDUSED, reusableBuffer.moduleSetup.msg);
}
}
uint8_t findNextUnusedModelId(uint8_t index, uint8_t module)
{
uint8_t usedModelIds[(MAX_RXNUM + 7) / 8];
memset(usedModelIds, 0, sizeof(usedModelIds));
for (uint8_t modelIndex = 0; modelIndex < MAX_MODELS; modelIndex++) {
if (modelIndex == index)
continue;
uint8_t id = modelHeaders[modelIndex].modelId[module];
if (id == 0)
continue;
uint8_t mask = 1u << (id & 7u);
usedModelIds[id >> 3u] |= mask;
}
for (uint8_t id = 1; id <= getMaxRxNum(module); id++) {
uint8_t mask = 1u << (id & 7u);
if (!(usedModelIds[id >> 3u] & mask)) {
// found free ID
return id;
}
}
// failed finding something...
return 0;
}
+3
View File
@@ -39,6 +39,9 @@ void storageClearRadioSettings();
bool storageReadRadioSettings(bool allowFixes = true);
void storageReadCurrentModel();
void checkModelIdUnique(uint8_t index, uint8_t module);
uint8_t findNextUnusedModelId(uint8_t index, uint8_t module);
#if defined(EEPROM_RLC)
#include "eeprom_rlc.h"
#else
+1 -3
View File
@@ -441,14 +441,12 @@ bool ModelsList::load()
if (!currentModel) {
if (model) {
currentModel = model;
currentCategory = category;
}
else {
model = new ModelCell(line);
category = new ModelsCategory("Models");
categories.push_back(category);
category->push_back(model);
}
currentCategory = category;
}
loaded = true;
+15 -17
View File
@@ -23,6 +23,7 @@
#include "sdcard_common.h"
#include "modelslist.h"
#include "conversions/conversions.h"
#include "model_init.h"
// defined either in sdcard_raw.cpp or sdcard_yaml.cpp
void storageCreateModelsList();
@@ -43,9 +44,6 @@ void storageEraseAll(bool warn)
static_cast<OpenTxTheme*>(theme)->load();
#endif
generalDefault();
modelDefault(1);
if (warn) {
ALERT(STR_STORAGE_WARNING, STR_BAD_RADIO_DATA, AU_BAD_RADIODATA);
}
@@ -53,7 +51,7 @@ void storageEraseAll(bool warn)
RAISE_ALERT(STR_STORAGE_WARNING, STR_STORAGE_FORMAT, NULL, AU_NONE);
storageFormat();
storageDirty(EE_GENERAL|EE_MODEL);
storageDirty(EE_GENERAL);
storageCheck(true);
}
@@ -68,7 +66,7 @@ void storageCheck(bool immediately)
{
if (storageDirtyMsk & EE_GENERAL) {
TRACE("eeprom write general");
storageDirtyMsk -= EE_GENERAL;
storageDirtyMsk &= ~EE_GENERAL;
const char * error = writeGeneralSettings();
if (error) {
TRACE("writeGeneralSettings error=%s", error);
@@ -77,7 +75,7 @@ void storageCheck(bool immediately)
if (storageDirtyMsk & EE_MODEL) {
TRACE("eeprom write model");
storageDirtyMsk -= EE_MODEL;
storageDirtyMsk &= ~EE_MODEL;
const char * error = writeModel();
if (error) {
TRACE("writeModel error=%s", error);
@@ -95,7 +93,7 @@ const char * createModel()
int index = findNextFileIndex(filename, LEN_MODEL_FILENAME, MODELS_PATH);
if (index > 0) {
modelDefault(index);
setModelDefaults(index);
memcpy(g_eeGeneral.currModelFilename, filename, sizeof(g_eeGeneral.currModelFilename));
storageDirty(EE_GENERAL);
storageDirty(EE_MODEL);
@@ -109,18 +107,20 @@ const char * createModel()
const char * loadModel(const char * filename, bool alarms)
{
uint8_t version;
preModelLoad();
const char * error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model), &version);
if (error) {
TRACE("loadModel error=%s", error);
}
if (error) {
modelDefault(0) ;
// just get some clean memory state in "g_model"
// so the mixer can run safely
memset(&g_model, 0, sizeof(g_model));
applyDefaultTemplate();
storageCheck(true);
alarms = false;
postModelLoad(false);
return error;
}
#if defined(STORAGE_CONVERSIONS)
@@ -130,8 +130,7 @@ const char * loadModel(const char * filename, bool alarms)
#endif
postModelLoad(alarms);
return error;
return nullptr;
}
void storageReadAll()
@@ -150,8 +149,7 @@ void storageReadAll()
}
if (loadModel(g_eeGeneral.currModelFilename, false) != nullptr) {
sdCheckAndCreateDirectory(MODELS_PATH);
createModel();
TRACE("No current model or SD card error");
}
// Wipe models list in case
+2
View File
@@ -60,6 +60,8 @@ const char * writeModel()
{
char path[256];
getModelPath(path, g_eeGeneral.currModelFilename);
sdCheckAndCreateDirectory(MODELS_PATH);
return writeFile(path, (uint8_t *)&g_model, sizeof(g_model));
}
@@ -697,7 +697,7 @@ static const struct YamlNode struct_Layout__PersistentData[] = {
};
static const struct YamlNode struct_CustomScreenData[] = {
YAML_IDX,
YAML_STRING("layoutName", 10),
YAML_STRING("LayoutId", 10),
YAML_STRUCT("layoutData", 6720, struct_Layout__PersistentData, NULL),
YAML_END
};
@@ -698,7 +698,7 @@ static const struct YamlNode struct_Layout__PersistentData[] = {
};
static const struct YamlNode struct_CustomScreenData[] = {
YAML_IDX,
YAML_STRING("layoutName", 10),
YAML_STRING("LayoutId", 10),
YAML_STRUCT("layoutData", 6720, struct_Layout__PersistentData, NULL),
YAML_END
};
+3 -4
View File
@@ -293,6 +293,9 @@ void tasksStart()
{
RTOS_INIT();
RTOS_CREATE_MUTEX(audioMutex);
RTOS_CREATE_MUTEX(mixerMutex);
#if defined(CLI)
cliStart();
#endif
@@ -303,9 +306,5 @@ void tasksStart()
#if !defined(SIMU)
RTOS_CREATE_TASK(audioTaskId, audioTask, "audio", audioStack, AUDIO_STACK_SIZE, AUDIO_TASK_PRIO);
#endif
RTOS_CREATE_MUTEX(audioMutex);
RTOS_CREATE_MUTEX(mixerMutex);
RTOS_START();
}
-1
View File
@@ -48,7 +48,6 @@ extern RTOS_TASK_HANDLE audioTaskId;
extern RTOS_DEFINE_STACK(audioStack, AUDIO_STACK_SIZE);
extern RTOS_MUTEX_HANDLE mixerMutex;
extern RTOS_FLAG_HANDLE openTxInitCompleteFlag;
void stackPaint();
void tasksStart();
+2 -2
View File
@@ -291,7 +291,7 @@ TEST(Conversions, ConversionX10From22)
EXPECT_EQ(9, g_model.telemetrySensors[0].frskyInstance.physID);
EXPECT_EQ((NUM_POTS + NUM_SLIDERS + 3), g_model.thrTraceSrc); // CH3
EXPECT_STREQ("Layout2P1", g_model.screenData[0].layoutName);
EXPECT_STREQ("Layout2P1", g_model.screenData[0].LayoutId);
EXPECT_STREQ("ModelBmp", g_model.screenData[0].layoutData.zones[0].widgetName);
EXPECT_STREQ("Value", g_model.topbarData.zones[0].widgetName);
EXPECT_EQ(MIXSRC_FIRST_TELEM, g_model.topbarData.zones[0].widgetData.options[0].value.unsignedValue);
@@ -358,7 +358,7 @@ TEST(Conversions, ConversionX12SFrom22)
EXPECT_EQ(9, g_model.telemetrySensors[0].frskyInstance.physID);
EXPECT_EQ((NUM_POTS + NUM_SLIDERS + 3), g_model.thrTraceSrc); // CH3
EXPECT_STREQ("Layout2P1", g_model.screenData[0].layoutName);
EXPECT_STREQ("Layout2P1", g_model.screenData[0].LayoutId);
EXPECT_STREQ("ModelBmp", g_model.screenData[0].layoutData.zones[0].widgetName);
EXPECT_STREQ("Value", g_model.topbarData.zones[0].widgetName);
EXPECT_EQ(MIXSRC_FIRST_TELEM, g_model.topbarData.zones[0].widgetData.options[0].unsignedValue);
+1 -1
View File
@@ -104,7 +104,7 @@ class OpenTxTest : public testing::Test
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
RADIO_RESET();
}
};
+8 -8
View File
@@ -466,7 +466,7 @@ TEST(Curves, LinearIntpol)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
for (int8_t i=-2; i<=2; i++) {
g_model.points[2+i] = 50*i;
}
@@ -672,7 +672,7 @@ TEST_F(TrimsTest, throttleTrimEle) {
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_eeGeneral.templateSetup = 17;
applyDefaultTemplate();
g_model.thrTrim = 1;
@@ -685,7 +685,7 @@ TEST_F(TrimsTest, throttleTrimEle) {
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_eeGeneral.templateSetup = 0;
applyDefaultTemplate();
}
@@ -696,7 +696,7 @@ TEST(Heli, BasicTest)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_model.swashR.collectiveSource = MIXSRC_Thr;
g_model.swashR.elevatorSource = MIXSRC_Ele;
g_model.swashR.aileronSource = MIXSRC_Ail;
@@ -728,7 +728,7 @@ TEST(Heli, Mode2Test)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_eeGeneral.templateSetup = 2;
applyDefaultTemplate();
g_model.swashR.collectiveSource = MIXSRC_Thr;
@@ -764,7 +764,7 @@ TEST(Trainer, UnpluggedTest)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_model.mixData[0].destCh = 0;
g_model.mixData[0].mltpx = MLTPX_ADD;
g_model.mixData[0].srcRaw = MIXSRC_FIRST_TRAINER;
@@ -781,7 +781,7 @@ TEST_F(MixerTest, flightModeTransition)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_model.flightModeData[1].swtch = TR(SWSRC_ID2, SWSRC_SA2);
g_model.flightModeData[0].fadeIn = 100;
g_model.flightModeData[0].fadeOut = 100;
@@ -807,7 +807,7 @@ TEST_F(MixerTest, flightModeOverflow)
SYSTEM_RESET();
MODEL_RESET();
MIXER_RESET();
modelDefault(0);
setModelDefaults(0);
g_model.flightModeData[1].swtch = TR(SWSRC_ID2, SWSRC_SA2);
g_model.flightModeData[0].fadeIn = 100;
g_model.flightModeData[0].fadeOut = 100;
+2 -2
View File
@@ -77,7 +77,7 @@ TEST(getSwitch, nullSW)
TEST(getSwitch, inputWithTrim)
{
MODEL_RESET();
modelDefault(0);
setModelDefaults(0);
MIXER_RESET();
// g_model.logicalSw[0] = { LS_FUNC_VPOS, MIXSRC_FIRST_INPUT, 0, 0 };
@@ -99,7 +99,7 @@ TEST(evalLogicalSwitches, playFile)
{
SYSTEM_RESET();
MODEL_RESET();
modelDefault(0);
setModelDefaults(0);
MIXER_RESET();
extern BitField<(MAX_LOGICAL_SWITCHES * 2/*on, off*/)> sdAvailableLogicalSwitchAudioFiles;