void eeReadAll() { // txmit('a') ; if(!ee32LoadGeneral() ) { // txmit('b') ; alert((char const *)PSTR(STR_BAD_EEPROM), true); g_eeGeneral.contrast = 18 ; message(PSTR(STR_EE_FORMAT)); generalDefault(); modelDefault(0); STORE_GENERALVARS; STORE_MODELVARS; } else { ee32LoadModel(g_eeGeneral.currModel); } // Now update the trainer values if necessary. uint32_t i ; for ( i = 0 ; i < 4 ; i += 1 ) { if ( g_eeGeneral.trainer.mix[i].swtch != -16 ) { g_eeGeneral.exTrainer[i].swtch = g_eeGeneral.trainer.mix[i].swtch ; g_eeGeneral.exTrainer[i].studWeight = g_eeGeneral.trainer.mix[i].studWeight * 13 / 4 ; g_eeGeneral.trainer.mix[i].swtch = -16 ; STORE_GENERALVARS ; } } }
void eeLoadModel(uint8_t id) { if(id<MAX_MODELS) { theFile.openRlc(FILE_MODEL(id)); uint16_t sz = theFile.readRlc((uint8_t*)&g_model, sizeof(g_model)); #ifdef SIMU if (sz > 0 && sz != sizeof(g_model)) { printf("Model data read=%d bytes vs %d bytes\n", sz, (int)sizeof(ModelData)); } #endif if (sz < 730/*sizeof(last compatible eeprom)*/) { modelDefault(id); eeCheck(true); } resetTimer1(); resetTimer2(); resetProto(); #ifdef TELEMLOGS initTelemLog(); #endif } }
TEST(Trims, invertedThrottlePlusThrottleTrim) { MODEL_RESET(); modelDefault(0); g_model.throttleReversed = 1; g_model.thrTrim = 1; // stick max + trim max anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024); // stick max + trim mid anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, 0); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024+250); // stick max + trim min anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024+500); // stick min + trim max anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], +1024); // stick min + trim min anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], +1024); // now the same tests with extended Trims g_model.extendedTrims = 1; // stick max + trim max anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024); // stick max + trim mid anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, 0); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024+1000); // stick max + trim min anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], -1024+2000); // stick min + trim max anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], +1024); // stick min + trim min anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], +1024); }
TEST(Trims, InstantTrim) { MODEL_RESET(); modelDefault(0); anaInValues[AIL_STICK] = 50; instantTrim(); EXPECT_EQ(25, getTrimValue(0, AIL_STICK)); }
void eeLoadModel(uint8_t id) { if (id<MAX_MODELS) { #if defined(SDCARD) closeLogs(); #endif if (pulsesStarted()) { pausePulses(); } pauseMixerCalculations(); uint32_t size = loadModel(id); #if defined(SIMU) if (sizeof(uint16_t) + sizeof(g_model) > EEPROM_ZONE_SIZE) TRACE("Model data size can't exceed %d bytes (%d bytes)", int(EEPROM_ZONE_SIZE-sizeof(uint16_t)), (int)sizeof(g_model)); if (size > 0 && size != sizeof(g_model)) TRACE("Model data read=%d bytes vs %d bytes\n", size, (int)sizeof(ModelData)); #endif if (size < EEPROM_BUFFER_SIZE) { // if not loaded a fair amount modelDefault(id) ; eeCheck(true); } AUDIO_FLUSH(); flightReset(); logicalSwitchesReset(); if (pulsesStarted()) { checkAll(); resumePulses(); } customFunctionsReset(); restoreTimers(); resumeMixerCalculations(); // TODO pulses should be started after mixer calculations ... #if defined(FRSKY) frskySendAlarms(); #endif #if defined(SDCARD) referenceModelAudioFiles(); #endif LOAD_MODEL_BITMAP(); SEND_FAILSAFE_1S(); PLAY_MODEL_NAME(); } }
TEST(Trims, CopySticksToOffset) { MODEL_RESET(); modelDefault(0); anaInValues[ELE_STICK] = -100; perMain(); copySticksToOffset(1); EXPECT_EQ(g_model.limitData[1].offset, -97); }
TEST(Trims, CopySticksToOffset) { MODEL_RESET(); modelDefault(0); anaInValues[ELE_STICK] = -100; #if defined(CPUARM) doMixerCalculations(); #else perMain(); #endif copySticksToOffset(1); EXPECT_EQ(g_model.limitData[1].offset, -97); }
TEST(Trims, CopyTrimsToOffset) { MODEL_RESET(); modelDefault(0); setTrimValue(0, ELE_STICK, -100); // -100 on elevator evalFunctions(); // it disables all safety channels copyTrimsToOffset(1); EXPECT_EQ(getTrimValue(0, ELE_STICK), -100); // unchanged #if defined(CPUARM) EXPECT_EQ(g_model.limitData[1].offset, -195); #else EXPECT_EQ(g_model.limitData[1].offset, -200); #endif }
TEST(Trims, InstantTrimNegativeCurve) { MODEL_RESET(); modelDefault(0); ExpoData *expo = expoAddress(AIL_STICK); expo->curve.type = CURVE_REF_CUSTOM; expo->curve.value = 1; g_model.points[0] = -100; g_model.points[1] = -75; g_model.points[2] = -50; g_model.points[3] = -25; g_model.points[4] = 0; anaInValues[AIL_STICK] = 512; instantTrim(); EXPECT_EQ(128, getTrimValue(0, AIL_STICK)); }
void eeErase(bool warn) { generalDefault(); modelDefault(0); if (warn) { ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM); } MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING); eepromFormat(); eeDirty(EE_GENERAL); eeDirty(EE_MODEL); eeCheck(true); }
TEST(getSwitch, inputWithTrim) { MODEL_RESET(); modelDefault(0); MIXER_RESET(); g_model.logicalSw[0] = { LS_FUNC_VPOS, MIXSRC_FIRST_INPUT, 0, 0 }; doMixerCalculations(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); setTrimValue(0, 0, 32); doMixerCalculations(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); }
TEST(evalLogicalSwitches, playFile) { SYSTEM_RESET(); MODEL_RESET(); modelDefault(0); MIXER_RESET(); extern uint64_t sdAvailableLogicalSwitchAudioFiles; sdAvailableLogicalSwitchAudioFiles = 0xffffffffffffffff; char filename[AUDIO_FILENAME_MAXLEN+1]; isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (0 << 16) + AUDIO_EVENT_OFF, filename); EXPECT_EQ(strcmp(filename, "/SOUNDS/en/MODEL01/L1-off.wav"), 0); isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (0 << 16) + AUDIO_EVENT_ON, filename); EXPECT_EQ(strcmp(filename, "/SOUNDS/en/MODEL01/L1-on.wav"), 0); isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (31 << 16) + AUDIO_EVENT_OFF, filename); EXPECT_EQ(strcmp(filename, "/SOUNDS/en/MODEL01/L32-off.wav"), 0); isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (31 << 16) + AUDIO_EVENT_ON, filename); EXPECT_EQ(strcmp(filename, "/SOUNDS/en/MODEL01/L32-on.wav"), 0); }
void eeReadAll() { if(!EeFsOpen() || EeFsck() < 0 || !eeLoadGeneral() ) { #ifdef SIM printf("bad eeprom contents\n"); #else alert(PSTR("Bad EEprom Data")); #endif EeFsFormat(); generalDefault(); theFile.writeRlc2(FILE_GENERAL,FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral, sizeof(g_eeGeneral),200); modelDefault(0); theFile.writeRlc2(FILE_MODEL(0),FILE_TYP_MODEL,(uint8_t*)&g_model, sizeof(g_model),200); } eeLoadModel(g_eeGeneral.currModel); }
void eeReadAll() { if(!EeFsOpen() || EeFsck() < 0 || !eeLoadGeneral() ) { alert(PSTR("Bad EEprom Data"), true); message(PSTR("EEPROM Formatting")); EeFsFormat(); //alert(PSTR("format ok")); generalDefault(); //alert(PSTR("default ok")); theFile.writeRlc(FILE_GENERAL, FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral), true); modelDefault(0); //alert(PSTR("modef ok")); theFile.writeRlc(FILE_MODEL(0), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model), true); //alert(PSTR("modwrite ok")); } eeLoadModel(g_eeGeneral.currModel); }
void eeReadAll() { fill_file_index() ; if (!eeLoadGeneral() ) { generalDefault(); modelDefault(0); ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM); MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING); /* we remove all models */ for (uint32_t i=0; i<MAX_MODELS; i++) eeDeleteModel(i); eeDirty(EE_GENERAL); eeDirty(EE_MODEL); } else { eeLoadModelHeaders() ; } // TODO common! stickMode = g_eeGeneral.stickMode; #if defined(CPUARM) for (uint8_t i=0; languagePacks[i]!=NULL; i++) { if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) { currentLanguagePackIdx = i; currentLanguagePack = languagePacks[i]; } } #endif }
void eeLoadModel(uint8_t id) { if (id<MAX_MODELS) { #if defined(SDCARD) closeLogs(); #endif if (pulsesStarted()) { pausePulses(); } pauseMixerCalculations(); uint16_t size = File_system[id+1].size ; memset(&g_model, 0, sizeof(g_model)); #if defined(SIMU) if (sizeof(struct t_eeprom_header) + sizeof(g_model) > 4096) TRACE("Model data size can't exceed %d bytes (%d bytes)", int(4096-sizeof(struct t_eeprom_header)), (int)sizeof(g_model)); else if (size > 0 && size != sizeof(g_model)) TRACE("Model data read=%d bytes vs %d bytes\n", size, (int)sizeof(ModelData)); #endif if (size > sizeof(g_model)) { size = sizeof(g_model) ; } if(size < 256) { // if not loaded a fair amount modelDefault(id) ; eeCheck(true); } else { read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&g_model, size) ; } AUDIO_FLUSH(); flightReset(); logicalSwitchesReset(); if (pulsesStarted()) { checkAll(); resumePulses(); } activeFnSwitches = 0; activeFunctions = 0; memclear(lastFunctionTime, sizeof(lastFunctionTime)); restoreTimers(); resumeMixerCalculations(); // TODO pulses should be started after mixer calculations ... #if defined(FRSKY) frskySendAlarms(); #endif #if defined(CPUARM) && defined(SDCARD) referenceModelAudioFiles(); #endif LOAD_MODEL_BITMAP(); SEND_FAILSAFE_1S(); } }
TEST(Trims, invertedThrottlePlusthrottleTrimWithZeroWeightOnThrottle) { MODEL_RESET(); modelDefault(0); g_model.throttleReversed = 1; g_model.thrTrim = 1; #if defined(PCBTARANIS) // the input already exists ExpoData *expo = expoAddress(THR_STICK); #else ExpoData *expo = expoAddress(0); expo->mode = 3; expo->chn = THR_STICK; #endif expo->weight = 0; // stick max + trim max anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); // stick max + trim mid anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, 0); evalMixes(1); EXPECT_LE(abs(channelOutputs[2] - 125), 1); // stick max + trim min anaInValues[THR_STICK] = +1024; setTrimValue(0, THR_STICK, TRIM_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], 250); // stick min + trim max anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_MAX); evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); // stick min + trim mid anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, 0); evalMixes(1); EXPECT_LE(abs(channelOutputs[2] - 125), 1); // stick min + trim min anaInValues[THR_STICK] = -1024; setTrimValue(0, THR_STICK, TRIM_MIN); evalMixes(1); EXPECT_EQ(channelOutputs[2], 250); // now some tests with extended Trims g_model.extendedTrims = 1; // trim min + various stick positions = should always be same value setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN); anaInValues[THR_STICK] = -1024; evalMixes(1); EXPECT_EQ(channelOutputs[2], 1000); anaInValues[THR_STICK] = -300; evalMixes(1); EXPECT_EQ(channelOutputs[2], 1000); anaInValues[THR_STICK] = +300; evalMixes(1); EXPECT_EQ(channelOutputs[2], 1000); anaInValues[THR_STICK] = +1024; evalMixes(1); EXPECT_EQ(channelOutputs[2], 1000); // trim max + various stick positions = should always be same value setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX); anaInValues[THR_STICK] = -1024; evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); anaInValues[THR_STICK] = -300; evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); anaInValues[THR_STICK] = +300; evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); anaInValues[THR_STICK] = +1024; evalMixes(1); EXPECT_EQ(channelOutputs[2], 0); }
void eeLoadModel(uint8_t id) { if(id>=MAX_MODELS) return; //paranoia theFile.openRd(FILE_MODEL(id)); uint16_t sz = 0; if(theFile.readRlc2((uint8_t*)&g_model,sizeof(g_model.name)+1) == (sizeof(g_model.name)+1)){ theFile.openRd(FILE_MODEL(id)); if(g_model.mdVers < MDVERS192){ sz = theFile.readRlc1((uint8_t*)&g_model, sizeof(g_model)); }else{ sz = theFile.readRlc2((uint8_t*)&g_model, sizeof(g_model)); } } // #if 0 // if( sz == sizeof(ModelData_r0) ){ // printf("converting model data t0 r84\n"); // char* pSrc = ((char*)&g_model) + sizeof(ModelData_r0); //Pointers behind the end // char* pDst = ((char*)&g_model) + sizeof(ModelData_r84); // ModelData_r84 *model84 = (ModelData_r84*)&g_model; // #define sizeof84(memb) sizeof(((ModelData_r84*)0)->memb) // fullCopy(sizeof84(trimData)+sizeof84(curves9)+sizeof84(curves5)); // // partCopy(sizeof84(mixData), sizeof(MixData_r0)*20); // // for(uint8_t i=0; i<DIM(model84->expoData); i++){ // partCopy(sizeof(ExpoData_r84), sizeof(ExpoData_r0)); // } // sz = sizeof(ModelData_r84); // model84->mdVers = MDVERS84; // } // #endif if( sz == sizeof(ModelData_r84) && g_model.mdVers == MDVERS84) { printf("converting model data from r84 to r143\n"); ModelData_r84 *model84 = (ModelData_r84*)&g_model; ModelData_r143 *model143 = (ModelData_r143*)&g_model; for(int8_t i=3; i>=0; i--){ int16_t val = trimExp2(model84->trimData[i].trim) + model84->trimData[i].trimDef_lt133; model143->trimData[i].itrim = trimRevert2(val); model143->trimData[i].tmode = 0; } memmove(&model143->curves5, &model84->curves5, sizeof(model84->curves5)+sizeof(model84->curves9)); memset(model143->curves3, 0, sizeof(model143->curves3)); model143->curves3[0][2] = 100; model143->curves3[2][0] = 100; model143->curves3[2][2] = 100; model143->curves3[1][0] = -100; sz = sizeof(ModelData_r143); model84->mdVers = MDVERS143; } if( sz == sizeof(ModelData_r143) && g_model.mdVers == MDVERS143) { printf("converting model data from r143 to r167\n"); ModelData_r143 *model143 = (ModelData_r143*)&g_model; ModelData_r167 *model167 = (ModelData_r167*)&g_model; for(int8_t i=0; i<NUM_CHNOUT; i++){ int8_t v = model143->limitData[i].min-100; model167->limitData[i].min = add7Bit(val2idx50_150(v),40); model167->limitData[i].scale = 0; v = model143->limitData[i].max+100; model167->limitData[i].max = add7Bit(val2idx50_150(v),-40); model167->limitData[i].binSwtch = 0; } model143->mdVers = MDVERS167; } if( sz == sizeof(ModelData_r167) && g_model.mdVers == MDVERS167) { printf("converting model data from r167 to r171\n"); ModelData_r167 *model167 = (ModelData_r167*)&g_model; ModelData_r171 *model171 = (ModelData_r171*)&g_model; ExpoData_r84 *hlpExp = (ExpoData_r84*) ((char*)&model171->expoTab +sizeof(model171->expoTab) -sizeof(model167->expoData)); // old:20B new:45B // move old to end // clr unused start 25B // interpret old to new <= 3*8=24B // clr old at end 20B // memmove(hlpExp, &model167->expoData, sizeof(ModelData_r167)-offsetof(ModelData_r167,expoData)); memset(model171->expoTab, 0, sizeof(model171->expoTab) -sizeof(model167->expoData)); for(int8_t i=0,j=0; i<4; i++){ if(hlpExp[i].expNorm || hlpExp[i].expNormWeight){ model171->expoTab[j].drSw = hlpExp[i].drSw ? -hlpExp[i].drSw : 0; model171->expoTab[j].chn = convertMode(i); model171->expoTab[j].mode3 = EM_BOTH; model171->expoTab[j].exp5 = val2idx15_100(hlpExp[i].expNorm); model171->expoTab[j].weight6 =val2idx30_100(hlpExp[i].expNormWeight+100); j++; } if(hlpExp[i].drSw && (hlpExp[i].expDr || hlpExp[i].expSwWeight)){ model171->expoTab[j].drSw = hlpExp[i].drSw; model171->expoTab[j].chn = convertMode(i); model171->expoTab[j].mode3 = EM_BOTH; model171->expoTab[j].exp5 = val2idx15_100(hlpExp[i].expDr); model171->expoTab[j].weight6 =val2idx30_100(hlpExp[i].expSwWeight+100); j++; } } memset(hlpExp, 0, sizeof(model167->expoData)); sz = sizeof(ModelData_r171); for(uint8_t i=0;i<MAX_MIXERS;i++){ MixData_r0 &md = model171->mixData[i]; if(md.destCh==0) break; md.srcRaw = convertMode(md.srcRaw-1)+1; } if(g_eeGeneral.stickMode & 1) memswap(&model171->trimData[1], &model171->trimData[2],sizeof(model171->trimData[1])); if(g_eeGeneral.stickMode & 2) memswap(&model171->trimData[0], &model171->trimData[3],sizeof(model171->trimData[0])); model167->mdVers = MDVERS171; } if( sz == sizeof(ModelData_r171) && g_model.mdVers == MDVERS171) { printf("converting model data from r171 to r192\n"); ModelData_r171 *model171 = (ModelData_r171*)&g_model; ModelData_r192 *model192 = (ModelData_r192*)&g_model; memmove(&model192->curves3, &model171->curves3, sizeof(ModelData_r171)-offsetof(ModelData_r171,curves3)); for(uint8_t i=MAX_MIXERS;i>0;){i--; MixData_r0 &md0 = model171->mixData[i]; MixData_r192 &md192 = model192->mixData[i]; uint8_t dc=md0.destCh; if(dc==0){ memset(&md192,0,5); continue; } memmove(&md192.weight,&md0.weight,3); // 0 1 2 3 4 5 6 7 8 9 uint8_t sr=md0.srcRaw; //0 RUD ELE THR AIL P1 P2 P3 MAX FUL X1-4 memset(&md192,0,2); md192.destCh =dc; if(sr>4){ if(sr<=9) md192.switchMode=1; //P1-3, FUL I=-1 if(sr==8) md192.switchMode=2; //MAX I=0 if(sr==9) sr=8; //FUL->MAX if(sr>9) sr+=8;//space for ch1-ch8 if(sr>7) sr+=3;//space for p1-3 } md192.srcRaw =sr-1; //now start with 0 if(md192.weight<0 && md192.curve){ md192.weight = -md192.weight; md192.curveNeg = 1; } } sz = sizeof(ModelData_r192); model171->mdVers = MDVERS192; } if( sz == sizeof(ModelData_r192) && g_model.mdVers == MDVERS192) { printf("converting model data from r192 to r204\n"); ModelData_r192 *model192 = (ModelData_r192*)&g_model; ModelData_r204 *model204 = (ModelData_r204*)&g_model; memmove(&model204->trimData,&model192->trimData,sizeof(model192->trimData)); memset(model204->switchTab,0,sizeof(model204->switchTab)); model204->trimData[0].tmode=0; model204->trimData[1].tmode=0; model204->trimData[2].tmode=0; model204->trimData[3].tmode=0; sz = sizeof(ModelData_r204); model204->mdVers = MDVERS204; } if( sz == sizeof(ModelData_TOP) && g_model.mdVers == MDVERS_TOP) { return; } printf("bad model%d data using default\n",id+1); modelDefault(id); }