diff --git a/src/main/interface/msp.c b/src/main/interface/msp.c index 4ebee9bbc..77b06b6a9 100644 --- a/src/main/interface/msp.c +++ b/src/main/interface/msp.c @@ -699,7 +699,7 @@ static bool mspCommonProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProce // Post flight statistics sbufWriteU8(dst, OSD_STAT_COUNT); for (int i = 0; i < OSD_STAT_COUNT; i++ ) { - sbufWriteU8(dst, osdConfig()->enabled_stats[i]); + sbufWriteU8(dst, osdStatGetState(i)); } // Timers @@ -2191,7 +2191,7 @@ static mspResult_e mspCommonProcessInCommand(uint8_t cmdMSP, sbuf_t *src) if (screen == 0 && addr < OSD_STAT_COUNT) { /* Set statistic item enable */ - osdConfigMutable()->enabled_stats[addr] = value; + osdStatSetState(addr, (value != 0)); } else if (addr < OSD_ITEM_COUNT) { /* Set element positions */ osdConfigMutable()->item_pos[addr] = value; diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c index cf5b9a9f5..e2ff3aa1f 100644 --- a/src/main/interface/settings.c +++ b/src/main/interface/settings.c @@ -867,20 +867,22 @@ const clivalue_t valueTable[] = { { "osd_adjustment_range_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_ADJUSTMENT_RANGE]) }, { "osd_core_temp_pos", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 0, OSD_POSCFG_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, item_pos[OSD_CORE_TEMPERATURE]) }, - { "osd_stat_max_spd", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_SPEED])}, - { "osd_stat_max_dist", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_DISTANCE])}, - { "osd_stat_min_batt", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MIN_BATTERY])}, - { "osd_stat_min_rssi", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MIN_RSSI])}, - { "osd_stat_max_curr", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_CURRENT])}, - { "osd_stat_used_mah", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_USED_MAH])}, - { "osd_stat_max_alt", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_MAX_ALTITUDE])}, - { "osd_stat_bbox", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_BLACKBOX])}, - { "osd_stat_endbatt", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_END_BATTERY])}, - { "osd_stat_battery", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_BATTERY])}, - { "osd_stat_bb_no", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_BLACKBOX_NUMBER])}, - { "osd_stat_rtc_date_time", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_RTC_DATE_TIME])}, - { "osd_stat_tim_1", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_TIMER_1])}, - { "osd_stat_tim_2", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats[OSD_STAT_TIMER_2])}, + // OSD stats enabled flags are stored as bitmapped values inside a 32bit parameter + { "osd_stat_max_spd", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MAX_SPEED, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_max_dist", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MAX_DISTANCE, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_min_batt", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MIN_BATTERY, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_min_rssi", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MIN_RSSI, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_max_curr", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MAX_CURRENT, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_used_mah", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_USED_MAH, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_max_alt", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_MAX_ALTITUDE, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_bbox", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_BLACKBOX, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_endbatt", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_END_BATTERY, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_battery", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_BATTERY, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_bb_no", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_BLACKBOX_NUMBER, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_rtc_date_time", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_RTC_DATE_TIME, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_tim_1", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_TIMER_1, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + { "osd_stat_tim_2", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = OSD_STAT_TIMER_2, PG_OSD_CONFIG, offsetof(osdConfig_t, enabled_stats)}, + #endif // PG_SYSTEM_CONFIG diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 3c7ac9cbe..1f13c9cf6 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -166,7 +166,7 @@ static const char compassBar[] = { SYM_HEADING_LINE, SYM_HEADING_DIVIDED_LINE, SYM_HEADING_LINE }; -PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 2); +PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 3); /** * Gets the correct altitude symbol for the current unit system @@ -385,6 +385,20 @@ static void osdFormatMessage(char *buff, size_t size, const char *message) buff[size - 1] = '\0'; } +void osdStatSetState(uint8_t statIndex, bool enabled) +{ + if (enabled) { + osdConfigMutable()->enabled_stats |= (1 << statIndex); + } else { + osdConfigMutable()->enabled_stats &= ~(1 << statIndex); + } +} + +bool osdStatGetState(uint8_t statIndex) +{ + return osdConfig()->enabled_stats & (1 << statIndex); +} + static bool osdDrawSingleElement(uint8_t item) { if (!VISIBLE(osdConfig()->item_pos[item]) || BLINK(item)) { @@ -951,20 +965,16 @@ void pgResetFn_osdConfig(osdConfig_t *osdConfig) osdConfig->item_pos[OSD_ARTIFICIAL_HORIZON] = OSD_POS(14, 2); osdConfig->item_pos[OSD_HORIZON_SIDEBARS] = OSD_POS(14, 6); - osdConfig->enabled_stats[OSD_STAT_MAX_SPEED] = true; - osdConfig->enabled_stats[OSD_STAT_MIN_BATTERY] = true; - osdConfig->enabled_stats[OSD_STAT_MIN_RSSI] = true; - osdConfig->enabled_stats[OSD_STAT_MAX_CURRENT] = true; - osdConfig->enabled_stats[OSD_STAT_USED_MAH] = true; - osdConfig->enabled_stats[OSD_STAT_MAX_ALTITUDE] = false; - osdConfig->enabled_stats[OSD_STAT_BLACKBOX] = true; - osdConfig->enabled_stats[OSD_STAT_END_BATTERY] = false; - osdConfig->enabled_stats[OSD_STAT_MAX_DISTANCE] = false; - osdConfig->enabled_stats[OSD_STAT_BLACKBOX_NUMBER] = true; - osdConfig->enabled_stats[OSD_STAT_TIMER_1] = false; - osdConfig->enabled_stats[OSD_STAT_TIMER_2] = true; - osdConfig->enabled_stats[OSD_STAT_RTC_DATE_TIME] = false; - osdConfig->enabled_stats[OSD_STAT_BATTERY] = false; + // Enable the default stats + osdConfig->enabled_stats = 0; // reset all to off and enable only a few initially + osdStatSetState(OSD_STAT_MAX_SPEED, true); + osdStatSetState(OSD_STAT_MIN_BATTERY, true); + osdStatSetState(OSD_STAT_MIN_RSSI, true); + osdStatSetState(OSD_STAT_MAX_CURRENT, true); + osdStatSetState(OSD_STAT_USED_MAH, true); + osdStatSetState(OSD_STAT_BLACKBOX, true); + osdStatSetState(OSD_STAT_BLACKBOX_NUMBER, true); + osdStatSetState(OSD_STAT_TIMER_2, true); osdConfig->units = OSD_UNIT_METRIC; @@ -1236,12 +1246,7 @@ static void osdDisplayStatisticLabel(uint8_t y, const char * text, const char * */ static bool isSomeStatEnabled(void) { - for (int i = 0; i < OSD_STAT_COUNT; i++) { - if (osdConfig()->enabled_stats[i]) { - return true; - } - } - return false; + return (osdConfig()->enabled_stats != 0); } static void osdShowStats(uint16_t endBatteryVoltage) @@ -1252,7 +1257,7 @@ static void osdShowStats(uint16_t endBatteryVoltage) displayClearScreen(osdDisplayPort); displayWrite(osdDisplayPort, 2, top++, " --- STATS ---"); - if (osdConfig()->enabled_stats[OSD_STAT_RTC_DATE_TIME]) { + if (osdStatGetState(OSD_STAT_RTC_DATE_TIME)) { bool success = false; #ifdef USE_RTC_TIME success = osdFormatRtcDateTime(&buff[0]); @@ -1264,72 +1269,72 @@ static void osdShowStats(uint16_t endBatteryVoltage) displayWrite(osdDisplayPort, 2, top++, buff); } - if (osdConfig()->enabled_stats[OSD_STAT_TIMER_1]) { + if (osdStatGetState(OSD_STAT_TIMER_1)) { osdFormatTimer(buff, false, (OSD_TIMER_SRC(osdConfig()->timers[OSD_TIMER_1]) == OSD_TIMER_SRC_ON ? false : true), OSD_TIMER_1); osdDisplayStatisticLabel(top++, osdTimerSourceNames[OSD_TIMER_SRC(osdConfig()->timers[OSD_TIMER_1])], buff); } - if (osdConfig()->enabled_stats[OSD_STAT_TIMER_2]) { + if (osdStatGetState(OSD_STAT_TIMER_2)) { osdFormatTimer(buff, false, (OSD_TIMER_SRC(osdConfig()->timers[OSD_TIMER_2]) == OSD_TIMER_SRC_ON ? false : true), OSD_TIMER_2); osdDisplayStatisticLabel(top++, osdTimerSourceNames[OSD_TIMER_SRC(osdConfig()->timers[OSD_TIMER_2])], buff); } - if (osdConfig()->enabled_stats[OSD_STAT_MAX_SPEED] && STATE(GPS_FIX)) { + if (osdStatGetState(OSD_STAT_MAX_SPEED) && STATE(GPS_FIX)) { itoa(stats.max_speed, buff, 10); osdDisplayStatisticLabel(top++, "MAX SPEED", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_MAX_DISTANCE]) { + if (osdStatGetState(OSD_STAT_MAX_DISTANCE)) { tfp_sprintf(buff, "%d%c", osdGetMetersToSelectedUnit(stats.max_distance), osdGetMetersToSelectedUnitSymbol()); osdDisplayStatisticLabel(top++, "MAX DISTANCE", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_MIN_BATTERY]) { + if (osdStatGetState(OSD_STAT_MIN_BATTERY)) { tfp_sprintf(buff, "%d.%1d%c", stats.min_voltage / 10, stats.min_voltage % 10, SYM_VOLT); osdDisplayStatisticLabel(top++, "MIN BATTERY", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_END_BATTERY]) { + if (osdStatGetState(OSD_STAT_END_BATTERY)) { tfp_sprintf(buff, "%d.%1d%c", endBatteryVoltage / 10, endBatteryVoltage % 10, SYM_VOLT); osdDisplayStatisticLabel(top++, "END BATTERY", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_BATTERY]) { + if (osdStatGetState(OSD_STAT_BATTERY)) { tfp_sprintf(buff, "%d.%1d%c", getBatteryVoltage() / 10, getBatteryVoltage() % 10, SYM_VOLT); osdDisplayStatisticLabel(top++, "BATTERY", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_MIN_RSSI]) { + if (osdStatGetState(OSD_STAT_MIN_RSSI)) { itoa(stats.min_rssi, buff, 10); strcat(buff, "%"); osdDisplayStatisticLabel(top++, "MIN RSSI", buff); } if (batteryConfig()->currentMeterSource != CURRENT_METER_NONE) { - if (osdConfig()->enabled_stats[OSD_STAT_MAX_CURRENT]) { + if (osdStatGetState(OSD_STAT_MAX_CURRENT)) { itoa(stats.max_current, buff, 10); strcat(buff, "A"); osdDisplayStatisticLabel(top++, "MAX CURRENT", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_USED_MAH]) { + if (osdStatGetState(OSD_STAT_USED_MAH)) { tfp_sprintf(buff, "%d%c", getMAhDrawn(), SYM_MAH); osdDisplayStatisticLabel(top++, "USED MAH", buff); } } - if (osdConfig()->enabled_stats[OSD_STAT_MAX_ALTITUDE]) { + if (osdStatGetState(OSD_STAT_MAX_ALTITUDE)) { osdFormatAltitudeString(buff, stats.max_altitude, false); osdDisplayStatisticLabel(top++, "MAX ALTITUDE", buff); } #ifdef USE_BLACKBOX - if (osdConfig()->enabled_stats[OSD_STAT_BLACKBOX] && blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) { + if (osdStatGetState(OSD_STAT_BLACKBOX) && blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) { osdGetBlackboxStatusString(buff); osdDisplayStatisticLabel(top++, "BLACKBOX", buff); } - if (osdConfig()->enabled_stats[OSD_STAT_BLACKBOX_NUMBER] && blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) { + if (osdStatGetState(OSD_STAT_BLACKBOX_NUMBER) && blackboxConfig()->device && blackboxConfig()->device != BLACKBOX_DEVICE_SERIAL) { itoa(blackboxGetLogNumber(), buff, 10); osdDisplayStatisticLabel(top++, "BB LOG NUM", buff); } diff --git a/src/main/io/osd.h b/src/main/io/osd.h index b98d9859c..e34cbc78c 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -113,6 +113,9 @@ typedef enum { OSD_STAT_COUNT // MUST BE LAST } osd_stats_e; +// Make sure the number of stats do not exceed the available 32bit storage +STATIC_ASSERT(OSD_STAT_COUNT <= 32, osdstats_overflow); + typedef enum { OSD_UNIT_IMPERIAL, OSD_UNIT_METRIC @@ -166,7 +169,7 @@ typedef struct osdConfig_s { uint8_t ahMaxPitch; uint8_t ahMaxRoll; - bool enabled_stats[OSD_STAT_COUNT]; + uint32_t enabled_stats; int8_t esc_temp_alarm; int16_t esc_rpm_alarm; int16_t esc_current_alarm; @@ -180,3 +183,6 @@ struct displayPort_s; void osdInit(struct displayPort_s *osdDisplayPort); void osdResetAlarms(void); void osdUpdate(timeUs_t currentTimeUs); +void osdStatSetState(uint8_t statIndex, bool enabled); +bool osdStatGetState(uint8_t statIndex); + diff --git a/src/test/unit/osd_unittest.cc b/src/test/unit/osd_unittest.cc index 10ebe3351..853737210 100644 --- a/src/test/unit/osd_unittest.cc +++ b/src/test/unit/osd_unittest.cc @@ -142,12 +142,7 @@ void doTestArm(bool testEmpty = true) * Auxiliary function. Test is there're stats that must be shown */ bool isSomeStatEnabled(void) { - for (int i = 0; i < OSD_STAT_COUNT; i++) { - if (osdConfigMutable()->enabled_stats[i]) { - return true; - } - } - return false; + return (osdConfigMutable()->enabled_stats != 0); } /* @@ -288,19 +283,19 @@ TEST(OsdTest, TestStatsImperial) { // given // this set of enabled post flight statistics - osdConfigMutable()->enabled_stats[OSD_STAT_MAX_SPEED] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_MIN_BATTERY] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_MIN_RSSI] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_MAX_CURRENT] = false; - osdConfigMutable()->enabled_stats[OSD_STAT_USED_MAH] = false; - osdConfigMutable()->enabled_stats[OSD_STAT_MAX_ALTITUDE] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_BLACKBOX] = false; - osdConfigMutable()->enabled_stats[OSD_STAT_END_BATTERY] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_TIMER_1] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_TIMER_2] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_RTC_DATE_TIME] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_MAX_DISTANCE] = true; - osdConfigMutable()->enabled_stats[OSD_STAT_BLACKBOX_NUMBER] = false; + osdStatSetState(OSD_STAT_MAX_SPEED, true); + osdStatSetState(OSD_STAT_MIN_BATTERY, true); + osdStatSetState(OSD_STAT_MIN_RSSI, true); + osdStatSetState(OSD_STAT_MAX_CURRENT, false); + osdStatSetState(OSD_STAT_USED_MAH, false); + osdStatSetState(OSD_STAT_MAX_ALTITUDE, true); + osdStatSetState(OSD_STAT_BLACKBOX, false); + osdStatSetState(OSD_STAT_END_BATTERY, true); + osdStatSetState(OSD_STAT_TIMER_1, true); + osdStatSetState(OSD_STAT_TIMER_2, true); + osdStatSetState(OSD_STAT_RTC_DATE_TIME, true); + osdStatSetState(OSD_STAT_MAX_DISTANCE, true); + osdStatSetState(OSD_STAT_BLACKBOX_NUMBER, false); // and // using imperial unit system