Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to RX/RC mode handling code #3363

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/fc/rc_controls.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

#define AIRMODE_DEADBAND 25
#define MIN_RC_TICK_INTERVAL_MS 20
#define DEFAULT_RC_SWITCH_DISARM_DELAY_MS 150 // Wait at least 150ms before disarming via switch
#define DEFAULT_RC_SWITCH_DISARM_DELAY_MS 250 // Wait at least 250ms before disarming via switch

stickPositions_e rcStickPositions;

Expand Down
21 changes: 15 additions & 6 deletions src/main/fc/rc_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,24 @@ void updateActivatedModes(void)
// For AND logic, the specified condition count and valid condition count must be the same.
// For OR logic, the valid condition count must be greater than zero.

if (modeActivationOperatorConfig()->modeActivationOperator == MODE_OPERATOR_AND) {
// AND the conditions
if (activeConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) {
bitArraySet(newMask.bits, modeIndex);
// Prohibit BOX mode change alltogether if RX link is not stable enough
if (rxIsSignalStable() || modeIndex == BOXFAILSAFE) {
if (modeActivationOperatorConfig()->modeActivationOperator == MODE_OPERATOR_AND) {
// AND the conditions
if (activeConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) {
bitArraySet(newMask.bits, modeIndex);
}
}
else {
// OR the conditions
if (activeConditionCountPerMode[modeIndex] > 0) {
bitArraySet(newMask.bits, modeIndex);
}
}
}
else {
// OR the conditions
if (activeConditionCountPerMode[modeIndex] > 0) {
// Retail current mode state
if (bitArrayGet(rcModeActivationMask.bits, modeIndex)) {
bitArraySet(newMask.bits, modeIndex);
}
}
Expand Down
22 changes: 19 additions & 3 deletions src/main/rx/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ static rssiSource_e rssiSource;
static bool rxDataProcessingRequired = false;
static bool auxiliaryProcessingRequired = false;

static uint32_t rxValidFramesCount = 0;
static bool rxSignalReceived = false;
static bool rxFlightChannelsValid = false;
static bool rxIsInFailsafeMode = true;
Expand All @@ -92,7 +93,8 @@ int16_t rcRaw[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
uint32_t rcInvalidPulsPeriod[MAX_SUPPORTED_RC_CHANNEL_COUNT];

#define MAX_INVALID_PULS_TIME 300
#define FILTERING_SAMPLE_COUNT 5
#define MAX_INVALID_PULS_TIME 300

#define SKIP_RC_ON_SUSPEND_PERIOD 1500000 // 1.5 second period in usec (call frequency independent)
#define SKIP_RC_SAMPLES_ON_RESUME 2 // flush 2 samples to drop wrong measurements (timing independent)
Expand Down Expand Up @@ -364,6 +366,12 @@ bool rxIsReceivingSignal(void)
return rxSignalReceived;
}

bool rxIsSignalStable(void)
{
// Filtering may delay the channel values up to FILTERING_SAMPLE_COUNT in worst case
return rxIsReceivingSignal() && (rxValidFramesCount >= (rxRuntimeConfig.requireFiltering ? FILTERING_SAMPLE_COUNT : 1));
}

bool rxAreFlightChannelsValid(void)
{
return rxFlightChannelsValid;
Expand Down Expand Up @@ -432,7 +440,6 @@ bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTime)
return rxDataProcessingRequired || auxiliaryProcessingRequired; // data driven or 50Hz
}

#define FILTERING_SAMPLE_COUNT 5
static uint16_t applyChannelFiltering(uint8_t chan, uint16_t sample)
{
static int16_t rcSamples[MAX_SUPPORTED_RC_CHANNEL_COUNT][FILTERING_SAMPLE_COUNT];
Expand Down Expand Up @@ -482,6 +489,15 @@ void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs)
rxDataProcessingRequired = false;
rxNextUpdateAtUs = currentTimeUs + DELAY_50_HZ;

// We got here, that means we have received a valid frame (or a frame timeout)
// If we are receiving signal increase valid frame count (used as a consistency measurement)
if (rxSignalReceived) {
rxValidFramesCount++;
}
else {
rxValidFramesCount = 0;
}

// only proceed when no more samples to skip and suspend period is over
if (skipRxSamples) {
if (currentTimeUs > suspendRxSignalUntil) {
Expand All @@ -492,7 +508,7 @@ void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs)
}

rxFlightChannelsValid = true;

// Read and process channel data
for (int channel = 0; channel < rxRuntimeConfig.channelCount; channel++) {
const uint8_t rawChannel = calculateChannelRemapping(rxConfig()->rcmap, REMAPPABLE_CHANNEL_COUNT, channel);
Expand Down
1 change: 1 addition & 0 deletions src/main/rx/rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ extern rxRuntimeConfig_t rxRuntimeConfig; //!!TODO remove this extern, only need
void rxInit(void);
void rxUpdateRSSISource(void);
bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTime);
bool rxIsSignalStable(void);
bool rxIsReceivingSignal(void);
bool rxAreFlightChannelsValid(void);
void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs);
Expand Down