void updateRx(uint32_t currentTime) { rxDataReceived = false; shouldCheckPulse = true; if (rxSignalReceived) { if (((int32_t)(currentTime - needRxSignalBefore) >= 0)) { rxSignalReceived = false; #ifdef DEBUG_RX_SIGNAL_LOSS debug[0]++; #endif } } #ifdef SERIAL_RX if (feature(FEATURE_RX_SERIAL)) { uint8_t frameStatus = serialRxFrameStatus(rxConfig); if (frameStatus & SERIAL_RX_FRAME_COMPLETE) { rxDataReceived = true; rxSignalReceived = (frameStatus & SERIAL_RX_FRAME_FAILSAFE) == 0; if (rxSignalReceived && feature(FEATURE_FAILSAFE)) { shouldCheckPulse = false; failsafeOnValidDataReceived(); } } else { shouldCheckPulse = false; } } #endif if (feature(FEATURE_RX_MSP)) { rxDataReceived = rxMspFrameComplete(); if (rxDataReceived) { if (feature(FEATURE_FAILSAFE)) { failsafeOnValidDataReceived(); } } } if ((feature(FEATURE_RX_SERIAL | FEATURE_RX_MSP) && rxDataReceived) || feature(FEATURE_RX_PARALLEL_PWM)) { needRxSignalBefore = currentTime + DELAY_10_HZ; } if (feature(FEATURE_RX_PPM)) { if (isPPMDataBeingReceived()) { rxSignalReceived = true; needRxSignalBefore = currentTime + DELAY_10_HZ; resetPPMDataReceivedState(); } shouldCheckPulse = rxSignalReceived; } }
static void detectAndApplySignalLossBehaviour(void) { int channel; uint16_t sample; bool useValueFromRx = true; bool rxIsDataDriven = isRxDataDriven(); if (!rxSignalReceived) { if (rxIsDataDriven && rxDataReceived) { // use the values from the RX } else { useValueFromRx = false; } } rxResetFlightChannelStatus(); for (channel = 0; channel < rxRuntimeConfig.channelCount; channel++) { sample = (useValueFromRx) ? rcRaw[channel] : PPM_RCVR_TIMEOUT; bool validPulse = isPulseValid(sample); if (!validPulse) { sample = getRxfailValue(channel); } rxUpdateFlightChannelStatus(channel, validPulse); if (rxIsDataDriven) { rcData[channel] = sample; } else { rcData[channel] = calculateNonDataDrivenChannel(channel, sample); } } rxFlightChannelsValid = rxHaveValidFlightChannels(); if ((rxFlightChannelsValid) && !IS_RC_MODE_ACTIVE(BOXFAILSAFE)) { failsafeOnValidDataReceived(); } else { rxSignalReceived = false; failsafeOnValidDataFailed(); for (channel = 0; channel < rxRuntimeConfig.channelCount; channel++) { rcData[channel] = getRxfailValue(channel); } } }
// pulse duration is in micro seconds (usec) STATIC_UNIT_TESTED void rxCheckPulse(uint8_t channel, uint16_t pulseDuration) { static uint8_t goodChannelMask = 0; if (channel < 4 && pulseDuration >= rxConfig->rx_min_usec && pulseDuration <= rxConfig->rx_max_usec ) { // if signal is valid - mark channel as OK goodChannelMask |= (1 << channel); } if (goodChannelMask == REQUIRED_CHANNEL_MASK) { goodChannelMask = 0; failsafeOnValidDataReceived(); rxSignalReceived = true; rxPwmFlightChannelsAreGood = true; } }
static void detectAndApplySignalLossBehaviour(void) { int channel; uint16_t sample; bool useValueFromRx = true; bool rxIsDataDriven = isRxDataDriven(); uint32_t currentMilliTime = millis(); if (!rxIsDataDriven) { rxSignalReceived = rxSignalReceivedNotDataDriven; rxIsInFailsafeMode = rxIsInFailsafeModeNotDataDriven; } if (!rxSignalReceived || rxIsInFailsafeMode) { useValueFromRx = false; } #ifdef DEBUG_RX_SIGNAL_LOSS debug[0] = rxSignalReceived; debug[1] = rxIsInFailsafeMode; debug[2] = rxRuntimeConfig.rcReadRawFn(&rxRuntimeConfig, 0); #endif rxResetFlightChannelStatus(); for (channel = 0; channel < rxRuntimeConfig.channelCount; channel++) { sample = (useValueFromRx) ? rcRaw[channel] : PPM_RCVR_TIMEOUT; bool validPulse = isPulseValid(sample); if (!validPulse) { if (currentMilliTime < rcInvalidPulsPeriod[channel]) { sample = rcData[channel]; // hold channel for MAX_INVALID_PULS_TIME } else { sample = getRxfailValue(channel); // after that apply rxfail value rxUpdateFlightChannelStatus(channel, validPulse); } } else { rcInvalidPulsPeriod[channel] = currentMilliTime + MAX_INVALID_PULS_TIME; } if (rxIsDataDriven) { rcData[channel] = sample; } else { rcData[channel] = calculateNonDataDrivenChannel(channel, sample); } } rxFlightChannelsValid = rxHaveValidFlightChannels(); if ((rxFlightChannelsValid) && !(IS_RC_MODE_ACTIVE(BOXFAILSAFE) && feature(FEATURE_FAILSAFE))) { failsafeOnValidDataReceived(); } else { rxIsInFailsafeMode = rxIsInFailsafeModeNotDataDriven = true; failsafeOnValidDataFailed(); for (channel = 0; channel < rxRuntimeConfig.channelCount; channel++) { rcData[channel] = getRxfailValue(channel); } } #ifdef DEBUG_RX_SIGNAL_LOSS debug[3] = rcData[THROTTLE]; #endif }