diff --git a/src/FatFs/ffconf.h b/src/FatFs/ffconf.h index 6754c9e61..fcdf65533 100644 --- a/src/FatFs/ffconf.h +++ b/src/FatFs/ffconf.h @@ -188,12 +188,12 @@ extern "C" { #if defined(CPUARM) #define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ + #define _SYNC_t unsigned char /*OS_MutexID*/ /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ #else #define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ #endif #define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ -#define _SYNC_t OS_MutexID /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ /* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module. / diff --git a/src/debug.cpp b/src/debug.cpp index 1087ad562..83394f38e 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -35,6 +35,7 @@ */ #include "../opentx.h" +#include #include #if !defined(SIMU) diff --git a/src/gtests.cpp b/src/gtests.cpp index 54f0bf38a..4d229be71 100644 --- a/src/gtests.cpp +++ b/src/gtests.cpp @@ -49,7 +49,9 @@ void doMixerCalculations(); memset(ex_chans, 0, sizeof(ex_chans)); \ memset(act, 0, sizeof(act)); \ memset(swOn, 0, sizeof(swOn)); \ - int32_t lastAct = 0; lastAct = lastAct; /* to avoid a warning */ + int32_t lastAct = 0; lastAct = lastAct; /* to avoid a warning */ \ + s_last_switch_used = 0; \ + s_last_switch_value = 0; uint16_t anaInValues[NUM_STICKS+NUM_POTS] = { 0 }; uint16_t anaIn(uint8_t chan) @@ -231,10 +233,8 @@ TEST(EEPROM, rm) EXPECT_EQ(sz, 0); } -#if defined(FRSKY) - +#if defined(FRSKY) && !defined(FRSKY_SPORT) extern void processFrskyPacket(uint8_t *packet); - TEST(FrSky, gpsNfuel) { g_model.frsky.usrProto = 1; @@ -279,25 +279,37 @@ TEST(FrSky, dateNtime) EXPECT_EQ(frskyData.hub.min, 18); EXPECT_EQ(frskyData.hub.sec, 50); } - #endif +#if defined(FRSKY_SPORT) +extern bool checkSportPacket(uint8_t *packet); +TEST(FrSkySPORT, checkCrc) +{ + // uint8_t pkt[] = { 0x7E, 0x98, 0x10, 0x10, 0x00, 0x7D, 0x5E, 0x02, 0x00, 0x00, 0x5F }; + uint8_t pkt[] = { 0x7E, 0x98, 0x10, 0x10, 0x00, 0x7E, 0x02, 0x00, 0x00, 0x5F }; + EXPECT_EQ(checkSportPacket(pkt+1), true); +} +#endif + +#if !defined(PCBTARANIS) TEST(getSwitch, undefCSW) { MODEL_RESET(); EXPECT_EQ(getSwitch(MAX_PSWITCH), false); EXPECT_EQ(getSwitch(-MAX_PSWITCH), true); // no good answer there! } +#endif TEST(getSwitch, circularCSW) { MODEL_RESET(); - g_model.customSw[0] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_OR }; - g_model.customSw[1] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_AND }; - EXPECT_EQ(getSwitch(MAX_SWITCH-NUM_CSW), false); - EXPECT_EQ(getSwitch(-(MAX_SWITCH-NUM_CSW)), true); - EXPECT_EQ(getSwitch(1+MAX_SWITCH-NUM_CSW), false); - EXPECT_EQ(getSwitch(-(1+MAX_SWITCH-NUM_CSW)), true); + MIXER_RESET(); + g_model.customSw[0] = { SWSRC_SW1, SWSRC_SW1, CS_OR }; + g_model.customSw[1] = { SWSRC_SW1, SWSRC_SW1, CS_AND }; + EXPECT_EQ(getSwitch(SWSRC_SW1), false); + EXPECT_EQ(getSwitch(-SWSRC_SW1), true); + EXPECT_EQ(getSwitch(SWSRC_SW2), false); + EXPECT_EQ(getSwitch(-SWSRC_SW2), true); } TEST(getSwitch, nullSW) @@ -306,6 +318,32 @@ TEST(getSwitch, nullSW) EXPECT_EQ(getSwitch(0), true); } +#if !defined(PCBTARANIS) +TEST(getSwitch, recursiveSW) +{ + MODEL_RESET(); + MIXER_RESET(); + + g_model.customSw[0] = { SWSRC_RUD, -SWSRC_SW2, CS_OR }; + g_model.customSw[1] = { SWSRC_ELE, -SWSRC_SW1, CS_OR }; + + EXPECT_EQ(getSwitch(SWSRC_SW1), false); + EXPECT_EQ(getSwitch(SWSRC_SW2), true); + + s_last_switch_used = 0; + EXPECT_EQ(getSwitch(SWSRC_SW1), false); + EXPECT_EQ(getSwitch(SWSRC_SW2), true); + + simuSetSwitch(1, 1); + s_last_switch_used = 0; + EXPECT_EQ(getSwitch(SWSRC_SW1), true); + EXPECT_EQ(getSwitch(SWSRC_SW2), true); + + s_last_switch_used = 0; + EXPECT_EQ(getSwitch(SWSRC_SW1), true); + EXPECT_EQ(getSwitch(SWSRC_SW2), false); +} + TEST(FlightModes, nullFadeOut_posFadeIn) { MODEL_RESET(); @@ -415,6 +453,7 @@ TEST(Mixer, Cascaded5Channels) EXPECT_EQ(chans[4], -CHANNEL_MAX); } } +#endif TEST(Mixer, InfiniteRecursiveChannels) { @@ -512,6 +551,7 @@ TEST(Mixer, RecursiveAddChannelAfterInactivePhase) } \ } while (0) +#if !defined(CPUARM) TEST(Mixer, SlowOnSwitch) { MODEL_RESET(); @@ -582,7 +622,9 @@ TEST(Mixer, SlowOnSwitchAndPhase) s_perout_flight_phase = 1; CHECK_SLOW_MOVEMENT(0, -1, 250); } +#endif +#if !defined(PCBTARANIS) TEST(Mixer, SlowOnSwitchSource) { MODEL_RESET(); @@ -627,7 +669,9 @@ TEST(Mixer, SlowAndDelayOnReplace3POSSource) CHECK_DELAY(0, 500); CHECK_SLOW_MOVEMENT(0, +1, 250); } +#endif +#if !defined(CPUARM) TEST(Mixer, SlowOnSwitchReplace) { MODEL_RESET(); @@ -657,7 +701,9 @@ TEST(Mixer, SlowOnSwitchReplace) // slow is not applied, but it's better than the first mix not applied at all! EXPECT_EQ(chans[0], CHANNEL_MAX/2); } +#endif +#if !defined(PCBTARANIS) TEST(Mixer, NoTrimOnInactiveMix) { MODEL_RESET(); @@ -677,6 +723,7 @@ TEST(Mixer, NoTrimOnInactiveMix) simuSetSwitch(0, 0); CHECK_SLOW_MOVEMENT(0, -1, 100); } +#endif TEST(Curves, LinearIntpol) { diff --git a/src/gui/menu_model.cpp b/src/gui/menu_model.cpp index 03a7922ed..e59e56f8d 100644 --- a/src/gui/menu_model.cpp +++ b/src/gui/menu_model.cpp @@ -894,7 +894,7 @@ enum menuModelSetupItems { #endif #if defined(PCBTARANIS) && defined(SDCARD) -void onModelSetupMenu(const char *result) +void onModelSetupBitmapMenu(const char *result) { if (result == STR_UPDATE_LIST) { if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), NULL)) { @@ -904,7 +904,10 @@ void onModelSetupMenu(const char *result) } else { // The user choosed a bmp file in the list - memcpy(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); + if (memcmp(result, "---", 3) == 0) + memset(g_model.header.bitmap, 0, sizeof(g_model.header.bitmap)); + else + memcpy(g_model.header.bitmap, result, 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); @@ -984,14 +987,14 @@ void menuModelSetup(uint8_t event) #if defined(PCBTARANIS) && defined(SDCARD) case ITEM_MODEL_BITMAP: lcd_putsLeft(y, STR_BITMAP); - if (ZLEN(g_model.header.bitmap) > 0) + if (ZEXIST(g_model.header.bitmap)) lcd_putsnAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.bitmap, sizeof(g_model.header.bitmap), attr); else lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; if (listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), g_model.header.bitmap, LIST_NONE_SD_FILE)) { - menuHandler = onModelSetupMenu; + menuHandler = onModelSetupBitmapMenu; } else { POPUP_WARNING(STR_NO_BITMAPS_ON_SD); @@ -1223,7 +1226,6 @@ void menuModelSetup(uint8_t event) } break; - case ITEM_MODEL_INTERNAL_MODULE_CHANNELS: case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS: case ITEM_MODEL_TRAINER_CHANNELS: @@ -2869,8 +2871,8 @@ void menuModelMixOne(uint8_t event) #endif case MIX_FIELD_SOURCE: lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_SOURCE)); - putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, attr); - if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST_CH); + putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); + if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); break; case MIX_FIELD_WEIGHT: lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT); @@ -2987,6 +2989,8 @@ static uint8_t s_copySrcCh; #define _STR_MAX(x) PSTR("/" #x) #define STR_MAX(x) _STR_MAX(x) +#define MIX_LINE_SRC_POS 4*FW-1 + #if LCD_W >= 212 #define EXPO_LINE_WEIGHT_POS 7*FW+1 #define EXPO_LINE_EXPO_POS 11*FW+5 @@ -2995,7 +2999,6 @@ static uint8_t s_copySrcCh; #define EXPO_LINE_SELECT_POS 18 #define EXPO_LINE_FM_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH-FW-1 #define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH - #define MIX_LINE_SRC_POS 4*FW #define MIX_LINE_WEIGHT_POS 11*FW+5 #define MIX_LINE_CURVE_POS 12*FW+4 #define MIX_LINE_SWITCH_POS 16*FW+1 @@ -3008,7 +3011,6 @@ static uint8_t s_copySrcCh; #define EXPO_LINE_SELECT_POS 24 #define EXPO_LINE_FM_POS #define EXPO_LINE_NAME_POS LCD_W-sizeof(ed->name)*FW-MENUS_SCROLLBAR_WIDTH - #define MIX_LINE_SRC_POS 4*FW #define MIX_LINE_WEIGHT_POS 11*FW+3 #define MIX_LINE_CURVE_POS 12*FW+2 #define MIX_LINE_SWITCH_POS 16*FW @@ -3024,7 +3026,6 @@ static uint8_t s_copySrcCh; #endif #define EXPO_LINE_FM_POS LCD_W-FW-MENUS_SCROLLBAR_WIDTH #define EXPO_LINE_SELECT_POS 24 - #define MIX_LINE_SRC_POS 4*FW #define MIX_LINE_WEIGHT_POS 11*FW+3 #define MIX_LINE_CURVE_POS 12*FW+2 #define MIX_LINE_SWITCH_POS 16*FW @@ -3754,6 +3755,23 @@ void menuModelGVars(uint8_t event) } #endif +#if defined(CPUARM) + #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL; IsValueAvailable isValueAvailable = NULL + #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f)) + #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn + #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) +#elif defined(CPUM64) + #define INCDEC_DECLARE_VARS() + #define INCDEC_SET_FLAG(f) + #define INCDEC_ENABLE_CHECK(fn) + #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL) +#else + #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL + #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f)) + #define INCDEC_ENABLE_CHECK(fn) + #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag) +#endif + enum CustomSwitchFields { CSW_FIELD_FUNCTION, CSW_FIELD_V1, @@ -3770,7 +3788,7 @@ enum CustomSwitchFields { #if LCD_W >= 212 #define CSW_1ST_COLUMN (4*FW-3) #define CSW_2ND_COLUMN (8*FW+1) - #define CSW_3RD_COLUMN (13*FW+2) + #define CSW_3RD_COLUMN (14*FW) #define CSW_4TH_COLUMN (21*FW+1) #define CSW_5TH_COLUMN (26*FW+1) #define CSW_6TH_COLUMN (31*FW+1) @@ -3916,9 +3934,7 @@ void menuModelCustomSwitches(uint8_t event) #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: #endif -#if !defined(PCBTARANIS) case EVT_KEY_FIRST(KEY_RIGHT): -#endif case EVT_KEY_FIRST(KEY_ENTER): if (sub >= 0) { s_currIdx = sub; @@ -3971,18 +3987,12 @@ void menuModelCustomSwitches(uint8_t event) } } } + #else void menuModelCustomSwitches(uint8_t event) { -#if defined(CPUM64) - #define INCDEC_SET_FLAG(f) - #define CHECK_INCDEC_CSPARAM(event, var, min, max) CHECK_INCDEC_MODELVAR(event, var, min, max) -#else - uint8_t incdecFlag; - #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f)) - #define CHECK_INCDEC_CSPARAM(event, var, min, max) var = checkIncDec(event, var, min, max, incdecFlag) -#endif + INCDEC_DECLARE_VARS(); MENU(STR_MENUCUSTOMSWITCHES, menuTabModel, e_CustomSwitches, NUM_CSW+1, {0, NAVIGATION_LINE_BY_LINE|CSW_FIELD_LAST/*repeated...*/}); @@ -4014,7 +4024,11 @@ void menuModelCustomSwitches(uint8_t event) // CSW params uint8_t cstate = cswFamily(cs->func); +#if defined(CPUARM) + int16_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; +#else int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; +#endif if (cstate == CS_VBOOL) { putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); @@ -4022,11 +4036,13 @@ void menuModelCustomSwitches(uint8_t event) v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1; INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_ENABLE_CHECK(NULL); } else if (cstate == CS_VCOMP) { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, attr1); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_ENABLE_CHECK(isSourceAvailable); } else if (cstate == CS_VTIMER) { lcd_outdezAtt(CSW_2ND_COLUMN, y, cswTimerValue(cs->v1), LEFT|PREC1|attr1); @@ -4034,13 +4050,18 @@ void menuModelCustomSwitches(uint8_t event) v1_min = v2_min = -128; v1_max = v2_max = 122; INCDEC_SET_FLAG(0); + INCDEC_ENABLE_CHECK(NULL); } else { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, attr1); - if (horz == 1) + if (horz == 1) { INCDEC_SET_FLAG(INCDEC_SOURCE); - else + INCDEC_ENABLE_CHECK(isSourceAvailable); + } + else { INCDEC_SET_FLAG(0); + INCDEC_ENABLE_CHECK(NULL); + } #if defined(FRSKY) if (cs->v1 >= MIXSRC_FIRST_TELEM) { putsTelemetryChannel(CSW_3RD_COLUMN, y, cs->v1 - MIXSRC_FIRST_TELEM, convertCswTelemValue(cs), LEFT|attr2); @@ -4102,10 +4123,10 @@ void menuModelCustomSwitches(uint8_t event) break; } case CSW_FIELD_V1: - CHECK_INCDEC_CSPARAM(event, cs->v1, v1_min, v1_max); + cs->v1 = CHECK_INCDEC_PARAM(event, cs->v1, v1_min, v1_max); break; case CSW_FIELD_V2: - CHECK_INCDEC_CSPARAM(event, cs->v2, v2_min, v2_max); + cs->v2 = CHECK_INCDEC_PARAM(event, cs->v2, v2_min, v2_max); break; case CSW_FIELD_ANDSW: #if defined(CPUARM) @@ -4247,6 +4268,7 @@ void menuModelCustomFunctions(uint8_t event) case 2: if (sd->swtch) { + INCDEC_DECLARE_VARS(); int16_t val_displayed = CFN_PARAM(sd); int8_t val_min = 0; uint8_t val_max = 255; @@ -4271,7 +4293,7 @@ void menuModelCustomFunctions(uint8_t event) #else xcoord_t x = (CFN_FUNC(sd) == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN); #endif - if (ZLEN(sd->param.name)) + if (ZEXIST(sd->param.name)) lcd_putsnAtt(x, y, sd->param.name, sizeof(sd->param.name), attr); else lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr); @@ -4292,12 +4314,14 @@ void menuModelCustomFunctions(uint8_t event) else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 2; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+1, attr); + INCDEC_ENABLE_CHECK(isSourceP1Available); } #endif #if defined(CPUARM) else if (CFN_FUNC(sd) == FUNC_VOLUME) { val_max = MIXSRC_LAST_CH-1; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+1, attr); + INCDEC_ENABLE_CHECK(isSourceP1Available); } #elif defined(VOICE) else if (CFN_FUNC(sd) == FUNC_PLAY_TRACK) { @@ -4326,6 +4350,7 @@ void menuModelCustomFunctions(uint8_t event) else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 2; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+1, attr); + INCDEC_ENABLE_CHECK(isSourceP1Available); } #endif #if defined(SDCARD) @@ -4363,6 +4388,7 @@ void menuModelCustomFunctions(uint8_t event) case FUNC_ADJUST_GVAR_SOURCE: val_max = MIXSRC_LAST_CH-1; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+1, attr); + INCDEC_ENABLE_CHECK(isSourceP1Available); break; case FUNC_ADJUST_GVAR_GVAR: val_max = MAX_GVARS-1; @@ -4389,7 +4415,7 @@ void menuModelCustomFunctions(uint8_t event) } if (active) { - CFN_PARAM(sd) = checkIncDec(event, val_displayed, val_min, val_max, EE_MODEL); + CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); } } else if (attr) { diff --git a/src/gui/menus.cpp b/src/gui/menus.cpp index e69fc9b41..56f4cc514 100644 --- a/src/gui/menus.cpp +++ b/src/gui/menus.cpp @@ -86,7 +86,12 @@ int8_t p2valdiff; #endif int8_t checkIncDec_Ret; + +#if defined(CPUARM) +int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags, IsValueAvailable isValueAvailable) +#else int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) +#endif { int16_t newval = val; @@ -126,7 +131,14 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui #else if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { #endif +#if defined(CPUARM) + do { + newval++; + } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); + if (newval > i_max) newval = val; +#else newval++; +#endif AUDIO_KEYPAD_UP(); } #if defined(PCBTARANIS) @@ -134,7 +146,14 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui #else else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { #endif +#if defined(CPUARM) + do { + newval--; + } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); + if (newval < i_min) newval = val; +#else newval--; +#endif AUDIO_KEYPAD_DOWN(); } @@ -1067,3 +1086,40 @@ void drawStatusLine() } } #endif + +#if defined(CPUARM) +bool isSourceAvailable(int16_t source) +{ +#if !defined(HELI) + if (source>=MIXSRC_CYC1 && source<=MIXSRC_CYC3) + return false; +#endif + + if (source>=MIXSRC_CH1 && source<=MIXSRC_LAST_CH) { + uint8_t destCh = source-MIXSRC_CH1; + for (uint8_t i = 0; i < MAX_MIXERS; i++) { + MixData *md = mixAddress(i); + if (md->srcRaw == 0) return false; + if (md->destCh==destCh) return true; + } + return false; + } + + if (source>=MIXSRC_SW1 && source<=MIXSRC_LAST_CSW) { + CustomSwData * cs = cswAddress(source-MIXSRC_SW1); + return (cs->func != CS_OFF); + } + +#if !defined(GVARS) + if (source>=MIXSRC_GVAR1 && source<=MIXSRC_LAST_GVAR) + return false; +#endif + + return true; +} + +bool isSourceP1Available(int16_t source) +{ + return isSourceAvailable(source+1); +} +#endif diff --git a/src/gui/menus.h b/src/gui/menus.h index e561e2edf..114ebc8a5 100644 --- a/src/gui/menus.h +++ b/src/gui/menus.h @@ -154,7 +154,12 @@ extern int8_t s_editMode; // global editmode #define TITLE_ROW ((uint8_t)-1) #define HIDDEN_ROW ((uint8_t)-2) +#if defined(CPUARM) +typedef bool (*IsValueAvailable)(int16_t); +int16_t checkIncDec(uint8_t event, int16_t i_pval, int16_t i_min, int16_t i_max, uint8_t i_flags=0, IsValueAvailable isValueAvailable=NULL); +#else int16_t checkIncDec(uint8_t event, int16_t i_pval, int16_t i_min, int16_t i_max, uint8_t i_flags=0); +#endif #if defined(CPUM64) int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max); @@ -173,19 +178,24 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max); var = checkIncDecModelZero(event,var,max) #if defined(AUTOSWITCH) -#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) -#define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \ - var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH) + #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) + #define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \ + var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH) #else -#define AUTOSWITCH_ENTER_LONG() (0) -#define CHECK_INCDEC_MODELSWITCH CHECK_INCDEC_MODELVAR + #define AUTOSWITCH_ENTER_LONG() (0) + #define CHECK_INCDEC_MODELSWITCH CHECK_INCDEC_MODELVAR #endif -#if defined(AUTOSOURCE) -#define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \ - var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE) +#if defined(CPUARM) + bool isSourceAvailable(int16_t source); + bool isSourceP1Available(int16_t source); + #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \ + var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable) +#elif defined(AUTOSOURCE) + #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \ + var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS) #else -#define CHECK_INCDEC_MODELSOURCE CHECK_INCDEC_MODELVAR + #define CHECK_INCDEC_MODELSOURCE CHECK_INCDEC_MODELVAR #endif #define CHECK_INCDEC_GENVAR(event, var, min, max) \ diff --git a/src/gui/view_main.cpp b/src/gui/view_main.cpp index 2f3e7c7a2..40fd59b25 100644 --- a/src/gui/view_main.cpp +++ b/src/gui/view_main.cpp @@ -319,7 +319,7 @@ void displayTimers() if (g_model.timers[0].mode) { TimerState & timerState = timersStates[0]; putsTime(TIMERS_X, TIMER1_Y, timerState.val, MIDSIZE|LEFT, MIDSIZE|LEFT); - putsTmrMode(TIMERS_X, TIMER1_Y-6, g_model.timers[0].mode, SWCONDENSED|SMLSIZE); + putsTmrMode(TIMERS_X, TIMER1_Y-6, g_model.timers[0].mode, STRCONDENSED|SMLSIZE); if (g_model.timers[0].persistent) lcd_putcAtt(TIMERS_R, TIMER1_Y+1, 'P', SMLSIZE); if (timerState.val < 0) lcd_hline(TIMERS_X-6, TIMER1_Y+2, 4); } @@ -328,7 +328,7 @@ void displayTimers() if (g_model.timers[1].mode) { TimerState & timerState = timersStates[1]; putsTime(TIMERS_X, TIMER2_Y, timerState.val, MIDSIZE|LEFT, MIDSIZE|LEFT); - putsTmrMode(TIMERS_X, TIMER2_Y-6, g_model.timers[1].mode, SWCONDENSED|SMLSIZE); + putsTmrMode(TIMERS_X, TIMER2_Y-6, g_model.timers[1].mode, STRCONDENSED|SMLSIZE); if (g_model.timers[1].persistent) lcd_putcAtt(TIMERS_R, TIMER2_Y+1, 'P', SMLSIZE); if (timerState.val < 0) lcd_hline(TIMERS_X-6, TIMER2_Y+2, 4); } @@ -353,7 +353,7 @@ void displayTimers() TimerState & timerState = timersStates[0]; uint8_t att = DBLSIZE | (timerState.state==TMR_BEEPING ? BLINK|INVERS : 0); putsTime(12*FW+2+10*FWNUM-4, FH*2, timerState.val, att, att); - putsTmrMode(timerState.val >= 0 ? 9*FW-FW/2+3 : 9*FW-FW/2-4, FH*3, g_model.timers[0].mode, SWCONDENSED); + putsTmrMode(timerState.val >= 0 ? 9*FW-FW/2+3 : 9*FW-FW/2-4, FH*3, g_model.timers[0].mode, STRCONDENSED); } } #endif @@ -801,7 +801,7 @@ void menuMainView(uint8_t event) } else { // timer2 putsTime(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE, DBLSIZE); - putsTmrMode(timersStates[1].val >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timers[1].mode, SWCONDENSED); + putsTmrMode(timersStates[1].val >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timers[1].mode, STRCONDENSED); // lcd_outdezNAtt(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s } #endif // PCBTARANIS diff --git a/src/lcd.cpp b/src/lcd.cpp index b4058fad0..637835de7 100644 --- a/src/lcd.cpp +++ b/src/lcd.cpp @@ -808,11 +808,21 @@ void putsVBat(xcoord_t x, uint8_t y, LcdFlags att) void putsStrIdx(xcoord_t x, uint8_t y, const pm_char *str, uint8_t idx, LcdFlags att) { lcd_putsAtt(x, y, str, att); + if (att & SMLSIZE) lcd_outdezNAtt(lcdLastPos+1, y, idx, att|LEFT, 2); else lcd_outdezNAtt(lcdLastPos, y, idx, att|LEFT, 2); + +#if defined(CPUARM) + uint8_t lastPos = lcdLastPos; +#endif + lcd_putsAtt(x, y, str, att); + +#if defined(CPUARM) + lcdLastPos = lastPos; +#endif } void putsMixerSource(xcoord_t x, uint8_t y, uint8_t idx, LcdFlags att) @@ -830,8 +840,15 @@ void putsMixerSource(xcoord_t x, uint8_t y, uint8_t idx, LcdFlags att) #endif else if (idx < MIXSRC_CH1) putsStrIdx(x, y, STR_PPM, idx-MIXSRC_PPM1+1, att); - else if (idx <= MIXSRC_LAST_CH) + else if (idx <= MIXSRC_LAST_CH) { putsStrIdx(x, y, STR_CH, idx-MIXSRC_CH1+1, att); +#if defined(PCBTARANIS) + if (ZEXIST(g_model.limitData[idx-MIXSRC_CH1].name) && (att & STREXPANDED)) { + lcd_putcAtt(lcdLastPos, y, ' ', att); + lcd_putsnAtt(lcdLastPos+3, y, g_model.limitData[idx-MIXSRC_CH1].name, LEN_CHANNEL_NAME, ZCHAR|att); + } +#endif + } #if defined(GVARS) || !defined(PCBSTD) else if (idx <= MIXSRC_LAST_GVAR) putsStrIdx(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att); @@ -899,7 +916,7 @@ void putsSwitches(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att) if (idx > SWSRC_ON) { idx -= SWSRC_ON; char suffix = CHR_TOGGLE; - if (idx != SWSRC_ON && (~att & SWCONDENSED)) lcd_putcAtt(x+3*FW, y, suffix, att); + if (idx != SWSRC_ON && (~att & STRCONDENSED)) lcd_putcAtt(x+3*FW, y, suffix, att); } lcd_putsiAtt(x, y, STR_VSWITCHES, idx-1, att); } @@ -930,8 +947,9 @@ void putsCurve(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att) void putsTmrMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att) { - if (mode >= TMR_VAROFS+MAX_PSWITCH+NUM_CSW) + if (mode >= TMR_VAROFS+MAX_PSWITCH+NUM_CSW) { mode++; + } if (mode < 0) { mode = TMR_VAROFS - mode - 1; diff --git a/src/lcd.h b/src/lcd.h index 6931ce9ca..926abd7f8 100644 --- a/src/lcd.h +++ b/src/lcd.h @@ -86,6 +86,7 @@ /* no 0x80 here because of "GV"1 which is aligned LEFT */ /* no 0x10 here because of "MODEL"01 which uses LEADING0 */ #define BSS 0x20 +#define STRCONDENSED 0x40 /* means that THRm will be displayed as THR */ #define ZCHAR 0x80 /* lcd outdez flags */ @@ -104,9 +105,6 @@ #define FILL_WHITE 0x10 #endif -/* switches flags */ -#define SWCONDENSED 0x20 /* means that THRm will be displayed as THR */ - /* telemetry flags */ #define NO_UNIT 0x40 @@ -114,10 +112,12 @@ #define MIDSIZE 0x0100 #define SMLSIZE 0x0200 #define TINSIZE 0x0400 + #define STREXPANDED 0x0800 #else #define MIDSIZE DBLSIZE #define SMLSIZE 0x00 #define TINSIZE 0x00 + #define STREXPANDED 0x00 #endif #if defined(PCBTARANIS) diff --git a/src/myeeprom.h b/src/myeeprom.h index 303ff43af..955ebb99c 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -242,7 +242,7 @@ enum ModuleIndex { }; #define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME]; #define MODELDATA_EXTRA uint8_t externalModule; uint8_t trainerMode; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; -#define LIMITDATA_EXTRA char name[6]; +#define LIMITDATA_EXTRA char name[LEN_CHANNEL_NAME]; #define swstate_t uint16_t #elif defined(PCBSKY9X) #define MODELDATA_BITMAP @@ -323,6 +323,7 @@ PACK(typedef struct t_EEGeneral { #define LEN_BITMAP_NAME 10 #define LEN_EXPOMIX_NAME 8 #define LEN_FP_NAME 10 +#define LEN_CHANNEL_NAME 6 #elif defined(PCBSKY9X) #define LEN_MODEL_NAME 10 #define LEN_EXPOMIX_NAME 6 @@ -1172,9 +1173,11 @@ enum MixSources { MIXSRC_LAST_GVAR = MIXSRC_GVAR1+MAX_GVARS-1, MIXSRC_FIRST_TELEM, - MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+NUM_TELEMETRY-1, + MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+NUM_TELEMETRY-1 }; +#define MIXSRC_LAST MIXSRC_LAST_CH + #define MIN_POINTS 3 #define MAX_POINTS 17 diff --git a/src/opentx.cpp b/src/opentx.cpp index 03b62784d..9390a5409 100644 --- a/src/opentx.cpp +++ b/src/opentx.cpp @@ -97,13 +97,18 @@ ModelData g_model; uint8_t modelBitmap[MODEL_BITMAP_SIZE]; void loadModelBitmap(char *name, uint8_t *bitmap) { - char lfn[] = BITMAPS_PATH "/xxxxxxxxxx.bmp"; - strncpy(lfn+sizeof(BITMAPS_PATH), name, LEN_BITMAP_NAME); - lfn[sizeof(BITMAPS_PATH)+LEN_BITMAP_NAME] = '\0'; - strcat(lfn+sizeof(BITMAPS_PATH), BITMAPS_EXT); - if (bmpLoad(bitmap, lfn, MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { - memcpy(bitmap, logo_taranis, MODEL_BITMAP_SIZE); + uint8_t len = zlen(name, LEN_BITMAP_NAME); + if (len > 0) { + char lfn[] = BITMAPS_PATH "/xxxxxxxxxx.bmp"; + strncpy(lfn+sizeof(BITMAPS_PATH), name, len); + strcpy(lfn+sizeof(BITMAPS_PATH)+len, BITMAPS_EXT); + if (bmpLoad(bitmap, lfn, MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT) == 0) { + return; + } } + + // In all error cases, we set the default logo + memcpy(bitmap, logo_taranis, MODEL_BITMAP_SIZE); } #endif @@ -178,6 +183,15 @@ char idx2char(int8_t idx) } #if defined(CPUARM) +bool zexist(const char *str, uint8_t size) +{ + for (int i=0; i 0) { @@ -831,8 +845,6 @@ int16_t cyc_anas[3] = {0}; // TODO same naming convention than the putsMixerSource -bool __getSwitch(int8_t swtch); - getvalue_t getValue(uint8_t i) { /*srcRaw is shifted +1!*/ @@ -858,13 +870,13 @@ getvalue_t getValue(uint8_t i) else if (iandsw; - if (cs->func == CS_OFF || (s && !__getSwitch(s))) { + if (cs->func == CS_OFF || (s && !getSwitch(s))) { csLastValue[cs_idx] = CS_LAST_VALUE_INIT; result = false; } else if ((s=cswFamily(cs->func)) == CS_VBOOL) { - bool res1 = __getSwitch(cs->v1); - bool res2 = __getSwitch(cs->v2); + bool res1 = getSwitch(cs->v1); + bool res2 = getSwitch(cs->v2); switch (cs->func) { case CS_AND: result = (res1 && res2); @@ -1099,20 +1105,15 @@ bool __getSwitch(int8_t swtch) #endif if (result) - s_last_switch_value |= ((GETSWITCH_RECURSIVE_TYPE)1< 0 ? result : !result; } -bool getSwitch(int8_t swtch) -{ - s_last_switch_used = 0; - s_last_switch_value = 0; - return __getSwitch(swtch); -} - swstate_t switches_states = 0; int8_t getMovedSwitch() { @@ -1147,7 +1148,7 @@ int8_t getMovedSwitch() mask = (1<<(i-2)); prev = (switches_states & mask); } - bool next = __getSwitch(i); + bool next = getSwitch(i); if (prev != next) { if (i!=MAX_PSWITCH || next==true) result = next ? i : -i; @@ -1568,9 +1569,7 @@ void doSplash() #if defined(PCBSTD) lcdSetContrast(); -#elif defined(PCBTARANIS) - bool secondSplash = false; -#else +#elif !defined(PCBTARANIS) tmr10ms_t curTime = get_tmr10ms() + 10; uint8_t contrast = 10; lcdSetRefVolt(contrast); @@ -1599,17 +1598,7 @@ void doSplash() if (pwrCheck()==e_power_off) return; -#if defined(PCBTARANIS) - if (!secondSplash && get_tmr10ms() >= tgtime-200) { - secondSplash = true; - static uint8_t sdSplash[2+4*(LCD_W*LCD_H/8)]; - if (!bmpLoad(sdSplash, BITMAPS_PATH "/splash.bmp", LCD_W, LCD_H)) { - lcd_clear(); - lcd_bmp(0, 0, sdSplash); - lcdRefresh(); - } - } -#elif !defined(PCBSTD) +#if !defined(PCBTARANIS) && !defined(PCBSTD) if (curTime < get_tmr10ms()) { curTime += 10; if (contrast < g_eeGeneral.contrast) { @@ -3122,6 +3111,9 @@ void doMixerCalculations() static uint16_t delta = 0; static ACTIVE_PHASES_TYPE s_fade_flight_phases = 0; static uint8_t s_last_phase = 255; // TODO reinit everything here when the model changes, no??? + + s_last_switch_used = 0; + uint8_t phase = getFlightPhase(); if (s_last_phase != phase) { @@ -3160,6 +3152,7 @@ void doMixerCalculations() if (s_fade_flight_phases) { memclear(sum_chans512, sizeof(sum_chans512)); for (uint8_t p=0; p> 4) * fp_act[p]; weight += fp_act[p]; } + s_last_switch_used = 0; } assert(weight); s_perout_flight_phase = phase; diff --git a/src/opentx.h b/src/opentx.h index 7a4e88bd9..ac9d34eb5 100644 --- a/src/opentx.h +++ b/src/opentx.h @@ -219,11 +219,13 @@ #define NOINLINE #endif #define CONVERT_PTR(x) ((uint32_t)(uint64_t)(x)) + char *convertSimuPath(const char *path); #else #define FORCEINLINE inline __attribute__ ((always_inline)) #define NOINLINE __attribute__ ((noinline)) #define SIMU_SLEEP(x) #define CONVERT_PTR(x) ((uint32_t)(x)) + #define convertSimuPath(x) (x) #endif // RESX range is used for internal calculation; The menu says -100.0 to 100.0; internally it is -1024 to 1024 to allow some optimizations @@ -907,6 +909,14 @@ extern int8_t safetyCh[NUM_CHNOUT]; extern uint8_t trimsCheckTimer; +#if defined(CPUARM) + #define GETSWITCH_RECURSIVE_TYPE uint32_t +#else + #define GETSWITCH_RECURSIVE_TYPE uint16_t +#endif + +extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_used; +extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_value; extern int16_t csLastValue[NUM_CSW]; #define CS_LAST_VALUE_INIT -32768 @@ -1434,11 +1444,13 @@ void putsTelemetryValue(xcoord_t x, uint8_t y, lcdint_t val, uint8_t unit, uint8 #if defined(CPUARM) uint8_t zlen(const char *str, uint8_t size); +bool zexist(const char *str, uint8_t size); char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx); #define strcat_modelname(dest, idx) strcat_zchar(dest, modelHeaders[idx].name, LEN_MODEL_NAME, STR_MODEL, PSIZE(TR_MODEL), idx+1) #define strcat_phasename(dest, idx) strcat_zchar(dest, g_model.phaseData[idx].name, LEN_FP_NAME, NULL, 0, 0) #define strcat_mixername(dest, idx) strcat_zchar(dest, g_model.mixData[idx].name, LEN_EXPOMIX_NAME, NULL, 0, 0) #define ZLEN(s) zlen(s, sizeof(s)) +#define ZEXIST(s) zexist(s, sizeof(s)) #endif // Stick tolerance varies between transmitters, Higher is better diff --git a/src/targets/taranis/board_taranis.h b/src/targets/taranis/board_taranis.h index b3afaba90..2b99e1abb 100644 --- a/src/targets/taranis/board_taranis.h +++ b/src/targets/taranis/board_taranis.h @@ -37,8 +37,6 @@ #ifndef board_taranis_h #define board_taranis_h -#include - #include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rcc.h" #include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_gpio.h" #include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_spi.h" diff --git a/src/telemetry/frsky_sport.cpp b/src/telemetry/frsky_sport.cpp index d397fc1a0..69658da41 100644 --- a/src/telemetry/frsky_sport.cpp +++ b/src/telemetry/frsky_sport.cpp @@ -268,15 +268,15 @@ void processHubPacket(uint8_t id, uint16_t value) bool checkSportPacket(uint8_t *packet) { - short t_short =0; - for (int i=0; i> 8; //0-100 - t_short &= 0x00ff; - t_short += t_short >> 8; //0-0FF - t_short &= 0x00ff; - } - return packet[FRSKY_RX_PACKET_SIZE-1] == (uint8_t)t_short; + short crc = 0; + for (int i=1; i> 8; //0-100 + crc &= 0x00ff; + crc += crc >> 8; //0-0FF + crc &= 0x00ff; + } + return (crc == 0x00ff); } #define SPORT_DATA_U8(packet) (packet[4]) @@ -290,8 +290,8 @@ void processSportPacket(uint8_t *packet) uint8_t prim = packet[1]; uint16_t appId = *((uint16_t *)(packet+2)); -// if (!checkSportPacket(packet)) -// return; + if (!checkSportPacket(packet)) + return; switch (prim) {