static void detectAndApplySignalLossBehaviour(void) { int channel; rxResetFlightChannelStatus(); for (channel = 0; channel < rxRuntimeConfig.channelCount; channel++) { uint16_t sample = rcRaw[channel]; if (!rxSignalReceived) { if (isRxDataDriven() && rxDataReceived) { // use the values from the RX } else { sample = PPM_RCVR_TIMEOUT; } } bool validPulse = isPulseValid(sample); if (!validPulse) { sample = getRxfailValue(channel); } rxUpdateFlightChannelStatus(channel, validPulse); if (isRxDataDriven()) { 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); } } }
void calculateRxChannelsAndUpdateFailsafe(uint32_t currentTime) { rxUpdateAt = currentTime + DELAY_50_HZ; failsafeOnRxCycleStarted(); if (isRxDataDriven()) { processDataDrivenRx(); } else { processNonDataDrivenRx(); } }
void updateRx(uint32_t currentTime) { resetRxSignalReceivedFlagIfNeeded(currentTime); if (isRxDataDriven()) { rxDataReceived = false; } #ifdef SERIAL_RX if (feature(FEATURE_RX_SERIAL)) { uint8_t frameStatus = serialRxFrameStatus(); if (frameStatus & SERIAL_RX_FRAME_COMPLETE) { rxDataReceived = true; rxIsInFailsafeMode = (frameStatus & SERIAL_RX_FRAME_FAILSAFE) != 0; rxSignalReceived = !rxIsInFailsafeMode; needRxSignalBefore = currentTime + DELAY_10_HZ; } } #endif if (feature(FEATURE_RX_MSP)) { rxDataReceived = rxMspFrameComplete(); if (rxDataReceived) { rxSignalReceived = true; rxIsInFailsafeMode = false; needRxSignalBefore = currentTime + DELAY_5_HZ; } } if (feature(FEATURE_RX_PPM)) { if (isPPMDataBeingReceived()) { rxSignalReceivedNotDataDriven = true; rxIsInFailsafeModeNotDataDriven = false; needRxSignalBefore = currentTime + DELAY_10_HZ; resetPPMDataReceivedState(); } } if (feature(FEATURE_RX_PARALLEL_PWM)) { if (isPWMDataBeingReceived()) { rxSignalReceivedNotDataDriven = true; rxIsInFailsafeModeNotDataDriven = false; needRxSignalBefore = currentTime + DELAY_10_HZ; } } }
static void processRxChannels(void) { uint8_t chan; if (feature(FEATURE_RX_MSP)) { return; // rcData will have already been updated by MSP_SET_RAW_RC } rxPwmFlightChannelsAreGood = false; for (chan = 0; chan < rxRuntimeConfig.channelCount; chan++) { if (!rcReadRawFunc) { rcData[chan] = getRxfailValue(chan); continue; } uint8_t rawChannel = calculateChannelRemapping(rxConfig->rcmap, REMAPPABLE_CHANNEL_COUNT, chan); // sample the channel uint16_t sample = rcReadRawFunc(&rxRuntimeConfig, rawChannel); if (shouldCheckPulse) { rxCheckPulse(chan, sample); } // validate the range and check if rx signal is received if (sample < rxConfig->rx_min_usec || sample > rxConfig->rx_max_usec || !rxSignalReceived) { sample = getRxfailValue(chan); } if (isRxDataDriven()) { rcData[chan] = sample; } else { rcData[chan] = calculateNonDataDrivenChannel(chan, sample); } } // Using PARALLEL PWM and one of the 4 control channels is out of range: // Probably one of the cables came loose, all channels are set to rxfail values if ((rxPwmFlightChannelsAreGood == false) && feature(FEATURE_RX_PARALLEL_PWM)) { for (chan = 0; chan < rxRuntimeConfig.channelCount; chan++) { rcData[chan] = getRxfailValue(chan); } } }
void calculateRxChannelsAndUpdateFailsafe(uint32_t currentTime) { rxUpdateAt = currentTime + DELAY_50_HZ; if (!feature(FEATURE_RX_MSP)) { // rcData will have already been updated by MSP_SET_RAW_RC if (!isRxDataDriven()) { processNonDataDrivenRx(); } } // only proceed when no more samples to skip and suspend period is over if (skipRxSamples) { if (currentTime > suspendRxSignalUntil) { skipRxSamples--; } return; } readRxChannelsApplyRanges(); detectAndApplySignalLossBehaviour(); }
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 }
bool updateRx(timeUs_t currentTimeUs) { resetRxSignalReceivedFlagIfNeeded(currentTimeUs); if (isRxDataDriven()) { rxDataReceived = false; } #ifdef SERIAL_RX if (feature(FEATURE_RX_SERIAL)) { const uint8_t frameStatus = serialRxFrameStatus(rxConfig); if (frameStatus & RX_FRAME_COMPLETE) { rxDataReceived = true; rxIsInFailsafeMode = (frameStatus & RX_FRAME_FAILSAFE) != 0; rxSignalReceived = !rxIsInFailsafeMode; needRxSignalBefore = currentTimeUs + DELAY_10_HZ; } } #endif #ifdef USE_RX_SPI if (feature(FEATURE_RX_SPI)) { const uint8_t frameStatus = rxRuntimeConfig.rcFrameStatusFn(); if (frameStatus & RX_FRAME_COMPLETE) { rxDataReceived = true; rxIsInFailsafeMode = false; rxSignalReceived = !rxIsInFailsafeMode; needRxSignalBefore = currentTimeUs + DELAY_5_HZ; } } #endif #ifndef SKIP_RX_MSP if (feature(FEATURE_RX_MSP)) { const uint8_t frameStatus = rxMspFrameStatus(); if (frameStatus & RX_FRAME_COMPLETE) { rxDataReceived = true; rxIsInFailsafeMode = false; rxSignalReceived = !rxIsInFailsafeMode; needRxSignalBefore = currentTimeUs + DELAY_5_HZ; } } #endif #ifndef SKIP_RX_PWM_PPM if (feature(FEATURE_RX_PPM)) { if (isPPMDataBeingReceived()) { rxSignalReceivedNotDataDriven = true; rxIsInFailsafeModeNotDataDriven = false; needRxSignalBefore = currentTimeUs + DELAY_10_HZ; resetPPMDataReceivedState(); } } if (feature(FEATURE_RX_PARALLEL_PWM)) { if (isPWMDataBeingReceived()) { rxSignalReceivedNotDataDriven = true; rxIsInFailsafeModeNotDataDriven = false; needRxSignalBefore = currentTimeUs + DELAY_10_HZ; } } #endif return rxDataReceived || ((int32_t)(currentTimeUs - rxUpdateAt) >= 0); // data driven or 50Hz }