void osdUpdate(uint32_t currentTime) { static uint8_t rcDelay = BUTTON_TIME; static uint8_t lastSec = 0; uint8_t key = 0, sec; // detect enter to menu if (IS_MID(THROTTLE) && IS_HI(YAW) && IS_HI(PITCH) && !ARMING_FLAG(ARMED)) osdOpenMenu(); // detect arm/disarm if (armState != ARMING_FLAG(ARMED)) { if (ARMING_FLAG(ARMED)) osdArmMotors(); // reset statistic etc else osdShowStats(); // show statistic armState = ARMING_FLAG(ARMED); } osdUpdateStats(); sec = currentTime / 1000000; if (ARMING_FLAG(ARMED) && sec != lastSec) { flyTime++; lastSec = sec; } if (refreshTimeout) { if (IS_HI(THROTTLE) || IS_HI(PITCH)) // hide statistics refreshTimeout = 1; refreshTimeout--; if (!refreshTimeout) max7456ClearScreen(); return; } blinkState = (millis() / 200) % 2; if (inMenu) { if (rcDelay) { rcDelay--; } else if (IS_HI(PITCH)) { key = KEY_UP; rcDelay = BUTTON_TIME; } else if (IS_LO(PITCH)) { key = KEY_DOWN; rcDelay = BUTTON_TIME; } else if (IS_LO(ROLL)) { key = KEY_LEFT; rcDelay = BUTTON_TIME; } else if (IS_HI(ROLL)) { key = KEY_RIGHT; rcDelay = BUTTON_TIME; } else if ((IS_HI(YAW) || IS_LO(YAW)) && currentMenu != menuRc) // this menu is used to check transmitter signals so can exit using YAW { key = KEY_ESC; rcDelay = BUTTON_TIME; } if (key && !currentElement) { rcDelay = osdHandleKey(key); return; } if (currentElement) // edit position of element { if (key) { if (key == KEY_ESC) { // exit osdMenuBack(); rcDelay = BUTTON_PAUSE; *currentElement &= ~BLINK_FLAG; currentElement = NULL; return; } else { uint8_t x, y; x = OSD_X(*currentElement); y = OSD_Y(*currentElement); switch (key) { case KEY_UP: y--; break; case KEY_DOWN: y++; break; case KEY_RIGHT: x++; break; case KEY_LEFT: x--; break; } *currentElement &= 0xFC00; *currentElement |= OSD_POS(x, y); max7456ClearScreen(); } } osdDrawElements(); } else osdDrawMenu(); } else { osdUpdateAlarms(); osdDrawElements(); } }
STATIC_UNIT_TESTED void osdRefresh(timeUs_t currentTimeUs) { static timeUs_t lastTimeUs = 0; static bool osdStatsEnabled = false; static bool osdStatsVisible = false; static timeUs_t osdStatsRefreshTimeUs; static uint16_t endBatteryVoltage; // detect arm/disarm if (armState != ARMING_FLAG(ARMED)) { if (ARMING_FLAG(ARMED)) { osdStatsEnabled = false; osdStatsVisible = false; osdResetStats(); osdShowArmed(); resumeRefreshAt = currentTimeUs + (REFRESH_1S / 2); } else if (isSomeStatEnabled() && (!(getArmingDisableFlags() & ARMING_DISABLED_RUNAWAY_TAKEOFF) || !VISIBLE(osdConfig()->item_pos[OSD_WARNINGS]))) { // suppress stats if runaway takeoff triggered disarm and WARNINGS element is visible osdStatsEnabled = true; resumeRefreshAt = currentTimeUs + (60 * REFRESH_1S); endBatteryVoltage = getBatteryVoltage(); } armState = ARMING_FLAG(ARMED); } if (ARMING_FLAG(ARMED)) { osdUpdateStats(); timeUs_t deltaT = currentTimeUs - lastTimeUs; flyTime += deltaT; stats.armed_time += deltaT; } else if (osdStatsEnabled) { // handle showing/hiding stats based on OSD disable switch position if (displayIsGrabbed(osdDisplayPort)) { osdStatsEnabled = false; resumeRefreshAt = 0; stats.armed_time = 0; } else { if (IS_RC_MODE_ACTIVE(BOXOSD) && osdStatsVisible) { osdStatsVisible = false; displayClearScreen(osdDisplayPort); } else if (!IS_RC_MODE_ACTIVE(BOXOSD)) { if (!osdStatsVisible) { osdStatsVisible = true; osdStatsRefreshTimeUs = 0; } if (currentTimeUs >= osdStatsRefreshTimeUs) { osdStatsRefreshTimeUs = currentTimeUs + REFRESH_1S; osdShowStats(endBatteryVoltage); } } } } lastTimeUs = currentTimeUs; if (resumeRefreshAt) { if (cmp32(currentTimeUs, resumeRefreshAt) < 0) { // in timeout period, check sticks for activity to resume display. if (IS_HI(THROTTLE) || IS_HI(PITCH)) { resumeRefreshAt = currentTimeUs; } displayHeartbeat(osdDisplayPort); return; } else { displayClearScreen(osdDisplayPort); resumeRefreshAt = 0; osdStatsEnabled = false; stats.armed_time = 0; } } blinkState = (currentTimeUs / 200000) % 2; #ifdef USE_ESC_SENSOR if (feature(FEATURE_ESC_SENSOR)) { escDataCombined = getEscSensorData(ESC_SENSOR_COMBINED); } #endif #ifdef USE_CMS if (!displayIsGrabbed(osdDisplayPort)) { osdUpdateAlarms(); osdDrawElements(); displayHeartbeat(osdDisplayPort); #ifdef OSD_CALLS_CMS } else { cmsUpdate(currentTimeUs); #endif } #endif lastArmState = ARMING_FLAG(ARMED); }