/* * Called periodically by the scheduler */ void osdUpdate(timeUs_t currentTimeUs) { static uint32_t counter = 0; if (isBeeperOn()) { showVisualBeeper = true; } #ifdef MAX7456_DMA_CHANNEL_TX // don't touch buffers if DMA transaction is in progress if (displayIsTransferInProgress(osdDisplayPort)) { return; } #endif // MAX7456_DMA_CHANNEL_TX #ifdef USE_SLOW_MSP_DISPLAYPORT_RATE_WHEN_UNARMED static uint32_t idlecounter = 0; if (!ARMING_FLAG(ARMED)) { if (idlecounter++ % 4 != 0) { return; } } #endif // redraw values in buffer #ifdef USE_MAX7456 #define DRAW_FREQ_DENOM 5 #else #define DRAW_FREQ_DENOM 10 // MWOSD @ 115200 baud ( #endif #define STATS_FREQ_DENOM 50 if (counter % DRAW_FREQ_DENOM == 0) { osdRefresh(currentTimeUs); showVisualBeeper = false; } else { // rest of time redraw screen 10 chars per idle so it doesn't lock the main idle displayDrawScreen(osdDisplayPort); } ++counter; #ifdef USE_CMS // do not allow ARM if we are in menu if (displayIsGrabbed(osdDisplayPort)) { setArmingDisabled(ARMING_DISABLED_OSD_MENU); } else { unsetArmingDisabled(ARMING_DISABLED_OSD_MENU); } #endif }
void dashboardUpdate(timeUs_t currentTimeUs) { static uint8_t previousArmedState = 0; bool pageChanging; #ifdef CMS static bool wasGrabbed = false; if (displayIsGrabbed(displayPort)) { wasGrabbed = true; return; } else if (wasGrabbed) { pageChanging = true; wasGrabbed = false; } else { pageChanging = false; } #else pageChanging = false; #endif bool updateNow = (int32_t)(currentTimeUs - nextDisplayUpdateAt) >= 0L; if (!updateNow) { return; } nextDisplayUpdateAt = currentTimeUs + DASHBOARD_UPDATE_FREQUENCY; bool armedState = ARMING_FLAG(ARMED) ? true : false; bool armedStateChanged = armedState != previousArmedState; previousArmedState = armedState; if (armedState) { if (!armedStateChanged) { return; } currentPageId = PAGE_ARMED; pageChanging = true; } else { if (armedStateChanged) { currentPageId = PAGE_STATUS; pageChanging = true; } if ((currentPageId == PAGE_WELCOME) && ((int32_t)(currentTimeUs - nextPageAt) >= 0L)) { currentPageId = PAGE_STATUS; pageChanging = true; } if (forcePageChange) { pageChanging = true; forcePageChange = false; } } if (pageChanging) { // Some OLED displays do not respond on the first initialisation so refresh the display // when the page changes in the hopes the hardware responds. This also allows the // user to power off/on the display or connect it while powered. if (!displayPresent) { resetDisplay(); } if (!displayPresent) { return; } i2c_OLED_clear_display_quick(); showTitle(); } if (!displayPresent) { return; } switch(currentPageId) { case PAGE_WELCOME: showWelcomePage(); break; case PAGE_ARMED: showArmedPage(); break; case PAGE_STATUS: showStatusPage(); break; } if (!armedState) { updateFailsafeStatus(); updateRxStatus(); updateTicker(); } }
void dashboardUpdate(timeUs_t currentTimeUs) { static uint8_t previousArmedState = 0; #ifdef CMS if (displayIsGrabbed(displayPort)) { return; } #endif const bool updateNow = (int32_t)(currentTimeUs - nextDisplayUpdateAt) >= 0L; if (!updateNow) { return; } nextDisplayUpdateAt = currentTimeUs + DISPLAY_UPDATE_FREQUENCY; bool armedState = ARMING_FLAG(ARMED) ? true : false; bool armedStateChanged = armedState != previousArmedState; previousArmedState = armedState; if (armedState) { if (!armedStateChanged) { return; } dashboardSetPage(PAGE_ARMED); pageState.pageChanging = true; } else { if (armedStateChanged) { pageState.pageFlags |= PAGE_STATE_FLAG_FORCE_PAGE_CHANGE; } pageState.pageChanging = (pageState.pageFlags & PAGE_STATE_FLAG_FORCE_PAGE_CHANGE) || (((int32_t)(currentTimeUs - pageState.nextPageAt) >= 0L && (pageState.pageFlags & PAGE_STATE_FLAG_CYCLE_ENABLED))); if (pageState.pageChanging && (pageState.pageFlags & PAGE_STATE_FLAG_CYCLE_ENABLED)) { do { pageState.cycleIndex++; pageState.cycleIndex = pageState.cycleIndex % PAGE_COUNT; pageState.page = &pages[pageState.cycleIndex]; } while (pageState.page->flags & PAGE_FLAGS_SKIP_CYCLING); } } if (pageState.pageChanging) { pageState.pageFlags &= ~PAGE_STATE_FLAG_FORCE_PAGE_CHANGE; pageState.nextPageAt = currentTimeUs + PAGE_CYCLE_FREQUENCY; // Some OLED displays do not respond on the first initialisation so refresh the display // when the page changes in the hopes the hardware responds. This also allows the // user to power off/on the display or connect it while powered. resetDisplay(); if (!dashboardPresent) { return; } handlePageChange(); } if (!dashboardPresent) { return; } pageState.page->drawFn(); if (!armedState) { updateFailsafeStatus(); updateRxStatus(); updateTicker(); } }
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); }