From 36e17a665267d1a0005d5e8fae675e48d326a5c9 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Mon, 26 Dec 2022 04:03:57 -0600 Subject: [PATCH 01/10] Modified OSD stats functions to accomodate single page stats for HD displays. --- src/main/io/osd.c | 371 ++++++++++++++++++++++++---------------------- 1 file changed, 191 insertions(+), 180 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 3ae37686146..0be71acdac6 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -3855,7 +3855,7 @@ static void osdUpdateStats(void) stats.max_altitude = MAX(stats.max_altitude, osdGetAltitude()); } -static void osdShowStatsPage1(void) +static void osdShowStats(bool isHD, int page) { const char * disarmReasonStr[DISARM_REASON_COUNT] = { "UNKNOWN", "TIMEOUT", "STICKS", "SWITCH", "SWITCH", "KILLSW", "FAILSAFE", "NAV SYS", "LANDING"}; uint8_t top = 1; /* first fully visible line */ @@ -3864,211 +3864,222 @@ static void osdShowStatsPage1(void) char buff[10]; statsPagesCheck = 1; + if (page < 1 || page > 2) + { + page = 1; + } + displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); displayClearScreen(osdDisplayPort); - displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2 ->"); - - if (feature(FEATURE_GPS)) { - displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); - osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); - osdLeftAlignString(buff); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - displayWrite(osdDisplayPort, statNameX, top, "AVG SPEED :"); - osdGenerateAverageVelocityStr(buff); - osdLeftAlignString(buff); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - displayWrite(osdDisplayPort, statNameX, top, "MAX DISTANCE :"); - osdFormatDistanceStr(buff, stats.max_distance*100); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - displayWrite(osdDisplayPort, statNameX, top, "TRAVELED DISTANCE:"); - osdFormatDistanceStr(buff, getTotalTravelDistance()); - displayWrite(osdDisplayPort, statValuesX, top++, buff); + if (isHD) + { + displayWrite(osdDisplayPort, statNameX, top++, "--- STATS ---"); + } + else if (page == 1) + { + displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2 ->"); + } + else if (page == 2) + { + displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); } - displayWrite(osdDisplayPort, statNameX, top, "MAX ALTITUDE :"); - osdFormatAltitudeStr(buff, stats.max_altitude); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - switch (rxConfig()->serialrx_provider) { - case SERIALRX_CRSF: - displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI % :"); - itoa(stats.min_rssi, buff, 10); - strcat(buff, "%"); + if (isHD || page == 1) + { + if (feature(FEATURE_GPS)) { + displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); + osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); + osdLeftAlignString(buff); displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI DBM :"); - itoa(stats.min_rssi_dbm, buff, 10); - tfp_sprintf(buff, "%s%c", buff, SYM_DBM); + displayWrite(osdDisplayPort, statNameX, top, "AVG SPEED :"); + osdGenerateAverageVelocityStr(buff); + osdLeftAlignString(buff); displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "MIN LQ :"); - itoa(stats.min_lq, buff, 10); - strcat(buff, "%"); + displayWrite(osdDisplayPort, statNameX, top, "MAX DISTANCE :"); + osdFormatDistanceStr(buff, stats.max_distance*100); displayWrite(osdDisplayPort, statValuesX, top++, buff); - break; - default: - displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI :"); - itoa(stats.min_rssi, buff, 10); - strcat(buff, "%"); + + displayWrite(osdDisplayPort, statNameX, top, "TRAVELED DISTANCE:"); + osdFormatDistanceStr(buff, getTotalTravelDistance()); displayWrite(osdDisplayPort, statValuesX, top++, buff); } - displayWrite(osdDisplayPort, statNameX, top, "FLY TIME :"); - uint16_t flySeconds = getFlightTime(); - uint16_t flyMinutes = flySeconds / 60; - flySeconds %= 60; - uint16_t flyHours = flyMinutes / 60; - flyMinutes %= 60; - tfp_sprintf(buff, "%02u:%02u:%02u", flyHours, flyMinutes, flySeconds); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - displayWrite(osdDisplayPort, statNameX, top, "DISARMED BY :"); - displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); - displayCommitTransaction(osdDisplayPort); -} - -static void osdShowStatsPage2(void) -{ - uint8_t top = 1; /* first fully visible line */ - const uint8_t statNameX = osdDisplayIsHD() ? 11 : 1; - const uint8_t statValuesX = osdDisplayIsHD() ? 30 : 20; - char buff[10]; - statsPagesCheck = 1; - - displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); - displayClearScreen(osdDisplayPort); - - displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); - - if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { - displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); - osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); - } else { - displayWrite(osdDisplayPort, statNameX, top, "MIN CELL VOLTAGE :"); - osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3); - } - tfp_sprintf(buff, "%s%c", buff, SYM_VOLT); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - if (feature(FEATURE_CURRENT_METER)) { - displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :"); - osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3); - tfp_sprintf(buff, "%s%c", buff, SYM_AMP); + displayWrite(osdDisplayPort, statNameX, top, "MAX ALTITUDE :"); + osdFormatAltitudeStr(buff, stats.max_altitude); displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :"); - bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3); - buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; - buff[4] = '\0'; + switch (rxConfig()->serialrx_provider) { + case SERIALRX_CRSF: + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI % :"); + itoa(stats.min_rssi, buff, 10); + strcat(buff, "%"); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI DBM :"); + itoa(stats.min_rssi_dbm, buff, 10); + tfp_sprintf(buff, "%s%c", buff, SYM_DBM); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + displayWrite(osdDisplayPort, statNameX, top, "MIN LQ :"); + itoa(stats.min_lq, buff, 10); + strcat(buff, "%"); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + break; + default: + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI :"); + itoa(stats.min_rssi, buff, 10); + strcat(buff, "%"); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + } + + displayWrite(osdDisplayPort, statNameX, top, "FLY TIME :"); + uint16_t flySeconds = getFlightTime(); + uint16_t flyMinutes = flySeconds / 60; + flySeconds %= 60; + uint16_t flyHours = flyMinutes / 60; + flyMinutes %= 60; + tfp_sprintf(buff, "%02u:%02u:%02u", flyHours, flyMinutes, flySeconds); displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "USED CAPACITY :"); - if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - tfp_sprintf(buff, "%d%c", (int)getMAhDrawn(), SYM_MAH); + displayWrite(osdDisplayPort, statNameX, top, "DISARMED BY :"); + displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); + } + + if (isHD || page == 2) + { + if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { + displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); + osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); } else { - osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); - tfp_sprintf(buff, "%s%c", buff, SYM_WH); + displayWrite(osdDisplayPort, statNameX, top, "MIN CELL VOLTAGE :"); + osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3); } + tfp_sprintf(buff, "%s%c", buff, SYM_VOLT); displayWrite(osdDisplayPort, statValuesX, top++, buff); - int32_t totalDistance = getTotalTravelDistance(); - bool moreThanAh = false; - bool efficiencyValid = totalDistance >= 10000; - if (feature(FEATURE_GPS)) { - displayWrite(osdDisplayPort, statNameX, top, "AVG EFFICIENCY :"); - switch (osdConfig()->units) { - case OSD_UNIT_UK: - FALLTHROUGH; - case OSD_UNIT_IMPERIAL: - if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, 3); - if (!moreThanAh) { - tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); + if (feature(FEATURE_CURRENT_METER)) { + displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :"); + osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3); + tfp_sprintf(buff, "%s%c", buff, SYM_AMP); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :"); + bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3); + buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; + buff[4] = '\0'; + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + displayWrite(osdDisplayPort, statNameX, top, "USED CAPACITY :"); + if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { + tfp_sprintf(buff, "%d%c", (int)getMAhDrawn(), SYM_MAH); + } else { + osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); + tfp_sprintf(buff, "%s%c", buff, SYM_WH); + } + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + int32_t totalDistance = getTotalTravelDistance(); + bool moreThanAh = false; + bool efficiencyValid = totalDistance >= 10000; + if (feature(FEATURE_GPS)) { + displayWrite(osdDisplayPort, statNameX, top, "AVG EFFICIENCY :"); + switch (osdConfig()->units) { + case OSD_UNIT_UK: + FALLTHROUGH; + case OSD_UNIT_IMPERIAL: + if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, 3); + if (!moreThanAh) { + tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); + } else { + tfp_sprintf(buff, "%s%c", buff, SYM_AH_MI); + } + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + buff[3] = SYM_MAH_MI_0; + buff[4] = SYM_MAH_MI_1; + buff[5] = '\0'; + } } else { - tfp_sprintf(buff, "%s%c", buff, SYM_AH_MI); - } - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - buff[3] = SYM_MAH_MI_0; - buff[4] = SYM_MAH_MI_1; - buff[5] = '\0'; + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, 3); + tfp_sprintf(buff, "%s%c", buff, SYM_WH_MI); + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + } } - } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, 3); - tfp_sprintf(buff, "%s%c", buff, SYM_WH_MI); - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - } - } - break; - case OSD_UNIT_GA: - if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, 3); - if (!moreThanAh) { - tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); + break; + case OSD_UNIT_GA: + if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, 3); + if (!moreThanAh) { + tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); + } else { + tfp_sprintf(buff, "%s%c", buff, SYM_AH_NM); + } + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + buff[3] = SYM_MAH_NM_0; + buff[4] = SYM_MAH_NM_1; + buff[5] = '\0'; + } } else { - tfp_sprintf(buff, "%s%c", buff, SYM_AH_NM); + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, 3); + tfp_sprintf(buff, "%s%c", buff, SYM_WH_NM); + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + } } - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - buff[3] = SYM_MAH_NM_0; - buff[4] = SYM_MAH_NM_1; - buff[5] = '\0'; - } - } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, 3); - tfp_sprintf(buff, "%s%c", buff, SYM_WH_NM); - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - } - } - break; - case OSD_UNIT_METRIC_MPH: - FALLTHROUGH; - case OSD_UNIT_METRIC: - if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, 3); - if (!moreThanAh) { - tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); + break; + case OSD_UNIT_METRIC_MPH: + FALLTHROUGH; + case OSD_UNIT_METRIC: + if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, 3); + if (!moreThanAh) { + tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); + } else { + tfp_sprintf(buff, "%s%c", buff, SYM_AH_KM); + } + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + buff[3] = SYM_MAH_KM_0; + buff[4] = SYM_MAH_KM_1; + buff[5] = '\0'; + } } else { - tfp_sprintf(buff, "%s%c", buff, SYM_AH_KM); - } - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - buff[3] = SYM_MAH_KM_0; - buff[4] = SYM_MAH_KM_1; - buff[5] = '\0'; + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, 3); + tfp_sprintf(buff, "%s%c", buff, SYM_WH_KM); + if (!efficiencyValid) { + buff[0] = buff[1] = buff[2] = '-'; + } } - } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, 3); - tfp_sprintf(buff, "%s%c", buff, SYM_WH_KM); - if (!efficiencyValid) { - buff[0] = buff[1] = buff[2] = '-'; - } - } - break; + break; + } + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX, top++, buff); } - osdLeftAlignString(buff); - displayWrite(osdDisplayPort, statValuesX, top++, buff); } + + const float max_gforce = accGetMeasuredMaxG(); + displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :"); + osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + + const acc_extremes_t *acc_extremes = accGetMeasuredExtremes(); + const float acc_extremes_min = acc_extremes[Z].min; + const float acc_extremes_max = acc_extremes[Z].max; + + displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); + osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4); + strcat(buff,"/"); + displayWrite(osdDisplayPort, statValuesX - 1, top, buff); + osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3); + displayWrite(osdDisplayPort, statValuesX + 4, top++, buff); } - const float max_gforce = accGetMeasuredMaxG(); - displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :"); - osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3); - displayWrite(osdDisplayPort, statValuesX, top++, buff); - - const acc_extremes_t *acc_extremes = accGetMeasuredExtremes(); - displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); - osdFormatCentiNumber(buff, acc_extremes[Z].min * 100, 0, 2, 0, 4); - strcat(buff,"/"); - displayWrite(osdDisplayPort, statValuesX - 1, top, buff); - osdFormatCentiNumber(buff, acc_extremes[Z].max * 100, 0, 2, 0, 3); - displayWrite(osdDisplayPort, statValuesX + 4, top++, buff); displayCommitTransaction(osdDisplayPort); } @@ -4205,7 +4216,7 @@ static void osdRefresh(timeUs_t currentTimeUs) #endif osdSetNextRefreshIn(delay); } else { - osdShowStatsPage1(); // show first page of statistics + osdShowStats(osdDisplayIsHD(), 1); // show first page of statistics osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME); statsPageAutoSwapCntl = osdConfig()->stats_page_auto_swap_time > 0 ? 0 : 2; // disable swapping pages when time = 0 } @@ -4227,12 +4238,12 @@ static void osdRefresh(timeUs_t currentTimeUs) } else { if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { if (statsPageAutoSwapCntl == 0) { - osdShowStatsPage1(); + osdShowStats(osdDisplayIsHD(), 1); statsPageAutoSwapCntl = 1; } } else { if (statsPageAutoSwapCntl == 1) { - osdShowStatsPage2(); + osdShowStats(osdDisplayIsHD(), 2); statsPageAutoSwapCntl = 0; } } @@ -4247,11 +4258,11 @@ static void osdRefresh(timeUs_t currentTimeUs) resumeRefreshAt = 0; } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE1)) { if (statsPagesCheck == 1) { - osdShowStatsPage1(); + osdShowStats(osdDisplayIsHD(), 1); } } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE2)) { if (statsPagesCheck == 1) { - osdShowStatsPage2(); + osdShowStats(osdDisplayIsHD(), 2); } } else { displayHeartbeat(osdDisplayPort); From 7d557438c9d07ae56434e58a78d9a84c0b20bde3 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Mon, 26 Dec 2022 04:44:40 -0600 Subject: [PATCH 02/10] Cleaned up curly brace styling to match coding standards --- src/main/io/osd.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 0be71acdac6..72e0a61ed1b 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -3865,28 +3865,22 @@ static void osdShowStats(bool isHD, int page) statsPagesCheck = 1; if (page < 1 || page > 2) - { - page = 1; - } + page = 1; displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); displayClearScreen(osdDisplayPort); - if (isHD) - { + if (isHD) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS ---"); } - else if (page == 1) - { + else if (page == 1) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2 ->"); } - else if (page == 2) - { + else if (page == 2) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); } - if (isHD || page == 1) - { + if (isHD || page == 1) { if (feature(FEATURE_GPS)) { displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); @@ -3948,8 +3942,7 @@ static void osdShowStats(bool isHD, int page) displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); } - if (isHD || page == 2) - { + if (isHD || page == 2) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); From 67b501e1cb73c9b6a6d2e7b68414bc6143665055 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Tue, 27 Dec 2022 11:35:57 -0600 Subject: [PATCH 03/10] Modified osdShowStats() to call the parameter "isSinglePageCompatible" and added a function osdDisplayIsSinglePageCompatible() to check if the screen size is at least the size for DJIWTF. --- src/main/io/osd.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 72e0a61ed1b..ab485820cb0 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -221,8 +221,15 @@ bool osdDisplayIsPAL(void) bool osdDisplayIsHD(void) { - if (displayScreenSize(osdDisplayPort) >= VIDEO_BUFFER_CHARS_HDZERO) - { + if (displayScreenSize(osdDisplayPort) >= VIDEO_BUFFER_CHARS_HDZERO) { + return true; + } + return false; +} + +bool osdDisplayIsSinglePageCompatible(void) +{ + if (displayScreenSize(osdDisplayPort) >= VIDEO_BUFFER_CHARS_DJIWTF) { return true; } return false; @@ -3855,7 +3862,7 @@ static void osdUpdateStats(void) stats.max_altitude = MAX(stats.max_altitude, osdGetAltitude()); } -static void osdShowStats(bool isHD, int page) +static void osdShowStats(bool isSinglePageCompatible, int page) { const char * disarmReasonStr[DISARM_REASON_COUNT] = { "UNKNOWN", "TIMEOUT", "STICKS", "SWITCH", "SWITCH", "KILLSW", "FAILSAFE", "NAV SYS", "LANDING"}; uint8_t top = 1; /* first fully visible line */ @@ -3870,7 +3877,7 @@ static void osdShowStats(bool isHD, int page) displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); displayClearScreen(osdDisplayPort); - if (isHD) { + if (isSinglePageCompatible) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS ---"); } else if (page == 1) { @@ -3880,7 +3887,7 @@ static void osdShowStats(bool isHD, int page) displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); } - if (isHD || page == 1) { + if (isSinglePageCompatible || page == 1) { if (feature(FEATURE_GPS)) { displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); @@ -3942,7 +3949,7 @@ static void osdShowStats(bool isHD, int page) displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); } - if (isHD || page == 2) { + if (isSinglePageCompatible || page == 2) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); @@ -4064,7 +4071,6 @@ static void osdShowStats(bool isHD, int page) const acc_extremes_t *acc_extremes = accGetMeasuredExtremes(); const float acc_extremes_min = acc_extremes[Z].min; const float acc_extremes_max = acc_extremes[Z].max; - displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4); strcat(buff,"/"); @@ -4209,7 +4215,7 @@ static void osdRefresh(timeUs_t currentTimeUs) #endif osdSetNextRefreshIn(delay); } else { - osdShowStats(osdDisplayIsHD(), 1); // show first page of statistics + osdShowStats(osdDisplayIsSinglePageCompatible(), 1); // show first page of statistics osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME); statsPageAutoSwapCntl = osdConfig()->stats_page_auto_swap_time > 0 ? 0 : 2; // disable swapping pages when time = 0 } @@ -4231,12 +4237,12 @@ static void osdRefresh(timeUs_t currentTimeUs) } else { if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { if (statsPageAutoSwapCntl == 0) { - osdShowStats(osdDisplayIsHD(), 1); + osdShowStats(osdDisplayIsSinglePageCompatible(), 1); statsPageAutoSwapCntl = 1; } } else { if (statsPageAutoSwapCntl == 1) { - osdShowStats(osdDisplayIsHD(), 2); + osdShowStats(osdDisplayIsSinglePageCompatible(), 2); statsPageAutoSwapCntl = 0; } } @@ -4251,11 +4257,11 @@ static void osdRefresh(timeUs_t currentTimeUs) resumeRefreshAt = 0; } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE1)) { if (statsPagesCheck == 1) { - osdShowStats(osdDisplayIsHD(), 1); + osdShowStats(osdDisplayIsSinglePageCompatible(), 1); } } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE2)) { if (statsPagesCheck == 1) { - osdShowStats(osdDisplayIsHD(), 2); + osdShowStats(osdDisplayIsSinglePageCompatible(), 2); } } else { displayHeartbeat(osdDisplayPort); From 7d70bbc9a7eb380d8ebb6e044d8a8873d6d52a75 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Wed, 28 Dec 2022 01:46:08 -0600 Subject: [PATCH 04/10] Additional updates to support HDZERO. Updated the function which decides whether to support single page stats, osdVideoSystemIsSinglePageStatsCompatible(), to be based on the enumerated value for the selected video system. Combined MAX SPEED and AVG SPEED on to one line. Combined MIN RSSI % and MIN RSSI DBM on to one line. So we're down to 16 lines, 17 including the blank line at the top. --- src/main/io/osd.c | 136 +++++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 39 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index ab485820cb0..f0e03254a2d 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -227,12 +227,21 @@ bool osdDisplayIsHD(void) return false; } -bool osdDisplayIsSinglePageCompatible(void) -{ - if (displayScreenSize(osdDisplayPort) >= VIDEO_BUFFER_CHARS_DJIWTF) { - return true; +bool osdVideoSystemIsSinglePageStatsCompatible(void) +{ + bool result = false; + + switch ((videoSystem_e)osdConfig()->video_system) { + case VIDEO_SYSTEM_HDZERO: + FALLTHROUGH; + case VIDEO_SYSTEM_DJIWTF: + result = true; + break; + default: + result = false; } - return false; + + return result; } /** @@ -636,6 +645,27 @@ static inline void osdFormatFlyTime(char *buff, textAttributes_t *attr) } } +char *osdFormatTrimWhiteSpace(char *buff) +{ + char *end; + + // Trim leading spaces + while(isspace((unsigned char)*buff)) buff++; + + // All spaces? + if(*buff == 0) + return buff; + + // Trim trailing spaces + end = buff + strlen(buff) - 1; + while(end > buff && isspace((unsigned char)*end)) end--; + + // Write new null terminator character + end[1] = '\0'; + + return buff; +} + /** * Converts RSSI into a % value used by the OSD. */ @@ -3862,10 +3892,12 @@ static void osdUpdateStats(void) stats.max_altitude = MAX(stats.max_altitude, osdGetAltitude()); } -static void osdShowStats(bool isSinglePageCompatible, int page) +static void osdShowStats(bool isSinglePageStatsCompatible, int page) { const char * disarmReasonStr[DISARM_REASON_COUNT] = { "UNKNOWN", "TIMEOUT", "STICKS", "SWITCH", "SWITCH", "KILLSW", "FAILSAFE", "NAV SYS", "LANDING"}; - uint8_t top = 1; /* first fully visible line */ + uint8_t top = 1; /* first fully visible line */ + size_t multiValueLengthOffset = 0; + const uint8_t statNameX = osdDisplayIsHD() ? 11 : 1; const uint8_t statValuesX = osdDisplayIsHD() ? 30 : 20; char buff[10]; @@ -3877,27 +3909,37 @@ static void osdShowStats(bool isSinglePageCompatible, int page) displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); displayClearScreen(osdDisplayPort); - if (isSinglePageCompatible) { + if (isSinglePageStatsCompatible) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS ---"); - } - else if (page == 1) { + } else if (page == 1) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2 ->"); - } - else if (page == 2) { + } else if (page == 2) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); } - if (isSinglePageCompatible || page == 1) { - if (feature(FEATURE_GPS)) { - displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); - osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); - osdLeftAlignString(buff); - displayWrite(osdDisplayPort, statValuesX, top++, buff); + if (isSinglePageStatsCompatible || page == 1) { + if (feature(FEATURE_GPS)) { + if (isSinglePageStatsCompatible) { + displayWrite(osdDisplayPort, statNameX, top, "MAX/AVG SPEED :"); + osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); + osdLeftAlignString(buff); + strcat(osdFormatTrimWhiteSpace(buff),"/"); + multiValueLengthOffset = strlen(buff); + displayWrite(osdDisplayPort, statValuesX, top, buff); + osdGenerateAverageVelocityStr(buff); + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); + } else { + displayWrite(osdDisplayPort, statNameX, top, "MAX SPEED :"); + osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "AVG SPEED :"); - osdGenerateAverageVelocityStr(buff); - osdLeftAlignString(buff); - displayWrite(osdDisplayPort, statValuesX, top++, buff); + displayWrite(osdDisplayPort, statNameX, top, "AVG SPEED :"); + osdGenerateAverageVelocityStr(buff); + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + } displayWrite(osdDisplayPort, statNameX, top, "MAX DISTANCE :"); osdFormatDistanceStr(buff, stats.max_distance*100); @@ -3914,15 +3956,28 @@ static void osdShowStats(bool isSinglePageCompatible, int page) switch (rxConfig()->serialrx_provider) { case SERIALRX_CRSF: - displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI % :"); - itoa(stats.min_rssi, buff, 10); - strcat(buff, "%"); - displayWrite(osdDisplayPort, statValuesX, top++, buff); + if (isSinglePageStatsCompatible) { + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI %/DBM :"); + itoa(stats.min_rssi, buff, 10); + osdLeftAlignString(buff); + strcat(osdFormatTrimWhiteSpace(buff), "%/"); + multiValueLengthOffset = strlen(buff); + displayWrite(osdDisplayPort, statValuesX, top, buff); + itoa(stats.min_rssi_dbm, buff, 10); + tfp_sprintf(buff, "%s%c", buff, SYM_DBM); + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); + } else { + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI % :"); + itoa(stats.min_rssi, buff, 10); + strcat(buff, "%"); + displayWrite(osdDisplayPort, statValuesX, top++, buff); - displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI DBM :"); - itoa(stats.min_rssi_dbm, buff, 10); - tfp_sprintf(buff, "%s%c", buff, SYM_DBM); - displayWrite(osdDisplayPort, statValuesX, top++, buff); + displayWrite(osdDisplayPort, statNameX, top, "MIN RSSI DBM :"); + itoa(stats.min_rssi_dbm, buff, 10); + tfp_sprintf(buff, "%s%c", buff, SYM_DBM); + displayWrite(osdDisplayPort, statValuesX, top++, buff); + } displayWrite(osdDisplayPort, statNameX, top, "MIN LQ :"); itoa(stats.min_lq, buff, 10); @@ -3949,7 +4004,7 @@ static void osdShowStats(bool isSinglePageCompatible, int page) displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); } - if (isSinglePageCompatible || page == 2) { + if (isSinglePageStatsCompatible || page == 2) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); @@ -4073,10 +4128,13 @@ static void osdShowStats(bool isSinglePageCompatible, int page) const float acc_extremes_max = acc_extremes[Z].max; displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4); - strcat(buff,"/"); - displayWrite(osdDisplayPort, statValuesX - 1, top, buff); + osdLeftAlignString(buff); + strcat(osdFormatTrimWhiteSpace(buff),"/"); + multiValueLengthOffset = strlen(buff); + displayWrite(osdDisplayPort, statValuesX, top, buff); osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3); - displayWrite(osdDisplayPort, statValuesX + 4, top++, buff); + osdLeftAlignString(buff); + displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); } displayCommitTransaction(osdDisplayPort); @@ -4215,7 +4273,7 @@ static void osdRefresh(timeUs_t currentTimeUs) #endif osdSetNextRefreshIn(delay); } else { - osdShowStats(osdDisplayIsSinglePageCompatible(), 1); // show first page of statistics + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); // show first page of statistics osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME); statsPageAutoSwapCntl = osdConfig()->stats_page_auto_swap_time > 0 ? 0 : 2; // disable swapping pages when time = 0 } @@ -4237,12 +4295,12 @@ static void osdRefresh(timeUs_t currentTimeUs) } else { if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { if (statsPageAutoSwapCntl == 0) { - osdShowStats(osdDisplayIsSinglePageCompatible(), 1); + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); statsPageAutoSwapCntl = 1; } } else { if (statsPageAutoSwapCntl == 1) { - osdShowStats(osdDisplayIsSinglePageCompatible(), 2); + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); statsPageAutoSwapCntl = 0; } } @@ -4257,11 +4315,11 @@ static void osdRefresh(timeUs_t currentTimeUs) resumeRefreshAt = 0; } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE1)) { if (statsPagesCheck == 1) { - osdShowStats(osdDisplayIsSinglePageCompatible(), 1); + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); } } else if ((currentTimeUs > resumeRefreshAt) || ((!refreshWaitForResumeCmdRelease) && STATS_PAGE2)) { if (statsPagesCheck == 1) { - osdShowStats(osdDisplayIsSinglePageCompatible(), 2); + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); } } else { displayHeartbeat(osdDisplayPort); From 45d5baf7acfe42f9070105901567dc8198c5c9c3 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Wed, 28 Dec 2022 02:04:58 -0600 Subject: [PATCH 05/10] Modified 'MAX/AVG SPEED' to read 'SPEED MAX/AVG' to be more consistent with the other two multi-valued lines. --- src/main/io/osd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index f0e03254a2d..1c38371f047 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -3920,7 +3920,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, int page) if (isSinglePageStatsCompatible || page == 1) { if (feature(FEATURE_GPS)) { if (isSinglePageStatsCompatible) { - displayWrite(osdDisplayPort, statNameX, top, "MAX/AVG SPEED :"); + displayWrite(osdDisplayPort, statNameX, top, "SPEED MAX/AVG :"); osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); osdLeftAlignString(buff); strcat(osdFormatTrimWhiteSpace(buff),"/"); From 0ee6a396e9542097e15a69d01a46d967b8ffa401 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Wed, 28 Dec 2022 02:10:19 -0600 Subject: [PATCH 06/10] Changed back to 'MAX/AVG SPEED', I don't know what I was seeing before. This is more consistent. --- src/main/io/osd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 1c38371f047..f0e03254a2d 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -3920,7 +3920,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, int page) if (isSinglePageStatsCompatible || page == 1) { if (feature(FEATURE_GPS)) { if (isSinglePageStatsCompatible) { - displayWrite(osdDisplayPort, statNameX, top, "SPEED MAX/AVG :"); + displayWrite(osdDisplayPort, statNameX, top, "MAX/AVG SPEED :"); osdFormatVelocityStr(buff, stats.max_3D_speed, true, false); osdLeftAlignString(buff); strcat(osdFormatTrimWhiteSpace(buff),"/"); From 16ff747514c1480e20926c345f122c8da23e67f6 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Wed, 28 Dec 2022 13:25:07 -0600 Subject: [PATCH 07/10] Added temporary placeholder comment for the change necessary to support Avatar once it is added to the videoSystem_e enumeration. --- src/main/io/osd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index f0e03254a2d..5d0e788e572 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -234,6 +234,9 @@ bool osdVideoSystemIsSinglePageStatsCompatible(void) switch ((videoSystem_e)osdConfig()->video_system) { case VIDEO_SYSTEM_HDZERO: FALLTHROUGH; + // Placeholder for Avatar system support once Darren completes that. + // case VIDEO_SYSTEM_AVATAR: + // FALLTHROUGH; case VIDEO_SYSTEM_DJIWTF: result = true; break; From 35ea2a7d2fd95b574771daa50748b602a9fd3be3 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Fri, 30 Dec 2022 02:20:52 -0600 Subject: [PATCH 08/10] Reintroduced logic to refresh single-page stats on multi-page change events so that the "Saving Settings" and "Settings Saved" messages have a chance to be displayed since it wouldn't redraw them normally. --- src/main/io/osd.c | 92 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index b6e5be53c70..4aa2149c4d3 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -244,7 +244,7 @@ bool osdDisplayIsHD(void) } bool osdVideoSystemIsSinglePageStatsCompatible(void) -{ +{ bool result = false; switch ((videoSystem_e)osdConfig()->video_system) { @@ -4374,14 +4374,14 @@ static void osdRefresh(timeUs_t currentTimeUs) } if (resumeRefreshAt) { - + + /* This is a workaround to introduce a delay for the paging stick commands so that + * holding the roll stick doesn't cause a race condition with the osdShowStats() method + */ bool pageUp = false; - bool pageDown = false; + bool pageDown = false; if (!osdVideoSystemIsSinglePageStatsCompatible()) { - /* This is a workaround to introduce a delay for the paging stick commands so that - * holding the roll stick doesn't cause a race condition with the osdShowStats() method - */ if (osdIsPageUpKeyHeld()) { pageUp = true; statsPageAutoSwapCntl = 2; @@ -4389,31 +4389,73 @@ static void osdRefresh(timeUs_t currentTimeUs) pageDown = true; statsPageAutoSwapCntl = 2; } - if (statsPageAutoSwapCntl == 2) { - if (pageDown) { - if (statsPagesCheck == 1) { - osdShowStats(false, 1); - } - } else if (pageUp) { - if (statsPagesCheck == 1) { - osdShowStats(false, 2); - } + } + + if (statsPageAutoSwapCntl == 2) { + if (pageDown) { + if (statsPagesCheck == 1) { + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); + } + } else if (pageUp) { + if (statsPagesCheck == 1) { + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); + } + } + } else { + if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { + if (statsPageAutoSwapCntl == 0) { + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); + statsPageAutoSwapCntl = 1; } } else { - if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { - if (statsPageAutoSwapCntl == 0) { - osdShowStats(false, 1); - statsPageAutoSwapCntl = 1; - } - } else { - if (statsPageAutoSwapCntl == 1) { - osdShowStats(false, 2); - statsPageAutoSwapCntl = 0; - } + if (statsPageAutoSwapCntl == 1) { + osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); + statsPageAutoSwapCntl = 0; } } } + // bool pageUp = false; + // bool pageDown = false; + // if (!osdVideoSystemIsSinglePageStatsCompatible()) + // { + // /* This is a workaround to introduce a delay for the paging stick commands so that + // * holding the roll stick doesn't cause a race condition with the osdShowStats() method + // */ + // if (osdIsPageUpKeyHeld()) { + // pageUp = true; + // statsPageAutoSwapCntl = 2; + // } else if (osdIsPageDownKeyHeld()) { + // pageDown = true; + // statsPageAutoSwapCntl = 2; + // } + + + // if (statsPageAutoSwapCntl == 2) { + // if (pageDown) { + // if (statsPagesCheck == 1) { + // osdShowStats(false, 1); + // } + // } else if (pageUp) { + // if (statsPagesCheck == 1) { + // osdShowStats(false, 2); + // } + // } + // } else { + // if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { + // if (statsPageAutoSwapCntl == 0) { + // osdShowStats(false, 1); + // statsPageAutoSwapCntl = 1; + // } + // } else { + // if (statsPageAutoSwapCntl == 1) { + // osdShowStats(false, 2); + // statsPageAutoSwapCntl = 0; + // } + // } + // } + // } + if ((currentTimeUs > resumeRefreshAt) || CANCEL_STATS_COMMAND) { displayClearScreen(osdDisplayPort); resumeRefreshAt = 0; From 3fe64dd8b2d7c39da6968cb9a6de16726dca0764 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:04:47 -0600 Subject: [PATCH 09/10] Cleaned up an unnecessary comment block I inadevertently left in there. --- src/main/io/osd.c | 47 ++--------------------------------------------- 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 4aa2149c4d3..79ee643013d 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -4023,8 +4023,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, int page) displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); /* We only want to show this message once, so it will be shown after the second - * section for single page stats. - */ + * section for single page stats. */ if (!isSinglePageStatsCompatible) { if (savingSettings == true) { displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS)); @@ -4376,8 +4375,7 @@ static void osdRefresh(timeUs_t currentTimeUs) if (resumeRefreshAt) { /* This is a workaround to introduce a delay for the paging stick commands so that - * holding the roll stick doesn't cause a race condition with the osdShowStats() method - */ + * holding the roll stick doesn't cause a race condition with the osdShowStats() method. */ bool pageUp = false; bool pageDown = false; if (!osdVideoSystemIsSinglePageStatsCompatible()) @@ -4415,47 +4413,6 @@ static void osdRefresh(timeUs_t currentTimeUs) } } - // bool pageUp = false; - // bool pageDown = false; - // if (!osdVideoSystemIsSinglePageStatsCompatible()) - // { - // /* This is a workaround to introduce a delay for the paging stick commands so that - // * holding the roll stick doesn't cause a race condition with the osdShowStats() method - // */ - // if (osdIsPageUpKeyHeld()) { - // pageUp = true; - // statsPageAutoSwapCntl = 2; - // } else if (osdIsPageDownKeyHeld()) { - // pageDown = true; - // statsPageAutoSwapCntl = 2; - // } - - - // if (statsPageAutoSwapCntl == 2) { - // if (pageDown) { - // if (statsPagesCheck == 1) { - // osdShowStats(false, 1); - // } - // } else if (pageUp) { - // if (statsPagesCheck == 1) { - // osdShowStats(false, 2); - // } - // } - // } else { - // if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { - // if (statsPageAutoSwapCntl == 0) { - // osdShowStats(false, 1); - // statsPageAutoSwapCntl = 1; - // } - // } else { - // if (statsPageAutoSwapCntl == 1) { - // osdShowStats(false, 2); - // statsPageAutoSwapCntl = 0; - // } - // } - // } - // } - if ((currentTimeUs > resumeRefreshAt) || CANCEL_STATS_COMMAND) { displayClearScreen(osdDisplayPort); resumeRefreshAt = 0; From f457c551c6e20cd8020fc406433b08efd629b812 Mon Sep 17 00:00:00 2001 From: M0j0Risin <100724300+M0j0Risin@users.noreply.github.com> Date: Sat, 31 Dec 2022 22:54:51 -0600 Subject: [PATCH 10/10] Detection of compatablility for single-page stats is now based strictly on the number of rows currently displayed. OSD_STATS_SINGLE_PAGE_MIN_ROWS stores the minimum number of rows for single-page stats. I also made some additional improvements surrounding the logic for manually paging using the stick commands for multi-page stats. I think this makes the code a lot easier to follow. --- src/main/io/osd.c | 225 +++++++++++++++++++++++----------------------- 1 file changed, 112 insertions(+), 113 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 79ee643013d..b8c965ab54b 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -120,7 +120,8 @@ FILE_COMPILE_FOR_SPEED #define GFORCE_FILTER_TC 0.2 -#define CANCEL_STATS_COMMAND (rxGetChannelValue(THROTTLE) > 1750 || rxGetChannelValue(PITCH) > 1750) +#define OSD_STATS_SINGLE_PAGE_MIN_ROWS 18 +#define OSD_RESUME_UPDATES_STICK_COMMAND (rxGetChannelValue(THROTTLE) > 1750 || rxGetChannelValue(PITCH) > 1750) #define IS_HI(X) (rxGetChannelValue(X) > 1750) #define IS_LO(X) (rxGetChannelValue(X) < 1250) #define IS_MID(X) (rxGetChannelValue(X) > 1250 && rxGetChannelValue(X) < 1750) @@ -152,8 +153,6 @@ FILE_COMPILE_FOR_SPEED static timeMs_t notify_settings_saved = 0; static bool savingSettings = false; -// static bool statsUpdating = false; -// static timeMs_t cmsYieldUntil = 0; static unsigned currentLayout = 0; static int layoutOverride = -1; @@ -179,12 +178,10 @@ typedef struct statistic_s { static statistic_t stats; static timeUs_t resumeRefreshAt = 0; -static bool refreshWaitForResumeCmdRelease; static bool fullRedraw = false; static uint8_t armState; -static uint8_t statsPagesCheck = 0; typedef struct osdMapData_s { uint32_t scale; @@ -243,26 +240,6 @@ bool osdDisplayIsHD(void) return false; } -bool osdVideoSystemIsSinglePageStatsCompatible(void) -{ - bool result = false; - - switch ((videoSystem_e)osdConfig()->video_system) { - case VIDEO_SYSTEM_HDZERO: - FALLTHROUGH; - // Placeholder for Avatar system support once that is complete. - // case VIDEO_SYSTEM_AVATAR: - // FALLTHROUGH; - case VIDEO_SYSTEM_DJIWTF: - result = true; - break; - default: - result = false; - } - - return result; -} - /** * Formats a number given in cents, to support non integer values * without using floating point math. Value is always right aligned @@ -664,6 +641,10 @@ static inline void osdFormatFlyTime(char *buff, textAttributes_t *attr) } } +/** + * Trim whitespace from string. + * Used in Stats screen on lines with multiple values. +*/ char *osdFormatTrimWhiteSpace(char *buff) { char *end; @@ -3687,7 +3668,6 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig) static void osdSetNextRefreshIn(uint32_t timeMs) { resumeRefreshAt = micros() + timeMs * 1000; - refreshWaitForResumeCmdRelease = true; } static void osdCompleteAsyncInitialization(void) @@ -3911,32 +3891,31 @@ static void osdUpdateStats(void) stats.max_altitude = MAX(stats.max_altitude, osdGetAltitude()); } -static void osdShowStats(bool isSinglePageStatsCompatible, int page) +static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) { const char * disarmReasonStr[DISARM_REASON_COUNT] = { "UNKNOWN", "TIMEOUT", "STICKS", "SWITCH", "SWITCH", "KILLSW", "FAILSAFE", "NAV SYS", "LANDING"}; - uint8_t top = 1; /* first fully visible line */ + uint8_t top = 1; // Start one line down leaving space at the top of the screen. size_t multiValueLengthOffset = 0; const uint8_t statNameX = osdDisplayIsHD() ? 11 : 1; const uint8_t statValuesX = osdDisplayIsHD() ? 30 : 20; char buff[10]; - statsPagesCheck = 1; - if (page < 1 || page > 2) - page = 1; + if (page > 1) + page = 0; displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); displayClearScreen(osdDisplayPort); if (isSinglePageStatsCompatible) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS ---"); - } else if (page == 1) { + } else if (page == 0) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- 1/2 ->"); - } else if (page == 2) { + } else if (page == 1) { displayWrite(osdDisplayPort, statNameX, top++, "--- STATS --- <- 2/2"); } - if (isSinglePageStatsCompatible || page == 1) { + if (isSinglePageStatsCompatible || page == 0) { if (feature(FEATURE_GPS)) { if (isSinglePageStatsCompatible) { displayWrite(osdDisplayPort, statNameX, top, "MAX/AVG SPEED :"); @@ -4021,23 +4000,9 @@ static void osdShowStats(bool isSinglePageStatsCompatible, int page) displayWrite(osdDisplayPort, statNameX, top, "DISARMED BY :"); displayWrite(osdDisplayPort, statValuesX, top++, disarmReasonStr[getDisarmReason()]); - - /* We only want to show this message once, so it will be shown after the second - * section for single page stats. */ - if (!isSinglePageStatsCompatible) { - if (savingSettings == true) { - displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS)); - } else if (notify_settings_saved > 0) { - if (millis() > notify_settings_saved) { - notify_settings_saved = 0; - } else { - displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED)); - } - } - } } - if (isSinglePageStatsCompatible || page == 2) { + if (isSinglePageStatsCompatible || page == 1) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); @@ -4168,19 +4133,18 @@ static void osdShowStats(bool isSinglePageStatsCompatible, int page) osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3); osdLeftAlignString(buff); displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); + } - if (savingSettings == true) { - displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS)); - } else if (notify_settings_saved > 0) { - if (millis() > notify_settings_saved) { - notify_settings_saved = 0; - } else { - displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED)); - } + if (savingSettings == true) { + displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SAVING_SETTNGS)); + } else if (notify_settings_saved > 0) { + if (millis() > notify_settings_saved) { + notify_settings_saved = 0; + } else { + displayWrite(osdDisplayPort, statNameX, top++, OSD_MESSAGE_STR(OSD_MSG_SETTINGS_SAVED)); } } - displayHeartbeat(osdDisplayPort); displayCommitTransaction(osdDisplayPort); } @@ -4288,9 +4252,10 @@ static void osdFilterData(timeUs_t currentTimeUs) { lastRefresh = currentTimeUs; } -static bool osdIsPageUpKeyHeld(void) +// Detect when the user is holding the roll stick to the right +static bool osdIsPageUpStickCommandHeld(void) { - static int holdCount = 1; + static int pageUpHoldCount = 1; bool keyHeld = false; @@ -4299,22 +4264,23 @@ static bool osdIsPageUpKeyHeld(void) } if (!keyHeld) { - holdCount = 1; + pageUpHoldCount = 1; } else { - ++holdCount; + ++pageUpHoldCount; } - if (holdCount > 20) { - holdCount = 1; + if (pageUpHoldCount > 20) { + pageUpHoldCount = 1; return true; } return false; } -static bool osdIsPageDownKeyHeld(void) +// Detect when the user is holding the roll stick to the left +static bool osdIsPageDownStickCommandHeld(void) { - static int holdCount = 1; + static int pageDownHoldCount = 1; bool keyHeld = false; if (IS_LO(ROLL)) { @@ -4322,13 +4288,13 @@ static bool osdIsPageDownKeyHeld(void) } if (!keyHeld) { - holdCount = 1; + pageDownHoldCount = 1; } else { - ++holdCount; + ++pageDownHoldCount; } - if (holdCount > 20) { - holdCount = 1; + if (pageDownHoldCount > 20) { + pageDownHoldCount = 1; return true; } @@ -4349,78 +4315,111 @@ static void osdRefresh(timeUs_t currentTimeUs) return; } - // detect arm/disarm - static uint8_t statsPageAutoSwapCntl = 2; + bool statsSinglePageCompatible = (osdDisplayPort->rows >= OSD_STATS_SINGLE_PAGE_MIN_ROWS); + static uint8_t statsCurrentPage = 0; + static bool statsDisplayed = false; + static bool statsAutoPagingEnabled = true; + + // Detect arm/disarm if (armState != ARMING_FLAG(ARMED)) { if (ARMING_FLAG(ARMED)) { + // Display the "Arming" screen + statsDisplayed = false; osdResetStats(); - statsPageAutoSwapCntl = 2; - osdShowArmed(); // reset statistic etc + osdShowArmed(); uint32_t delay = ARMED_SCREEN_DISPLAY_TIME; - statsPagesCheck = 0; #if defined(USE_SAFE_HOME) if (safehome_distance) delay *= 3; #endif osdSetNextRefreshIn(delay); } else { - osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); // show first page of statistics - osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME); - statsPageAutoSwapCntl = osdConfig()->stats_page_auto_swap_time > 0 ? 0 : 2; + // Display the "Stats" screen + statsDisplayed = true; + statsCurrentPage = 0; + statsAutoPagingEnabled = osdConfig()->stats_page_auto_swap_time > 0 ? true : false; + osdShowStats(statsSinglePageCompatible, statsCurrentPage); + osdSetNextRefreshIn(STATS_SCREEN_DISPLAY_TIME); } armState = ARMING_FLAG(ARMED); } - if (resumeRefreshAt) { - - /* This is a workaround to introduce a delay for the paging stick commands so that - * holding the roll stick doesn't cause a race condition with the osdShowStats() method. */ - bool pageUp = false; - bool pageDown = false; - if (!osdVideoSystemIsSinglePageStatsCompatible()) - { - if (osdIsPageUpKeyHeld()) { - pageUp = true; - statsPageAutoSwapCntl = 2; - } else if (osdIsPageDownKeyHeld()) { - pageDown = true; - statsPageAutoSwapCntl = 2; - } - } - - if (statsPageAutoSwapCntl == 2) { - if (pageDown) { - if (statsPagesCheck == 1) { - osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); - } - } else if (pageUp) { - if (statsPagesCheck == 1) { - osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); + // This block is entered when we're showing the "Splash", "Armed" or "Stats" screens + if (resumeRefreshAt) { + + // Handle events only when the "Stats" screen is being displayed. + if (statsDisplayed) { + + // Manual paging stick commands are only applicable to multi-page stats. + // ****************************** + // For single-page stats, this effectively disables the ability to cancel the + // automatic paging/updates with the stick commands. So unless stats_page_auto_swap_time + // is set to 0 or greater than 4 (saved settings display interval is 5 seconds), then + // "Saved Settings" should display if it is active within the refresh interval. + // ****************************** + // With multi-page stats, "Saved Settings" could also be missed if the user + // has canceled automatic paging using the stick commands, because that is only + // updated when osdShowStats() is called. So, in that case, they would only see + // the "Saved Settings" message if they happen to manually change pages using the + // stick commands within the interval the message is displayed. + bool manualPageUpRequested = false; + bool manualPageDownRequested = false; + if (!statsSinglePageCompatible) { + // These methods ensure the paging stick commands are held for a brief period + // Otherwise it can result in a race condition where the stats are + // updated too quickly and can result in partial blanks, etc. + if (osdIsPageUpStickCommandHeld()) { + manualPageUpRequested = true; + statsAutoPagingEnabled = false; + } else if (osdIsPageDownStickCommandHeld()) { + manualPageDownRequested = true; + statsAutoPagingEnabled = false; } } - } else { - if (OSD_ALTERNATING_CHOICES((osdConfig()->stats_page_auto_swap_time * 1000), 2)) { - if (statsPageAutoSwapCntl == 0) { - osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 1); - statsPageAutoSwapCntl = 1; + + if (statsAutoPagingEnabled) { + // 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); + statsCurrentPage = 1; + } + } else { + if (statsCurrentPage == 1) { + osdShowStats(statsSinglePageCompatible, statsCurrentPage); + statsCurrentPage = 0; + } } } else { - if (statsPageAutoSwapCntl == 1) { - osdShowStats(osdVideoSystemIsSinglePageStatsCompatible(), 2); - statsPageAutoSwapCntl = 0; + // Process manual page change events for multi-page stats. + if (manualPageUpRequested) { + osdShowStats(statsSinglePageCompatible, 1); + statsCurrentPage = 1; + } else if (manualPageDownRequested) { + osdShowStats(statsSinglePageCompatible, 0); + statsCurrentPage = 0; } } } - if ((currentTimeUs > resumeRefreshAt) || CANCEL_STATS_COMMAND) { + // Handle events when either "Splash", "Armed" or "Stats" screens are displayed. + if ((currentTimeUs > resumeRefreshAt) || OSD_RESUME_UPDATES_STICK_COMMAND) { + // Time elapsed or canceled by stick commands. + // Exit to normal OSD operation. displayClearScreen(osdDisplayPort); resumeRefreshAt = 0; + statsDisplayed = false; + } else { + // Continue "Splash", "Armed" or "Stats" screens. + displayHeartbeat(osdDisplayPort); } - + return; } +// The "Splash", "Armed" or "Stats" screens are not currently displayed, so resume normal OSD operation. #ifdef USE_CMS if (!displayIsGrabbed(osdDisplayPort)) { displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING);