void onAdjustGvarSourceLongEnterPress(const char * result) { CustomFunctionData * cfn = &g_model.customFn[menuVerticalPosition]; if (result == STR_CONSTANT) { CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_CONSTANT; CFN_PARAM(cfn) = 0; eeDirty(EE_MODEL); } else if (result == STR_MIXSOURCE) { CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_SOURCE; CFN_PARAM(cfn) = 0; eeDirty(EE_MODEL); } else if (result == STR_GLOBALVAR) { CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_GVAR; CFN_PARAM(cfn) = 0; eeDirty(EE_MODEL); } else if (result == STR_INCDEC) { CFN_GVAR_MODE(cfn) = FUNC_ADJUST_GVAR_INC; CFN_PARAM(cfn) = 0; eeDirty(EE_MODEL); } else { onSourceLongEnterPress(result); } }
void backupEeprom() { char filename[60]; uint8_t buffer[1024]; FIL file; lcd_clear(); displayProgressBar(STR_WRITING); // reset unexpectedShutdown to prevent warning when user restores EEPROM backup g_eeGeneral.unexpectedShutdown = 0; eeDirty(EE_GENERAL); eeCheck(true); // create the directory if needed... DIR folder; FRESULT result = f_opendir(&folder, EEPROMS_PATH); if (result != FR_OK) { if (result == FR_NO_PATH) result = f_mkdir(EEPROMS_PATH); if (result != FR_OK) { POPUP_WARNING(SDCARD_ERROR(result)); return; } } // prepare the filename... char * tmp = strAppend(filename, EEPROMS_PATH "/eeprom"); tmp = strAppendDate(tmp, true); strAppend(tmp, EEPROM_EXT); // open the file for writing... f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS); for (int i=0; i<EESIZE; i+=1024) { UINT count; eepromReadBlock(buffer, i, 1024); f_write(&file, buffer, 1024, &count); updateProgressBar(i, EESIZE); SIMU_SLEEP(100/*ms*/); } f_close(&file); //set back unexpectedShutdown g_eeGeneral.unexpectedShutdown = 1; eeDirty(EE_GENERAL); eeCheck(true); }
void insertExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(expo, sizeof(ExpoData)); expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); expo->curve.type = CURVE_REF_EXPO; expo->mode = 3; // pos&neg expo->chn = s_currCh - 1; expo->weight = 100; } else { MixData *mix = mixAddress(idx); memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); memclear(mix, sizeof(MixData)); mix->destCh = s_currCh-1; mix->srcRaw = s_currCh; if (!isSourceAvailable(mix->srcRaw)) { mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); while (!isSourceAvailable(mix->srcRaw)) { mix->srcRaw += 1; } } mix->weight = 100; } resumeMixerCalculations(); eeDirty(EE_MODEL); }
static int luaModelSetModule(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); if (idx < NUM_MODULES) { ModuleData & module = g_model.moduleData[idx]; luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "rfProtocol")) { module.rfProtocol = luaL_checkinteger(L, -1); } else if (!strcmp(key, "modelId")) { g_model.header.modelId[idx] = modelHeaders[g_eeGeneral.currModel].modelId[idx] = luaL_checkinteger(L, -1); } else if (!strcmp(key, "firstChannel")) { module.channelsStart = luaL_checkinteger(L, -1); } else if (!strcmp(key, "channelsCount")) { module.channelsCount = luaL_checkinteger(L, -1) - 8; } } eeDirty(EE_MODEL); } return 0; }
FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr) { lcd_putsColumnLeft(x, y, STR_FLMODE); int posHorz = m_posHorz; for (int p=0; p<MAX_FLIGHT_MODES; p++) { LcdFlags flags = 0; if (attr) { flags |= INVERS; if (posHorz==p) flags |= BLINK; } if (value & (1<<p)) lcd_putcAtt(x, y, ' ', flags|FIXEDWIDTH); else lcd_putcAtt(x, y, '0'+p, flags); x += FW; } if (attr) { if (s_editMode && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; value ^= (1<<posHorz); eeDirty(EE_MODEL); } } return value; }
static int luaModelSetTimer(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); if (idx < MAX_TIMERS) { TimerData & timer = g_model.timers[idx]; luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "mode")) { timer.mode = luaL_checkinteger(L, -1); } else if (!strcmp(key, "start")) { timer.start = luaL_checkinteger(L, -1); } else if (!strcmp(key, "value")) { timersStates[idx].val = luaL_checkinteger(L, -1); } else if (!strcmp(key, "countdownBeep")) { timer.countdownBeep = luaL_checkinteger(L, -1); } else if (!strcmp(key, "minuteBeep")) { timer.minuteBeep = lua_toboolean(L, -1); } else if (!strcmp(key, "persistent")) { timer.persistent = luaL_checkinteger(L, -1); } } eeDirty(EE_MODEL); } return 0; }
void onCustomFunctionsFileSelectionMenu(const char *result) { int8_t sub = m_posVert - 1; CustomFunctionData * cf = &g_model.customFn[sub]; uint8_t func = CFN_FUNC(cf); if (result == STR_UPDATE_LIST) { char directory[256]; if (func == FUNC_PLAY_SCRIPT) { strcpy(directory, SCRIPTS_FUNCS_PATH); } else { strcpy(directory, SOUNDS_PATH); strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); } if (!listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cf->play.name), NULL)) { POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); s_menu_flags = 0; } } else { // The user choosed a file in the list memcpy(cf->play.name, result, sizeof(cf->play.name)); eeDirty(EE_MODEL); } }
void onSensorMenu(const char *result) { uint8_t index = m_posVert - 1 - ITEM_TELEMETRY_SENSOR1; if (index < MAX_SENSORS) { if (result == STR_EDIT) { pushMenu(menuModelSensor); } else if (result == STR_DELETE) { delTelemetryIndex(index); index += 1; if (index<MAX_SENSORS && isTelemetryFieldAvailable(index)) m_posVert += 1; else m_posVert = 1+ITEM_TELEMETRY_NEWSENSOR; } else if (result == STR_COPY) { int newIndex = availableTelemetryIndex(); if (newIndex >= 0) { TelemetrySensor & sourceSensor = g_model.telemetrySensors[index]; TelemetrySensor & newSensor = g_model.telemetrySensors[newIndex]; newSensor = sourceSensor; TelemetryItem & sourceItem = telemetryItems[index]; TelemetryItem & newItem = telemetryItems[newIndex]; newItem = sourceItem; eeDirty(EE_MODEL); } else { POPUP_WARNING(STR_TELEMETRYFULL); } } } }
void menuStatisticsView(uint8_t event) { TITLE(STR_MENUSTAT); switch(event) { case EVT_KEY_FIRST(KEY_UP): chainMenu(menuStatisticsDebug); break; case EVT_KEY_LONG(KEY_MENU): g_eeGeneral.globalTimer = 0; eeDirty(EE_GENERAL); sessionTimer = 0; break; case EVT_KEY_FIRST(KEY_EXIT): chainMenu(menuMainView); break; } // Session and Total timers lcd_putsAtt(STATS_1ST_COLUMN, FH*1+1, "SES", BOLD); putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*1+1, sessionTimer, 0, 0); lcd_putsAtt(STATS_1ST_COLUMN, FH*2+1, "TOT", BOLD); putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*2+1, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0); // Throttle special timers lcd_putsAtt(STATS_2ND_COLUMN, FH*0+1, "THR", BOLD); putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*0+1, s_timeCumThr, 0, 0); lcd_putsAtt(STATS_2ND_COLUMN, FH*1+1, "TH%", BOLD); putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*1+1, s_timeCum16ThrP/16, 0, 0); // Timers for (int i=0; i<TIMERS; i++) { putsStrIdx(STATS_3RD_COLUMN, FH*i+1, "TM", i+1, BOLD); if (timersStates[i].val > 3600) putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, TIMEHOUR, 0); else putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, 0, 0); } #if defined(THRTRACE) coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0); const coord_t x = 5; const coord_t y = 60; lcd_hline(x-3, y, MAXTRACE+3+3); lcd_vline(x, y-32, 32+3); for (coord_t i=0; i<MAXTRACE; i+=6) { lcd_vline(x+i+6, y-1, 3); } for (coord_t i=1; i<=MAXTRACE; i++) { lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]); traceRd++; if (traceRd>=MAXTRACE) traceRd = 0; if (traceRd==s_traceWr) break; } #endif }
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); }
int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) #endif { uint16_t delta = GV_GET_GV1_VALUE(max); bool invers = (attr & INVERS); // TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { s_editMode = !s_editMode; #if defined(CPUARM) if (attr & PREC1) value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta); else value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta); #else value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta); #endif eeDirty(EE_MODEL); } if (GV_IS_GV_VALUE(value, min, max)) { if (attr & LEFT) attr -= LEFT; /* because of ZCHAR */ else x -= 2*FW+FWNUM; #if defined(CPUARM) attr &= ~PREC1; #endif int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta); if (invers) { CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1); } if (idx < 0) { value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta); idx = -idx; lcd_putcAtt(x-6, y, '-', attr); } else { value = (int16_t) GV_CALC_VALUE_IDX_POS(idx, delta); idx++; } putsStrIdx(x, y, STR_GV, idx, attr); } else { lcd_outdezAtt(x, y, value, attr); #if defined(CPUARM) if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); #else if (invers) value = checkIncDec(event, value, min, max, EE_MODEL); #endif } return value; }
/*luadoc @function model.setGlobalVariable(index, phase, value) Sets current global variable value. See also model.getGlobalVariable() @param index zero based global variable index, use 0 for GV1, 8 for GV9 @param phase zero based phase index, use 0 for Phase 1, 5 for Phase 6 @param value new value for global variable. Permitted range is from -1024 to 1024. @notice Global variable can only store integer values, any floating point value is converted (todo check how) into integer value. */ static int luaModelSetGlobalVariable(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); unsigned int phase = luaL_checkunsigned(L, 2); int value = luaL_checkinteger(L, 3); if (phase < MAX_FLIGHT_MODES && idx < MAX_GVARS && value >= -GVAR_MAX && value <= GVAR_MAX) { g_model.flightModeData[phase].gvars[idx] = value; eeDirty(EE_MODEL); } return 0; }
void menuStatisticsView(uint8_t event) { TITLE(STR_MENUSTAT); switch(event) { case EVT_KEY_FIRST(KEY_UP): chainMenu(menuStatisticsDebug); return; #if defined(CPUARM) case EVT_KEY_LONG(KEY_MENU): g_eeGeneral.globalTimer = 0; eeDirty(EE_GENERAL); sessionTimer = 0; break; #endif case EVT_KEY_FIRST(KEY_EXIT): chainMenu(menuMainView); return; } lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP); putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0); putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0); #if defined(CPUARM) putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0); #endif #if defined(THRTRACE) uint8_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0); const uint8_t x=5; const uint8_t y=60; lcd_hline(x-3,y,MAXTRACE+3+3); lcd_vline(x,y-32,32+3); for (uint8_t i=0; i<MAXTRACE; i+=6) { lcd_vline(x+i+6,y-1,3); } for (uint8_t i=1; i<=MAXTRACE; i++) { lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]); traceRd++; if (traceRd>=MAXTRACE) traceRd = 0; if (traceRd==s_traceWr) break; } #endif }
void onCustomFunctionsMenu(const char *result) { int sub = menuVerticalPosition; CustomFunctionData * cfn; uint8_t eeFlags; if (menuHandlers[menuLevel] == menuModelCustomFunctions) { cfn = &g_model.customFn[sub]; eeFlags = EE_MODEL; } else { cfn = &g_eeGeneral.customFn[sub]; eeFlags = EE_GENERAL; } if (result == STR_COPY) { clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION; clipboard.data.cfn = *cfn; } else if (result == STR_PASTE) { *cfn = clipboard.data.cfn; eeDirty(eeFlags); } else if (result == STR_CLEAR) { memset(cfn, 0, sizeof(CustomFunctionData)); eeDirty(eeFlags); } else if (result == STR_INSERT) { memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); memset(cfn, 0, sizeof(CustomFunctionData)); eeDirty(eeFlags); } else if (result == STR_DELETE) { memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); eeDirty(eeFlags); } }
void onModelSetupBitmapMenu(const char *result) { if (result == STR_UPDATE_LIST) { if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), NULL)) { POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } else { // The user choosed a bmp file in the list copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); eeDirty(EE_MODEL); } }
void copyExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); } else { MixData *mix = mixAddress(idx); memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); } resumeMixerCalculations(); eeDirty(EE_MODEL); }
void onSdManagerMenu(const char *result) { char lfn[SD_SCREEN_FILE_LENGTH]; uint8_t index = m_posVert-1-s_pgOfs; if (result == STR_SD_INFO) { pushMenu(menuGeneralSdManagerInfo); } else if (result == STR_SD_FORMAT) { POPUP_CONFIRMATION(PSTR("Confirm Format?")); } else if (result == STR_DELETE_FILE) { f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); strcat_P(lfn, PSTR("/")); strcat(lfn, reusableBuffer.sdmanager.lines[index]); f_unlink(lfn); strncpy(statusLineMsg, reusableBuffer.sdmanager.lines[index], 13); strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED); showStatusLine(); if ((uint16_t)m_posVert == reusableBuffer.sdmanager.count) m_posVert--; reusableBuffer.sdmanager.offset = s_pgOfs-1; } #if defined(CPUARM) /* TODO else if (result == STR_LOAD_FILE) { f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); strcat(lfn, "/"); strcat(lfn, reusableBuffer.sdmanager.lines[index]); POPUP_WARNING(eeLoadModelSD(lfn)); } */ else if (result == STR_PLAY_FILE) { f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); strcat(lfn, "/"); strcat(lfn, reusableBuffer.sdmanager.lines[index]); audioQueue.playFile(lfn, PLAY_BACKGROUND, 255); } #endif #if defined(PCBTARANIS) else if (result == STR_ASSIGN_BITMAP) { strcpy(lfn, reusableBuffer.sdmanager.lines[index]); // TODO duplicated code for finding extension uint8_t len = strlen(lfn) - 4; memset(lfn+len, 0, sizeof(g_model.header.bitmap)-len); // TODO duplicated code memcpy(g_model.header.bitmap, lfn, sizeof(g_model.header.bitmap)); LOAD_MODEL_BITMAP(); memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); eeDirty(EE_MODEL); } #endif }
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 modelDefault(uint8_t id) { memset(&g_model, 0, sizeof(SKYModelData)); strncpy_P(g_model.name,PSTR(STR_MODEL), 10 ); g_model.name[5]='0'+(id+1)/10; g_model.name[6]='0'+(id+1)%10; g_model.modelVersion = MDSKYVERS; g_model.trimInc = 1 ; applyTemplate(0) ; //default 4 channel template memcpy(ModelNames[id+1], g_model.name, sizeof(g_model.name)); g_model.protocol = PROTO_OFF ; g_model.xprotocol = PROTO_OFF ; eeDirty(EE_MODEL) ; }
int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event) { uint16_t delta = GV_GET_GV1_VALUE(max); bool invers = (attr & INVERS); // TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { s_editMode = !s_editMode; if (attr & PREC1) value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta); else value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta); eeDirty(EE_MODEL); } if (GV_IS_GV_VALUE(value, min, max)) { if (attr & LEFT) attr -= LEFT; /* because of ZCHAR */ else x -= 2*FW+FWNUM; attr &= ~PREC1; int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta); if (idx >= 0) ++idx; // transform form idx=0=GV1 to idx=1=GV1 in order to handle double keys invert if (invers) { CHECK_INCDEC_MODELVAR_CHECK(event, idx, -MAX_GVARS, MAX_GVARS, noZero); if (idx == 0) idx = 1; // handle reset to zero, map to GV1 } if (idx < 0) { value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta); idx = -idx; lcd_putcAtt(x-6, y, '-', attr); } else { value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta); } putsStrIdx(x, y, STR_GV, idx, attr); } else { lcd_outdezAtt(x, y, value, attr); if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); } return value; }
void onTelemetryScriptFileSelectionMenu(const char *result) { int sub = m_posVert; int screenIndex = TELEMETRY_CURRENT_SCREEN(sub); if (result == STR_UPDATE_LIST) { if (!listSdFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) { POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); s_menu_flags = 0; } } else { // The user choosed a file in the list memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file)); eeDirty(EE_MODEL); LUA_LOAD_MODEL_SCRIPTS(); } }
static int luaModelSetInfo(lua_State *L) { luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "name")) { const char * name = luaL_checkstring(L, -1); str2zchar(g_model.header.name, name, sizeof(g_model.header.name)); memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name)); } else if (!strcmp(key, "bitmap")) { const char * name = luaL_checkstring(L, -1); strncpy(g_model.header.bitmap, name, sizeof(g_model.header.bitmap)); } } eeDirty(EE_MODEL); return 0; }
/*luadoc @function model.setOutput(index, value) Sets current global variable value. See also model.getGlobalVariable() @param index zero based output index, use 0 for CH1, 31 for CH32 @param value new value for output. The `value` is a table with following items: * `name` name of the output (channel) * `min` negative limit * `max` positive limit * `offset` subtrim value * `ppmCenter` ppm center value * `symetrical` 1 for symmetric limits, 0 for normal * `revert` 1 for inverted output, 0 for normal * `curve` curve reference (zero based index, 0 means Curve 1) */ static int luaModelSetOutput(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); if (idx < NUM_CHNOUT) { LimitData * limit = limitAddress(idx); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "name")) { const char * name = luaL_checkstring(L, -1); str2zchar(limit->name, name, sizeof(limit->name)); } else if (!strcmp(key, "min")) { limit->min = luaL_checkinteger(L, -1)+1000; } else if (!strcmp(key, "max")) { limit->max = luaL_checkinteger(L, -1)-1000; } else if (!strcmp(key, "offset")) { limit->offset = luaL_checkinteger(L, -1); } else if (!strcmp(key, "ppmCenter")) { limit->ppmCenter = luaL_checkinteger(L, -1); } else if (!strcmp(key, "symetrical")) { limit->symetrical = luaL_checkinteger(L, -1); } else if (!strcmp(key, "revert")) { limit->revert = luaL_checkinteger(L, -1); } else if (!strcmp(key, "curve")) { if (lua_isnil(L, -1)) limit->curve = 0; else limit->curve = luaL_checkinteger(L, -1) + 1; } } eeDirty(EE_MODEL); } return 0; }
void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event) { TimerData * timer = &g_model.timers[timerIdx]; putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, menuHorizontalPosition==1 ? attr|TIMEHOUR : TIMEHOUR, menuHorizontalPosition==2 ? attr|TIMEHOUR : TIMEHOUR); if (attr && menuHorizontalPosition < 0) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 11*FW, FH+1); if (attr && s_editMode>0) { div_t qr = div(timer->start, 60); switch (menuHorizontalPosition) { case 0: { swsrc_t timerMode = timer->mode; if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); if (timerMode < 0) timerMode += TMRMODE_COUNT-1; timer->mode = timerMode; #if defined(AUTOSWITCH) if (s_editMode>0) { swsrc_t val = timer->mode - (TMRMODE_COUNT-1); swsrc_t switchVal = checkIncDecMovedSwitch(val); if (val != switchVal) { timer->mode = switchVal + (TMRMODE_COUNT-1); eeDirty(EE_MODEL); } } #endif break; } case 1: qr.quot = checkIncDec(event, qr.quot, 0, 1439, EE_MODEL | NO_INCDEC_MARKS); // 23h59 timer->start = qr.rem + qr.quot*60; break; case 2: qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2; timer->start -= qr.rem ; if ((int16_t)timer->start < 0) timer->start=0; if ((int32_t)timer->start > 86399) timer->start=86399; // 23h59:59 break; } } }
void deleteExpoMix(uint8_t expo, uint8_t idx) { pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); int input = expo->chn; memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData)); if (!isInputAvailable(input)) { memclear(&g_model.inputNames[input], LEN_INPUT_NAME); } } else { MixData *mix = mixAddress(idx); memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData)); memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData)); } resumeMixerCalculations(); eeDirty(EE_MODEL); }
void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event) { TimerData * timer = &g_model.timers[timerIdx]; putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); if (attr && m_posHorz < 0) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); if (attr && s_editMode>0) { div_t qr = div(timer->start, 60); switch (m_posHorz) { case 0: { swsrc_t timerMode = timer->mode; if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); if (timerMode < 0) timerMode += TMRMODE_COUNT-1; timer->mode = timerMode; #if defined(AUTOSWITCH) if (s_editMode>0) { swsrc_t val = timer->mode - (TMRMODE_COUNT-1); swsrc_t switchVal = checkIncDecMovedSwitch(val); if (val != switchVal) { timer->mode = switchVal + (TMRMODE_COUNT-1); eeDirty(EE_MODEL); } } #endif break; } case 1: CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59); timer->start = qr.rem + qr.quot*60; break; case 2: qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2; timer->start -= qr.rem ; if ((int16_t)timer->start < 0) timer->start=0; break; } } }
uint8_t checkLastSwitch(uint8_t sw,uint8_t flg) //recognize switch changes { static bool lastState[SW_Trainer-SW_BASE+1]; uint8_t newSw = sw; for( uint8_t i=0; i< (SW_Trainer-SW_BASE+1); i++) { EnumKeys key = (EnumKeys)(i+SW_BASE); bool st= keyState(key); if(st != lastState[i]) { lastState[i] = st; if(key<SW_ID0 || key>SW_ID2 || st==true){ newSw = i+1; if((flg&_FL_POSNEG) && !st) newSw=-newSw; } } } if(sw==newSw) return sw; if(flg&(EE_MODEL|EE_GENERAL)) eeDirty(flg&(EE_MODEL|EE_GENERAL)); return newSw; }
void onCustomFunctionsFileSelectionMenu(const char *result) { int sub = menuVerticalPosition; CustomFunctionData * cfn; uint8_t eeFlags; if (menuHandlers[menuLevel] == menuModelCustomFunctions) { cfn = &g_model.customFn[sub]; eeFlags = EE_MODEL; } else { cfn = &g_eeGeneral.customFn[sub]; eeFlags = EE_GENERAL; } uint8_t func = CFN_FUNC(cfn); if (result == STR_UPDATE_LIST) { char directory[256]; if (func == FUNC_PLAY_SCRIPT) { strcpy(directory, SCRIPTS_FUNCS_PATH); } else { strcpy(directory, SOUNDS_PATH); strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); } if (!listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), NULL)) { POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); } } else { // The user choosed a file in the list memcpy(cfn->play.name, result, sizeof(cfn->play.name)); eeDirty(eeFlags); if (func == FUNC_PLAY_SCRIPT) { LUA_LOAD_MODEL_SCRIPTS(); } } }
static int luaModelSetCustomFunction(lua_State *L) { unsigned int idx = luaL_checkunsigned(L, 1); if (idx < NUM_CFN) { CustomFunctionData * cfn = &g_model.customFn[idx]; memclear(cfn, sizeof(CustomFunctionData)); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "switch")) { CFN_SWITCH(cfn) = luaL_checkinteger(L, -1); } else if (!strcmp(key, "func")) { CFN_FUNC(cfn) = luaL_checkinteger(L, -1); } else if (!strcmp(key, "name")) { const char * name = luaL_checkstring(L, -1); strncpy(cfn->play.name, name, sizeof(cfn->play.name)); } else if (!strcmp(key, "value")) { cfn->all.val = luaL_checkinteger(L, -1); } else if (!strcmp(key, "mode")) { cfn->all.mode = luaL_checkinteger(L, -1); } else if (!strcmp(key, "param")) { cfn->all.param = luaL_checkinteger(L, -1); } else if (!strcmp(key, "active")) { CFN_ACTIVE(cfn) = luaL_checkinteger(L, -1); } } eeDirty(EE_MODEL); } return 0; }
void generalDefault() { memset(&g_eeGeneral,0,sizeof(g_eeGeneral)); g_eeGeneral.myVers = MDSKYVERS ; g_eeGeneral.currModel= 0; g_eeGeneral.contrast = 30; g_eeGeneral.vBatWarn = 65; g_eeGeneral.stickMode= 1; g_eeGeneral.disablePotScroll= 1; g_eeGeneral.bright = 50 ; g_eeGeneral.volume = 2 ; g_eeGeneral.lightSw = MAX_SKYDRSWITCH ; // ON for (int i = 0; i < NUM_ANALOG_CALS ; ++i ) { *CalibMid[i] = 0x400 ; *CalibSpanPos[i] = 0x300 ; *CalibSpanNeg[i] = 0x300 ; } strncpy_P(g_eeGeneral.ownerName,PSTR(STR_ME), 10); g_eeGeneral.chkSum = evalChkSum() ; eeDirty(EE_GENERAL) ; }