diff --git a/src/main/cms/cms.c b/src/main/cms/cms.c index a32ab0af886..f2f66476e4d 100644 --- a/src/main/cms/cms.c +++ b/src/main/cms/cms.c @@ -902,7 +902,7 @@ long cmsMenuExit(displayPort_t *pDisplay, const void *ptr) setServoOutputEnabled(true); if ((exitType == CMS_EXIT_SAVEREBOOT) || (exitType == CMS_POPUP_SAVEREBOOT)) { - processDelayedSave(); + processDelayedSave(true); displayClearScreen(pDisplay); displayWrite(pDisplay, 5, 3, "REBOOTING..."); diff --git a/src/main/common/constants.h b/src/main/common/constants.h index 5447fa184e1..8f6db86ec6b 100644 --- a/src/main/common/constants.h +++ b/src/main/common/constants.h @@ -17,10 +17,10 @@ #pragma once -#define FEET_PER_MILE 5280 -#define FEET_PER_NAUTICALMILE 6076.118f -#define FEET_PER_KILOFEET 1000 // Used for altitude -#define METERS_PER_KILOMETER 1000 -#define METERS_PER_MILE 1609.344f -#define METERS_PER_FOOT 3.28084f -#define METERS_PER_NAUTICALMILE 1852.001f +#define FEET_PER_MILE 5280 +#define FEET_PER_NAUTICALMILE 6076.118f +#define FEET_PER_KILOFEET 1000 // Used for altitude +#define METERS_PER_KILOMETER 1000 +#define METERS_PER_MILE 1609.344f +#define METERS_PER_FOOT 3.28084f +#define METERS_PER_NAUTICALMILE 1852.001f diff --git a/src/main/fc/config.c b/src/main/fc/config.c index c9a50c60a25..a328bd3b8dd 100755 --- a/src/main/fc/config.c +++ b/src/main/fc/config.c @@ -68,6 +68,7 @@ #include "fc/config.h" #include "fc/controlrate_profile.h" +#include "fc/fc_core.h" #include "fc/rc_adjustments.h" #include "fc/rc_controls.h" #include "fc/rc_curves.h" @@ -375,9 +376,6 @@ void ensureEEPROMContainsValidData(void) */ void saveConfigAndNotify(void) { -#ifdef USE_OSD - osdStartedSaveProcess(); -#endif saveState = SAVESTATE_SAVEANDNOTIFY; } @@ -393,12 +391,24 @@ void saveConfig(void) } } -void processDelayedSave(void) +void processDelayedSave(bool readyToSave) { if (saveState == SAVESTATE_SAVEANDNOTIFY) { - processSaveConfigAndNotify(); - saveState = SAVESTATE_NONE; - } else if (saveState == SAVESTATE_SAVEONLY) { + if (emergInflightRearmEnabled() || !readyToSave) { + // Do not process save if we are potentially still flying. Once armed, this function will not be called until the next disarm. +#ifdef USE_OSD + osdSaveWaitingProcess(); +#endif + } else { +#ifdef USE_OSD + osdStartedSaveProcess(); +#endif + if (readyToSave) { + processSaveConfigAndNotify(); + saveState = SAVESTATE_NONE; + } + } + } else if (saveState == SAVESTATE_SAVEONLY && readyToSave) { suspendRxSignal(); writeEEPROM(); resumeRxSignal(); diff --git a/src/main/fc/config.h b/src/main/fc/config.h index ddb6a826b83..f046efe0fc3 100644 --- a/src/main/fc/config.h +++ b/src/main/fc/config.h @@ -121,7 +121,7 @@ void resetEEPROM(void); void readEEPROM(void); void writeEEPROM(void); void ensureEEPROMContainsValidData(void); -void processDelayedSave(void); +void processDelayedSave(bool readyToSave); void saveConfig(void); void saveConfigAndNotify(void); diff --git a/src/main/fc/fc_core.c b/src/main/fc/fc_core.c index bede8929fea..649387ee2a6 100644 --- a/src/main/fc/fc_core.c +++ b/src/main/fc/fc_core.c @@ -65,6 +65,7 @@ #include "io/beeper.h" #include "io/dashboard.h" #include "io/gps.h" +#include "io/osd.h" #include "io/serial.h" #include "io/statusindicator.h" #include "io/asyncfatfs/asyncfatfs.h" @@ -499,12 +500,29 @@ bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm) return counter >= EMERGENCY_ARMING_MIN_ARM_COUNT; } +uint16_t emergencyInFlightRearmTimeMS(void) +{ + uint16_t rearmMS = 0; + + if (STATE(IN_FLIGHT_EMERG_REARM)) { + timeMs_t currentTimeMs = millis(); + rearmMS = (uint16_t)((US2MS(lastDisarmTimeUs) + EMERGENCY_INFLIGHT_REARM_TIME_WINDOW_MS) - currentTimeMs); + } + + return rearmMS; +} + bool emergInflightRearmEnabled(void) { /* Emergency rearm allowed within 5s timeout period after disarm if craft still flying */ +// bool emergRearmActive = STATE(IN_FLIGHT_EMERG_REARM); +// DISABLE_STATE(IN_FLIGHT_EMERG_REARM); timeMs_t currentTimeMs = millis(); emergRearmStabiliseTimeout = 0; +// if (ARMING_FLAG(ARMED) && emergRearmActive && (armTime < (1 * USECS_PER_SEC))) +// ENABLE_STATE(IN_FLIGHT_EMERG_REARM); // This stays active for 1 second after re-arming + if ((lastDisarmReason != DISARM_SWITCH) || (currentTimeMs > US2MS(lastDisarmTimeUs) + EMERGENCY_INFLIGHT_REARM_TIME_WINDOW_MS)) { return false; @@ -872,7 +890,6 @@ static void applyThrottleTiltCompensation(void) void taskMainPidLoop(timeUs_t currentTimeUs) { - cycleTime = getTaskDeltaTime(TASK_SELF); dT = (float)cycleTime * 0.000001f; @@ -885,13 +902,15 @@ void taskMainPidLoop(timeUs_t currentTimeUs) if (!ARMING_FLAG(ARMED)) { armTime = 0; - // Delay saving for 0.5s to allow other functions to process save actions on disarm - if (currentTimeUs - lastDisarmTimeUs > USECS_PER_SEC / 2) { - processDelayedSave(); - } + // Delay saving for 0.5s to allow other functions to finish processing data to be stored on disarm + processDelayedSave((currentTimeUs - lastDisarmTimeUs > USECS_PER_SEC)); } if (armTime > 1 * USECS_PER_SEC) { // reset in flight emerg rearm flag 1 sec after arming once it's served its purpose +#ifdef USE_OSD + if (STATE(IN_FLIGHT_EMERG_REARM)) + osdSaveProcessAborted(); +#endif DISABLE_STATE(IN_FLIGHT_EMERG_REARM); } diff --git a/src/main/fc/fc_core.h b/src/main/fc/fc_core.h index ee5764696d8..ae9bca6de8d 100644 --- a/src/main/fc/fc_core.h +++ b/src/main/fc/fc_core.h @@ -41,7 +41,9 @@ timeUs_t getLastDisarmTimeUs(void); void tryArm(void); disarmReason_t getDisarmReason(void); +uint16_t emergencyInFlightRearmTimeMS(void); bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm); +bool emergInflightRearmEnabled(void); bool areSensorsCalibrating(void); float getFlightTime(void); diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 2d47d0ec2e9..756d15b9116 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -443,9 +443,22 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU8(dst, getConfigProfile()); if (cmdMSP == MSP_STATUS_EX) { +#if defined(USE_OSD) && defined(USE_MSP_OSD) + bool armingBit = bitArrayGet(mspBoxModeFlags.bits, BOXARM); + // If we are in emergency re-arm period and using MSP DisplayPort OSD, show that we are still Armed to prevent the VTX entering low power mode + if (feature(FEATURE_OSD) && emergInflightRearmEnabled()) + bitArraySet(mspBoxModeFlags.bits, BOXARM); +#endif sbufWriteU16(dst, averageSystemLoadPercent); sbufWriteU16(dst, armingFlags); sbufWriteU8(dst, accGetCalibrationAxisFlags()); + +#if defined(USE_OSD) && defined(USE_MSP_OSD) + if (armingBit) + bitArraySet(mspBoxModeFlags.bits, BOXARM); + else + bitArrayClr(mspBoxModeFlags.bits, BOXARM); +#endif } } break; diff --git a/src/main/fc/rc_controls.c b/src/main/fc/rc_controls.c index d03bd466a49..ca9ca77f519 100644 --- a/src/main/fc/rc_controls.c +++ b/src/main/fc/rc_controls.c @@ -218,8 +218,7 @@ void processRcStickPositions(bool isThrottleLow) tryArm(); return; } - } - else { + } else { if (armingSwitchIsActive) { rcDisarmTimeMs = currentTimeMs; tryArm(); diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 4d2fb29d459..69b3ca336df 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -163,8 +163,16 @@ #define OSD_MIN_FONT_VERSION 3 static timeMs_t linearDescentMessageMs = 0; + +typedef enum { + OSD_SAVE_MESSAGE_NONE, + OSD_SAVE_MESSAGE_WAITING, + OSD_SAVE_MESSAGE_SAVING, + OSD_SAVE_MESSAGE_SAVED +} osd_saveMessage_e; + static timeMs_t notify_settings_saved = 0; -static bool savingSettings = false; +static uint8_t savingSettings = OSD_SAVE_MESSAGE_NONE; static unsigned currentLayout = 0; static int layoutOverride = -1; @@ -226,12 +234,22 @@ static bool osdDisplayHasCanvas; PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 9); PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 1); +void osdSaveProcessAborted(void) { + notify_settings_saved = 0; + savingSettings = OSD_SAVE_MESSAGE_NONE; +} + +void osdSaveWaitingProcess(void) { + if (savingSettings == OSD_SAVE_MESSAGE_NONE) + savingSettings = OSD_SAVE_MESSAGE_WAITING; +} + void osdStartedSaveProcess(void) { - savingSettings = true; + savingSettings = OSD_SAVE_MESSAGE_SAVING; } void osdShowEEPROMSavedNotification(void) { - savingSettings = false; + savingSettings = OSD_SAVE_MESSAGE_SAVED; notify_settings_saved = millis() + 5000; } @@ -5086,22 +5104,30 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) // The following has been commented out as it will be added in #9688 // uint16_t rearmMs = (emergInflightRearmEnabled()) ? emergencyInFlightRearmTimeMS() : 0; - if (savingSettings == true) { + if (savingSettings == OSD_SAVE_MESSAGE_SAVING) { displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS))) / 2, row++, OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS)); - /*} else if (rearmMs > 0) { // Show rearming time if settings not actively being saved. Ignore the settings saved message if rearm available. - char emReArmMsg[23]; - tfp_sprintf(emReArmMsg, "** REARM PERIOD: "); - tfp_sprintf(emReArmMsg + strlen(emReArmMsg), "%02d", (uint8_t)MS2S(rearmMs)); - strcat(emReArmMsg, " **\0"); - displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(emReArmMsg));*/ + } else if (savingSettings == OSD_SAVE_MESSAGE_WAITING) { + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(OSD_MESSAGE_STR(OSD_MSG_WAITING_TO_SAVE))) / 2, row++, OSD_MESSAGE_STR(OSD_MSG_WAITING_TO_SAVE)); } else if (notify_settings_saved > 0) { if (millis() > notify_settings_saved) { notify_settings_saved = 0; - } else { + savingSettings = OSD_SAVE_MESSAGE_NONE; + } else if (savingSettings == OSD_SAVE_MESSAGE_SAVED) { displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED))) / 2, row++, OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED)); } } + if (emergInflightRearmEnabled()) { + uint16_t rearmMs = emergencyInFlightRearmTimeMS(); + if (rearmMs > 0) { + char emReArmMsg[23]; + tfp_sprintf(emReArmMsg, "** REARM PERIOD: "); + tfp_sprintf(emReArmMsg + strlen(emReArmMsg), "%02d", (uint8_t)MS2S(rearmMs)); + strcat(emReArmMsg, " **\0"); + displayWrite(osdDisplayPort, statNameX, row++, OSD_MESSAGE_STR(emReArmMsg)); + } + } + displayCommitTransaction(osdDisplayPort); } @@ -5393,9 +5419,10 @@ static void osdRefresh(timeUs_t currentTimeUs) } bool statsSinglePageCompatible = (osdDisplayPort->rows >= OSD_STATS_SINGLE_PAGE_MIN_ROWS); - static uint8_t statsCurrentPage = 0; - static bool statsDisplayed = false; - static bool statsAutoPagingEnabled = true; + static uint8_t statsCurrentPage = 0; + static timeMs_t statsRefreshTime = 0; + static bool statsDisplayed = false; + static bool statsAutoPagingEnabled = true; // Detect arm/disarm if (armState != ARMING_FLAG(ARMED)) { @@ -5463,25 +5490,24 @@ static void osdRefresh(timeUs_t currentTimeUs) // Alternate screens for multi-page stats. // Also, refreshes screen at swap interval for single-page stats. if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { - if (statsCurrentPage == 0) { - osdShowStats(statsSinglePageCompatible, statsCurrentPage); + if (statsCurrentPage == 0) statsCurrentPage = 1; - } } else { - if (statsCurrentPage == 1) { - osdShowStats(statsSinglePageCompatible, statsCurrentPage); + if (statsCurrentPage == 1) statsCurrentPage = 0; - } } } else { // Process manual page change events for multi-page stats. - if (manualPageUpRequested) { - osdShowStats(statsSinglePageCompatible, 1); + if (manualPageUpRequested) statsCurrentPage = 1; - } else if (manualPageDownRequested) { - osdShowStats(statsSinglePageCompatible, 0); + else if (manualPageDownRequested) statsCurrentPage = 0; - } + } + + // Only refresh the stats every 1/4 of a second. + if (statsRefreshTime <= millis()) { + statsRefreshTime = millis() + 250; + osdShowStats(statsSinglePageCompatible, statsCurrentPage); } } @@ -5838,26 +5864,28 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter } /* Messages that are shown regardless of Arming state */ - - // The following has been commented out as it will be added in #9688 - // uint16_t rearmMs = (emergInflightRearmEnabled()) ? emergencyInFlightRearmTimeMS() : 0; - - if (savingSettings == true) { + if (savingSettings == OSD_SAVE_MESSAGE_SAVING) { messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS); - /*} else if (rearmMs > 0) { // Show rearming time if settings not actively being saved. Ignore the settings saved message if rearm available. - char emReArmMsg[23]; - tfp_sprintf(emReArmMsg, "** REARM PERIOD: "); - tfp_sprintf(emReArmMsg + strlen(emReArmMsg), "%02d", (uint8_t)MS2S(rearmMs)); - strcat(emReArmMsg, " **\0"); - messages[messageCount++] = OSD_MESSAGE_STR(emReArmMsg);*/ + } else if (savingSettings == OSD_SAVE_MESSAGE_WAITING) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_WAITING_TO_SAVE); } else if (notify_settings_saved > 0) { if (millis() > notify_settings_saved) { notify_settings_saved = 0; - } else { + savingSettings = OSD_SAVE_MESSAGE_NONE; + } else if (savingSettings == OSD_SAVE_MESSAGE_SAVED) { messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED); } } + uint16_t rearmMs = emergencyInFlightRearmTimeMS(); + if (rearmMs > 0) { + char emReArmMsg[23]; + tfp_sprintf(emReArmMsg, "** REARM PERIOD: "); + tfp_sprintf(emReArmMsg + strlen(emReArmMsg), "%02d", (uint8_t)MS2S(rearmMs)); + strcat(emReArmMsg, " **\0"); + messages[messageCount++] = OSD_MESSAGE_STR(emReArmMsg); + } + if (messageCount > 0) { message = messages[OSD_ALTERNATING_CHOICES(systemMessageCycleTime(messageCount, messages), messageCount)]; if (message == failsafeInfoMessage) { diff --git a/src/main/io/osd.h b/src/main/io/osd.h index 5e53a436252..a28ee9709cb 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -118,6 +118,7 @@ #define OSD_MSG_UNABLE_ARM "UNABLE TO ARM" #define OSD_MSG_SAVING_SETTNGS "** SAVING SETTINGS **" #define OSD_MSG_SETTINGS_SAVED "** SETTINGS SAVED **" +#define OSD_MSG_WAITING_TO_SAVE "** WAITING TO SAVE **" #define OSD_MSG_ANGLEHOLD_ROLL "(ANGLEHOLD ROLL)" #define OSD_MSG_ANGLEHOLD_PITCH "(ANGLEHOLD PITCH)" #define OSD_MSG_ANGLEHOLD_LEVEL "(ANGLEHOLD LEVEL)" @@ -492,6 +493,8 @@ int32_t osdGetAltitude(void); bool osdUsingScaledThrottle(void); +void osdSaveProcessAborted(void); +void osdSaveWaitingProcess(void); void osdStartedSaveProcess(void); void osdShowEEPROMSavedNotification(void); diff --git a/src/main/navigation/navigation.c b/src/main/navigation/navigation.c index e7261b068cf..dbd1920bd46 100644 --- a/src/main/navigation/navigation.c +++ b/src/main/navigation/navigation.c @@ -3132,8 +3132,7 @@ void updateHomePosition(void) break; } } - } - else { + } else { static bool isHomeResetAllowed = false; // If pilot so desires he may reset home position to current position if (IS_RC_MODE_ACTIVE(BOXHOMERESET)) { @@ -3143,8 +3142,7 @@ void updateHomePosition(void) setHome = true; isHomeResetAllowed = false; } - } - else { + } else { isHomeResetAllowed = true; }