From 905f14d86cbbab1052ba05d9e162765b8696bf65 Mon Sep 17 00:00:00 2001 From: Bruce Luckcuck Date: Mon, 7 May 2018 08:40:16 -0400 Subject: [PATCH] Change enabled OSD stats storage to bitmap Previously the flags controlling the enabled OSD stats were stored as an array of boolean. This change reduces config storage by storing the flags as bits inside a single uint32. --- src/main/interface/msp.c | 4 +- src/main/interface/settings.c | 30 +++++++------- src/main/io/osd.c | 75 +++++++++++++++++++---------------- src/main/io/osd.h | 8 +++- src/test/unit/osd_unittest.cc | 33 +++++++-------- 5 files changed, 79 insertions(+), 71 deletions(-) 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