diff --git a/docs/Rx.md b/docs/Rx.md index a2f6511fe..a331e7dcf 100644 --- a/docs/Rx.md +++ b/docs/Rx.md @@ -144,13 +144,14 @@ Signal loss can be detected when: ### RX loss configuration The `rxfail` cli command is used to configure per-channel rx-loss behaviour. -You can use the `rxfail` command to change this behaviour, a channel can either be AUTOMATIC, HOLD or SET. +You can use the `rxfail` command to change this behaviour. +A flight channel can either be AUTOMATIC or HOLD, an AUX channel can either be SET or HOLD. -* AUTOMATIC - Flight channels are set to safe values (low throttle, mid position for yaw/pitch/roll), all AUX channels HOLD last value. +* AUTOMATIC - Flight channels are set to safe values (low throttle, mid position for yaw/pitch/roll). * HOLD - Channel holds the last value. * SET - Channel is set to a specific configured value. -The default mode for all channels is AUTOMATIC. +The default mode is AUTOMATIC for flight channels and HOLD for AUX channels. The rxfail command can be used in conjunction with mode ranges to trigger various actions. @@ -232,8 +233,12 @@ Set the RX for 'No Pulses'. Turn OFF TX and RX, Turn ON RX. Press and release ### Graupner GR-24 PWM -Set failsafe on channels 1-4 set to OFF in the receiver settings (via transmitter menu). +Set failsafe on the throttle channel in the receiver settings (via transmitter menu) to a value below `rx_min_usec` using channel mode FAILSAFE. +This is the prefered way, since this is *much faster* detected by the FC then a channel that sends no pulses (OFF). +__NOTE:__ +One or more control channels may be set to OFF to signal a failsafe condition to the FC, all other channels *must* be set to either HOLD or OFF. +Do __NOT USE__ the mode indicated with FAILSAFE instead, as this combination is NOT handled correctly by the FC. ## Receiver Channel Range Configuration. diff --git a/src/main/config/config.c b/src/main/config/config.c index 6764ad4ab..61ef67744 100755 --- a/src/main/config/config.c +++ b/src/main/config/config.c @@ -407,8 +407,8 @@ static void resetConf(void) for (i = 0; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) { rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &masterConfig.rxConfig.failsafe_channel_configurations[i]; - channelFailsafeConfiguration->mode = RX_FAILSAFE_MODE_AUTO; - channelFailsafeConfiguration->step = CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.midrc); + channelFailsafeConfiguration->mode = (i < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_MODE_AUTO : RX_FAILSAFE_MODE_HOLD; + channelFailsafeConfiguration->step = (i == THROTTLE) ? masterConfig.rxConfig.rx_min_usec : CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.midrc); } masterConfig.rxConfig.rssi_channel = 0; diff --git a/src/main/io/serial_cli.c b/src/main/io/serial_cli.c index eddbf960a..1e738a282 100644 --- a/src/main/io/serial_cli.c +++ b/src/main/io/serial_cli.c @@ -170,7 +170,12 @@ static const char * const featureNames[] = { }; // sync this with rxFailsafeChannelMode_e -static char rxFailsafeModes[RX_FAILSAFE_MODE_COUNT] = { 'a', 'h', 's'}; +static const char rxFailsafeModeCharacters[] = "ahs"; + +static const rxFailsafeChannelMode_e rxFailsafeModesTable[RX_FAILSAFE_TYPE_COUNT][RX_FAILSAFE_MODE_COUNT] = { + { RX_FAILSAFE_MODE_AUTO, RX_FAILSAFE_MODE_HOLD, RX_FAILSAFE_MODE_INVALID }, + { RX_FAILSAFE_MODE_INVALID, RX_FAILSAFE_MODE_HOLD, RX_FAILSAFE_MODE_SET } +}; #ifndef CJMCU // sync this with sensors_e @@ -587,27 +592,22 @@ static void cliRxFail(char *cmdline) rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &masterConfig.rxConfig.failsafe_channel_configurations[channel]; uint16_t value; + rxFailsafeChannelType_e type = (channel < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_TYPE_FLIGHT : RX_FAILSAFE_TYPE_AUX; rxFailsafeChannelMode_e mode = channelFailsafeConfiguration->mode; bool requireValue = channelFailsafeConfiguration->mode == RX_FAILSAFE_MODE_SET; - // TODO optimize to use rxFailsafeModes - less logic. ptr = strchr(ptr, ' '); if (ptr) { - switch (*(++ptr)) { - case 'a': - mode = RX_FAILSAFE_MODE_AUTO; - break; - - case 'h': - mode = RX_FAILSAFE_MODE_HOLD; - break; - - case 's': - mode = RX_FAILSAFE_MODE_SET; - break; - default: - cliShowParseError(); - return; + char *p = strchr(rxFailsafeModeCharacters, *(++ptr)); + if (p) { + uint8_t requestedMode = p - rxFailsafeModeCharacters; + mode = rxFailsafeModesTable[type][requestedMode]; + } else { + mode = RX_FAILSAFE_MODE_INVALID; + } + if (mode == RX_FAILSAFE_MODE_INVALID) { + cliShowParseError(); + return; } requireValue = mode == RX_FAILSAFE_MODE_SET; @@ -626,12 +626,15 @@ static void cliRxFail(char *cmdline) } channelFailsafeConfiguration->step = value; + } else if (requireValue) { + cliShowParseError(); + return; } channelFailsafeConfiguration->mode = mode; } - char modeCharacter = rxFailsafeModes[channelFailsafeConfiguration->mode]; + char modeCharacter = rxFailsafeModeCharacters[channelFailsafeConfiguration->mode]; // triple use of printf below // 1. acknowledge interpretation on command, diff --git a/src/main/rx/rx.c b/src/main/rx/rx.c index 78016c43b..6a74de89d 100644 --- a/src/main/rx/rx.c +++ b/src/main/rx/rx.c @@ -346,27 +346,29 @@ static uint16_t getRxfailValue(uint8_t channel) rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &rxConfig->failsafe_channel_configurations[channel]; switch(channelFailsafeConfiguration->mode) { - default: case RX_FAILSAFE_MODE_AUTO: switch (channel) { case ROLL: case PITCH: case YAW: return rxConfig->midrc; + case THROTTLE: if (feature(FEATURE_3D)) return rxConfig->midrc; else return rxConfig->rx_min_usec; } - // fall though to HOLD if there's nothing specific to do. + /* no break */ + + default: + case RX_FAILSAFE_MODE_INVALID: case RX_FAILSAFE_MODE_HOLD: return rcData[channel]; case RX_FAILSAFE_MODE_SET: return RXFAIL_STEP_TO_CHANNEL_VALUE(channelFailsafeConfiguration->step); } - } STATIC_UNIT_TESTED uint16_t applyRxChannelRangeConfiguraton(int sample, rxChannelRangeConfiguration_t range) diff --git a/src/main/rx/rx.h b/src/main/rx/rx.h index 7ab45f106..c35b3d10c 100644 --- a/src/main/rx/rx.h +++ b/src/main/rx/rx.h @@ -85,10 +85,18 @@ typedef enum { RX_FAILSAFE_MODE_AUTO = 0, RX_FAILSAFE_MODE_HOLD, RX_FAILSAFE_MODE_SET, + RX_FAILSAFE_MODE_INVALID, } rxFailsafeChannelMode_e; #define RX_FAILSAFE_MODE_COUNT 3 +typedef enum { + RX_FAILSAFE_TYPE_FLIGHT = 0, + RX_FAILSAFE_TYPE_AUX, +} rxFailsafeChannelType_e; + +#define RX_FAILSAFE_TYPE_COUNT 2 + typedef struct rxFailsafeChannelConfiguration_s { uint8_t mode; // See rxFailsafeChannelMode_e uint8_t step;