void updateLedStrip(void) { if (!(ledStripInitialised && isWS2811LedStripReady())) { return; } uint32_t now = micros(); bool animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L; bool indicatorFlashNow = (int32_t)(now - nextIndicatorFlashAt) >= 0L; bool warningFlashNow = (int32_t)(now - nextWarningFlashAt) >= 0L; if (!(warningFlashNow || indicatorFlashNow || animationUpdateNow)) { return; } static uint8_t indicatorFlashState = 0; // LAYER 1 applyLedModeLayer(); applyLedThrottleLayer(); // LAYER 2 if (warningFlashNow) { nextWarningFlashAt = now + LED_STRIP_10HZ; } applyLedWarningLayer(warningFlashNow); // LAYER 3 if (indicatorFlashNow) { uint8_t rollScale = abs(rcCommand[ROLL]) / 50; uint8_t pitchScale = abs(rcCommand[PITCH]) / 50; uint8_t scale = max(rollScale, pitchScale); nextIndicatorFlashAt = now + (LED_STRIP_5HZ / max(1, scale)); if (indicatorFlashState == 0) { indicatorFlashState = 1; } else { indicatorFlashState = 0; } } applyLedIndicatorLayer(indicatorFlashState); if (animationUpdateNow) { nextAnimationUpdateAt = now + LED_STRIP_20HZ; updateLedAnimationState(); } #ifdef USE_LED_ANIMATION applyLedAnimationLayer(); #endif ws2811UpdateStrip(); }
void ledStripUpdate(timeUs_t currentTimeUs) { if (!(ledStripInitialised && isWS2811LedStripReady())) { return; } if (IS_RC_MODE_ACTIVE(BOXLEDLOW) && !(ledStripConfig()->ledstrip_visual_beeper && isBeeperOn())) { if (ledStripEnabled) { ledStripDisable(); ledStripEnabled = false; } return; } ledStripEnabled = true; const uint32_t now = currentTimeUs; // test all led timers, setting corresponding bits uint32_t timActive = 0; for (timId_e timId = 0; timId < timTimerCount; timId++) { if (!(disabledTimerMask & (1 << timId))) { // sanitize timer value, so that it can be safely incremented. Handles inital timerVal value. const timeDelta_t delta = cmpTimeUs(now, timerVal[timId]); // max delay is limited to 5s if (delta < 0 && delta > -MAX_TIMER_DELAY) continue; // not ready yet timActive |= 1 << timId; if (delta >= 100 * 1000 || delta < 0) { timerVal[timId] = now; } } } if (!timActive) return; // no change this update, keep old state // apply all layers; triggered timed functions has to update timers scaledThrottle = ARMING_FLAG(ARMED) ? scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 0, 100) : 0; auxInput = rcData[ledStripConfig()->ledstrip_aux_channel]; applyLedFixedLayers(); for (timId_e timId = 0; timId < ARRAYLEN(layerTable); timId++) { uint32_t *timer = &timerVal[timId]; bool updateNow = timActive & (1 << timId); (*layerTable[timId])(updateNow, timer); } ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); }
void ledStripUpdate(uint32_t currentTime) { if (!(ledStripInitialised && isWS2811LedStripReady())) { return; } if (IS_RC_MODE_ACTIVE(BOXLEDLOW) && !(currentLedStripConfig->ledstrip_visual_beeper && isBeeperOn())) { if (ledStripEnabled) { ledStripDisable(); ledStripEnabled = false; } return; } ledStripEnabled = true; const uint32_t now = currentTime; // test all led timers, setting corresponding bits uint32_t timActive = 0; for (timId_e timId = 0; timId < timTimerCount; timId++) { // sanitize timer value, so that it can be safely incremented. Handles inital timerVal value. // max delay is limited to 5s int32_t delta = cmp32(now, timerVal[timId]); if (delta < 0 && delta > -LED_STRIP_MS(5000)) continue; // not ready yet timActive |= 1 << timId; if (delta >= LED_STRIP_MS(100) || delta < 0) { timerVal[timId] = now; } } if (!timActive) return; // no change this update, keep old state // apply all layers; triggered timed functions has to update timers scaledThrottle = ARMING_FLAG(ARMED) ? scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 10, 100) : 10; scaledAux = scaleRange(rcData[currentLedStripConfig->ledstrip_aux_channel], PWM_RANGE_MIN, PWM_RANGE_MAX, 0, HSV_HUE_MAX + 1); applyLedFixedLayers(); for (timId_e timId = 0; timId < ARRAYLEN(layerTable); timId++) { uint32_t *timer = &timerVal[timId]; bool updateNow = timActive & (1 << timId); (*layerTable[timId])(updateNow, timer); } ws2811UpdateStrip(); }
void updateLedStrip(void) { if (!(ledStripInitialised && isWS2811LedStripReady())) { return; } uint32_t now = micros(); bool animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L; bool indicatorFlashNow = (int32_t)(now - nextIndicatorFlashAt) >= 0L; bool warningFlashNow = (int32_t)(now - nextWarningFlashAt) >= 0L; if (!(warningFlashNow || indicatorFlashNow || animationUpdateNow)) { return; } static uint8_t indicatorFlashState = 0; static uint8_t warningState = 0; static uint8_t warningFlags; // LAYER 1 applyLedModeLayer(); applyLedThrottleLayer(); // LAYER 2 if (warningFlashNow) { nextWarningFlashAt = now + LED_STRIP_10HZ; if (warningState == 0) { warningState = 1; warningFlags = WARNING_FLAG_NONE; if (feature(FEATURE_VBAT) && shouldSoundBatteryAlarm()) { warningFlags |= WARNING_FLAG_LOW_BATTERY; } if (failsafe->vTable->hasTimerElapsed()) { warningFlags |= WARNING_FLAG_FAILSAFE; } } else { warningState = 0; } } if (warningFlags) { applyLedWarningLayer(warningState, warningFlags); } // LAYER 3 if (indicatorFlashNow) { uint8_t rollScale = abs(rcCommand[ROLL]) / 50; uint8_t pitchScale = abs(rcCommand[PITCH]) / 50; uint8_t scale = max(rollScale, pitchScale); nextIndicatorFlashAt = now + (LED_STRIP_5HZ / max(1, scale)); if (indicatorFlashState == 0) { indicatorFlashState = 1; } else { indicatorFlashState = 0; } } applyLedIndicatorLayer(indicatorFlashState); if (animationUpdateNow) { nextAnimationUpdateAt = now + LED_STRIP_20HZ; updateLedAnimationState(); } #ifdef USE_LED_ANIMATION applyLedAnimationLayer(); #endif ws2811UpdateStrip(); }
void updateLedStrip(void) { if (!(ledStripInitialised && isWS2811LedStripReady())) { return; } if (IS_RC_MODE_ACTIVE(BOXLEDLOW)) { if (ledStripEnabled) { ledStripDisable(); ledStripEnabled = false; } } else { ledStripEnabled = true; } if (!ledStripEnabled){ return; } uint32_t now = micros(); bool indicatorFlashNow = (int32_t)(now - nextIndicatorFlashAt) >= 0L; bool warningFlashNow = (int32_t)(now - nextWarningFlashAt) >= 0L; bool rotationUpdateNow = (int32_t)(now - nextRotationUpdateAt) >= 0L; #ifdef USE_LED_ANIMATION bool animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L; #endif if (!( indicatorFlashNow || rotationUpdateNow || warningFlashNow #ifdef USE_LED_ANIMATION || animationUpdateNow #endif )) { return; } static uint8_t indicatorFlashState = 0; // LAYER 1 applyLedModeLayer(); applyLedThrottleLayer(); // LAYER 2 if (warningFlashNow) { nextWarningFlashAt = now + LED_STRIP_10HZ; } applyLedWarningLayer(warningFlashNow); // LAYER 3 if (indicatorFlashNow) { uint8_t rollScale = ABS(rcCommand[ROLL]) / 50; uint8_t pitchScale = ABS(rcCommand[PITCH]) / 50; uint8_t scale = MAX(rollScale, pitchScale); nextIndicatorFlashAt = now + (LED_STRIP_5HZ / MAX(1, scale)); if (indicatorFlashState == 0) { indicatorFlashState = 1; } else { indicatorFlashState = 0; } } applyLedIndicatorLayer(indicatorFlashState); #ifdef USE_LED_ANIMATION if (animationUpdateNow) { nextAnimationUpdateAt = now + LED_STRIP_20HZ; updateLedAnimationState(); } applyLedAnimationLayer(); #endif if (rotationUpdateNow) { applyLedThrustRingLayer(); uint8_t animationSpeedScale = 1; if (ARMING_FLAG(ARMED)) { animationSpeedScale = scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 1, 10); } nextRotationUpdateAt = now + LED_STRIP_5HZ/animationSpeedScale; } ws2811UpdateStrip(); }