mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-17 13:25:30 +03:00
Tidy RX failsafe code
This commit is contained in:
parent
52c629751c
commit
5cd6627fb2
2 changed files with 27 additions and 72 deletions
|
@ -79,10 +79,8 @@ static bool rxDataProcessingRequired = false;
|
||||||
static bool auxiliaryProcessingRequired = false;
|
static bool auxiliaryProcessingRequired = false;
|
||||||
|
|
||||||
static bool rxSignalReceived = false;
|
static bool rxSignalReceived = false;
|
||||||
static bool rxSignalReceivedNotDataDriven = false;
|
|
||||||
static bool rxFlightChannelsValid = false;
|
static bool rxFlightChannelsValid = false;
|
||||||
static bool rxIsInFailsafeMode = true;
|
static bool rxIsInFailsafeMode = true;
|
||||||
static bool rxIsInFailsafeModeNotDataDriven = true;
|
|
||||||
static uint8_t rxChannelCount;
|
static uint8_t rxChannelCount;
|
||||||
|
|
||||||
static timeUs_t rxNextUpdateAtUs = 0;
|
static timeUs_t rxNextUpdateAtUs = 0;
|
||||||
|
@ -213,34 +211,12 @@ static bool nullProcessFrame(const rxRuntimeConfig_t *rxRuntimeConfig)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REQUIRED_CHANNEL_MASK 0x0F // first 4 channels
|
|
||||||
|
|
||||||
static uint8_t validFlightChannelMask;
|
|
||||||
|
|
||||||
STATIC_UNIT_TESTED void rxResetFlightChannelStatus(void) {
|
|
||||||
validFlightChannelMask = REQUIRED_CHANNEL_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC_UNIT_TESTED bool rxHaveValidFlightChannels(void)
|
|
||||||
{
|
|
||||||
return (validFlightChannelMask == REQUIRED_CHANNEL_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC_UNIT_TESTED bool isPulseValid(uint16_t pulseDuration)
|
STATIC_UNIT_TESTED bool isPulseValid(uint16_t pulseDuration)
|
||||||
{
|
{
|
||||||
return pulseDuration >= rxConfig()->rx_min_usec &&
|
return pulseDuration >= rxConfig()->rx_min_usec &&
|
||||||
pulseDuration <= rxConfig()->rx_max_usec;
|
pulseDuration <= rxConfig()->rx_max_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pulse duration is in micro seconds (usec)
|
|
||||||
STATIC_UNIT_TESTED void rxUpdateFlightChannelStatus(uint8_t channel, bool valid)
|
|
||||||
{
|
|
||||||
if (channel < NON_AUX_CHANNEL_COUNT && !valid) {
|
|
||||||
// if signal is invalid - mark channel as BAD
|
|
||||||
validFlightChannelMask &= ~(1 << channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_SERIAL_RX
|
#ifdef USE_SERIAL_RX
|
||||||
bool serialRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
|
bool serialRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
|
||||||
{
|
{
|
||||||
|
@ -396,11 +372,6 @@ bool rxAreFlightChannelsValid(void)
|
||||||
return rxFlightChannelsValid;
|
return rxFlightChannelsValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isRxDataDriven(void)
|
|
||||||
{
|
|
||||||
return !(feature(FEATURE_RX_PARALLEL_PWM | FEATURE_RX_PPM));
|
|
||||||
}
|
|
||||||
|
|
||||||
void suspendRxSignal(void)
|
void suspendRxSignal(void)
|
||||||
{
|
{
|
||||||
suspendRxSignalUntil = micros() + SKIP_RC_ON_SUSPEND_PERIOD;
|
suspendRxSignalUntil = micros() + SKIP_RC_ON_SUSPEND_PERIOD;
|
||||||
|
@ -422,22 +393,21 @@ bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTime)
|
||||||
if (rxSignalReceived) {
|
if (rxSignalReceived) {
|
||||||
if (currentTimeUs >= needRxSignalBefore) {
|
if (currentTimeUs >= needRxSignalBefore) {
|
||||||
rxSignalReceived = false;
|
rxSignalReceived = false;
|
||||||
rxSignalReceivedNotDataDriven = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_PWM) || defined(USE_PPM)
|
#if defined(USE_PWM) || defined(USE_PPM)
|
||||||
if (feature(FEATURE_RX_PPM)) {
|
if (feature(FEATURE_RX_PPM)) {
|
||||||
if (isPPMDataBeingReceived()) {
|
if (isPPMDataBeingReceived()) {
|
||||||
rxSignalReceivedNotDataDriven = true;
|
rxSignalReceived = true;
|
||||||
rxIsInFailsafeModeNotDataDriven = false;
|
rxIsInFailsafeMode = false;
|
||||||
needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs;
|
needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs;
|
||||||
resetPPMDataReceivedState();
|
resetPPMDataReceivedState();
|
||||||
}
|
}
|
||||||
} else if (feature(FEATURE_RX_PARALLEL_PWM)) {
|
} else if (feature(FEATURE_RX_PARALLEL_PWM)) {
|
||||||
if (isPWMDataBeingReceived()) {
|
if (isPWMDataBeingReceived()) {
|
||||||
rxSignalReceivedNotDataDriven = true;
|
rxSignalReceived = true;
|
||||||
rxIsInFailsafeModeNotDataDriven = false;
|
rxIsInFailsafeMode = false;
|
||||||
needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs;
|
needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -546,20 +516,11 @@ static void readRxChannelsApplyRanges(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void detectAndApplySignalLossBehaviour(timeUs_t currentTimeUs)
|
static void detectAndApplySignalLossBehaviour(void)
|
||||||
{
|
{
|
||||||
bool useValueFromRx = true;
|
const uint32_t currentTimeMs = millis();
|
||||||
const bool rxIsDataDriven = isRxDataDriven();
|
|
||||||
const uint32_t currentTimeMs = currentTimeUs / 1000;
|
|
||||||
|
|
||||||
if (!rxIsDataDriven) {
|
const bool useValueFromRx = rxSignalReceived && !rxIsInFailsafeMode;
|
||||||
rxSignalReceived = rxSignalReceivedNotDataDriven;
|
|
||||||
rxIsInFailsafeMode = rxIsInFailsafeModeNotDataDriven;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rxSignalReceived || rxIsInFailsafeMode) {
|
|
||||||
useValueFromRx = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_RX_SIGNAL_LOSS
|
#ifdef DEBUG_RX_SIGNAL_LOSS
|
||||||
debug[0] = rxSignalReceived;
|
debug[0] = rxSignalReceived;
|
||||||
|
@ -567,41 +528,37 @@ static void detectAndApplySignalLossBehaviour(timeUs_t currentTimeUs)
|
||||||
debug[2] = rxRuntimeConfig.rcReadRawFn(&rxRuntimeConfig, 0);
|
debug[2] = rxRuntimeConfig.rcReadRawFn(&rxRuntimeConfig, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rxResetFlightChannelStatus();
|
rxFlightChannelsValid = true;
|
||||||
|
|
||||||
for (int channel = 0; channel < rxChannelCount; channel++) {
|
for (int channel = 0; channel < rxChannelCount; channel++) {
|
||||||
|
uint16_t sample = rcRaw[channel];
|
||||||
|
|
||||||
uint16_t sample = (useValueFromRx) ? rcRaw[channel] : PPM_RCVR_TIMEOUT;
|
const bool validPulse = useValueFromRx && isPulseValid(sample);
|
||||||
|
|
||||||
bool validPulse = isPulseValid(sample);
|
if (validPulse) {
|
||||||
|
rcInvalidPulsPeriod[channel] = currentTimeMs + MAX_INVALID_PULS_TIME;
|
||||||
if (!validPulse) {
|
} else {
|
||||||
if (currentTimeMs < rcInvalidPulsPeriod[channel]) {
|
if (cmp32(currentTimeMs, rcInvalidPulsPeriod[channel]) < 0) {
|
||||||
sample = rcData[channel]; // hold channel for MAX_INVALID_PULS_TIME
|
continue; // skip to next channel to hold channel value MAX_INVALID_PULS_TIME
|
||||||
} else {
|
} else {
|
||||||
sample = getRxfailValue(channel); // after that apply rxfail value
|
sample = getRxfailValue(channel); // after that apply rxfail value
|
||||||
rxUpdateFlightChannelStatus(channel, validPulse);
|
if (channel < NON_AUX_CHANNEL_COUNT) {
|
||||||
|
rxFlightChannelsValid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
rcInvalidPulsPeriod[channel] = currentTimeMs + MAX_INVALID_PULS_TIME;
|
|
||||||
}
|
}
|
||||||
|
if (feature(FEATURE_RX_PARALLEL_PWM | FEATURE_RX_PPM)) {
|
||||||
if (rxIsDataDriven) {
|
|
||||||
rcData[channel] = sample;
|
|
||||||
} else {
|
|
||||||
// smooth output for PWM and PPM
|
// smooth output for PWM and PPM
|
||||||
rcData[channel] = calculateChannelMovingAverage(channel, sample);
|
rcData[channel] = calculateChannelMovingAverage(channel, sample);
|
||||||
|
} else {
|
||||||
|
rcData[channel] = sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rxFlightChannelsValid = rxHaveValidFlightChannels();
|
if (rxFlightChannelsValid && !IS_RC_MODE_ACTIVE(BOXFAILSAFE)) {
|
||||||
|
|
||||||
if ((rxFlightChannelsValid) && !IS_RC_MODE_ACTIVE(BOXFAILSAFE)) {
|
|
||||||
failsafeOnValidDataReceived();
|
failsafeOnValidDataReceived();
|
||||||
} else {
|
} else {
|
||||||
rxIsInFailsafeMode = rxIsInFailsafeModeNotDataDriven = true;
|
rxIsInFailsafeMode = true;
|
||||||
failsafeOnValidDataFailed();
|
failsafeOnValidDataFailed();
|
||||||
|
|
||||||
for (int channel = 0; channel < rxChannelCount; channel++) {
|
for (int channel = 0; channel < rxChannelCount; channel++) {
|
||||||
rcData[channel] = getRxfailValue(channel);
|
rcData[channel] = getRxfailValue(channel);
|
||||||
}
|
}
|
||||||
|
@ -635,7 +592,7 @@ bool calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs)
|
||||||
}
|
}
|
||||||
|
|
||||||
readRxChannelsApplyRanges();
|
readRxChannelsApplyRanges();
|
||||||
detectAndApplySignalLossBehaviour(currentTimeUs);
|
detectAndApplySignalLossBehaviour();
|
||||||
|
|
||||||
rcSampleIndex++;
|
rcSampleIndex++;
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,7 @@ extern "C" {
|
||||||
|
|
||||||
boxBitmask_t rcModeActivationMask;
|
boxBitmask_t rcModeActivationMask;
|
||||||
|
|
||||||
void rxResetFlightChannelStatus(void);
|
|
||||||
bool rxHaveValidFlightChannels(void);
|
|
||||||
bool isPulseValid(uint16_t pulseDuration);
|
bool isPulseValid(uint16_t pulseDuration);
|
||||||
void rxUpdateFlightChannelStatus(uint8_t channel, uint16_t pulseDuration);
|
|
||||||
|
|
||||||
PG_RESET_TEMPLATE(featureConfig_t, featureConfig,
|
PG_RESET_TEMPLATE(featureConfig_t, featureConfig,
|
||||||
.enabledFeatures = 0
|
.enabledFeatures = 0
|
||||||
|
@ -57,7 +54,8 @@ typedef struct testData_s {
|
||||||
|
|
||||||
static testData_t testData;
|
static testData_t testData;
|
||||||
|
|
||||||
TEST(RxTest, TestValidFlightChannelsLowArm)
|
#if 0 //!! valid pulse handling has changed so these test now test removed functions
|
||||||
|
TEST(RxTest, TestValidFlightChannels)
|
||||||
{
|
{
|
||||||
// given
|
// given
|
||||||
memset(&testData, 0, sizeof(testData));
|
memset(&testData, 0, sizeof(testData));
|
||||||
|
@ -189,7 +187,7 @@ TEST(RxTest, TestInvalidFlightChannels)
|
||||||
EXPECT_FALSE(rxHaveValidFlightChannels());
|
EXPECT_FALSE(rxHaveValidFlightChannels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// STUBS
|
// STUBS
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue