2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "common/time.h"
24 #include "common/tristate.h"
26 #include "config/parameter_group.h"
28 #define STICK_CHANNEL_COUNT 4
30 #define PWM_RANGE_MIN 1000
31 #define PWM_RANGE_MAX 2000
32 #define PWM_RANGE_MIDDLE (PWM_RANGE_MIN + ((PWM_RANGE_MAX - PWM_RANGE_MIN) / 2))
34 #define PWM_PULSE_MIN 750 // minimum PWM pulse width which is considered valid
35 #define PWM_PULSE_MAX 2250 // maximum PWM pulse width which is considered valid
37 #define MIDRC_MIN 1200
38 #define MIDRC_MAX 1700
40 #define RXFAIL_STEP_TO_CHANNEL_VALUE(step) (PWM_PULSE_MIN + 25 * step)
41 #define CHANNEL_VALUE_TO_RXFAIL_STEP(channelValue) ((constrain(channelValue, PWM_PULSE_MIN, PWM_PULSE_MAX) - PWM_PULSE_MIN) / 25)
42 #define MAX_RXFAIL_RANGE_STEP ((PWM_PULSE_MAX - PWM_PULSE_MIN) / 25)
44 #define DEFAULT_SERVO_MIN 1000
45 #define DEFAULT_SERVO_MIDDLE 1500
46 #define DEFAULT_SERVO_MAX 2000
48 #define DELAY_50_HZ (1000000 / 50)
49 #define DELAY_10_HZ (1000000 / 10)
50 #define DELAY_5_HZ (1000000 / 5)
52 #define RSSI_MAX_VALUE 1023
55 RX_FRAME_PENDING
= 0, // No new data available from receiver
56 RX_FRAME_COMPLETE
= (1 << 0), // There is new data available
57 RX_FRAME_FAILSAFE
= (1 << 1), // Receiver detected loss of RC link. Only valid when RX_FRAME_COMPLETE is set as well
58 RX_FRAME_PROCESSING_REQUIRED
= (1 << 2),
59 RX_FRAME_DROPPED
= (1 << 3), // Receiver detected dropped frame. Not loss of link yet.
70 SERIALRX_SPEKTRUM1024
= 0,
71 SERIALRX_SPEKTRUM2048
,
85 } rxSerialReceiverType_e
;
87 #define MAX_SUPPORTED_RC_CHANNEL_COUNT 34
89 #define NON_AUX_CHANNEL_COUNT 4
90 #define MAX_AUX_CHANNEL_COUNT (MAX_SUPPORTED_RC_CHANNEL_COUNT - NON_AUX_CHANNEL_COUNT)
92 extern const char rcChannelLetters
[];
94 #define MAX_MAPPABLE_RX_INPUTS 4
96 #define MAX_INVALID_RX_PULSE_TIME 300
98 #define RSSI_VISIBLE_VALUE_MIN 0
99 #define RSSI_VISIBLE_VALUE_MAX 100
100 #define RSSI_VISIBLE_FACTOR (RSSI_MAX_VALUE/(float)RSSI_VISIBLE_VALUE_MAX)
102 typedef struct rxChannelRangeConfig_s
{
105 } rxChannelRangeConfig_t
;
106 PG_DECLARE_ARRAY(rxChannelRangeConfig_t
, NON_AUX_CHANNEL_COUNT
, rxChannelRangeConfigs
);
108 typedef struct rxConfig_s
{
109 uint8_t receiverType
; // RC receiver type (rxReceiverType_e enum)
110 uint8_t rcmap
[MAX_MAPPABLE_RX_INPUTS
]; // mapping of radio channels to internal RPYTA+ order
111 uint8_t serialrx_provider
; // Type of UART-based receiver (rxSerialReceiverType_e enum). Only used if receiverType is RX_TYPE_SERIAL
112 uint8_t serialrx_inverted
; // Flip the default inversion of the protocol - e.g. sbus (Futaba, FrSKY) is inverted if this is false, uninverted if it's true. Support for uninverted OpenLRS (and modified FrSKY) receivers.
113 uint8_t halfDuplex
; // allow rx to operate in half duplex mode. From tristate_e.
114 #ifdef USE_SPEKTRUM_BIND
115 uint8_t spektrum_sat_bind
; // number of bind pulses for Spektrum satellite receivers
116 uint8_t spektrum_sat_bind_autoreset
; // whenever we will reset (exit) binding mode after hard reboot
118 uint8_t rssi_channel
;
119 uint8_t rssiMin
; // minimum RSSI sent by the RX - [RSSI_VISIBLE_VALUE_MIN, RSSI_VISIBLE_VALUE_MAX]
120 uint8_t rssiMax
; // maximum RSSI sent by the RX - [RSSI_VISIBLE_VALUE_MIN, RSSI_VISIBLE_VALUE_MAX]
121 uint16_t sbusSyncInterval
;
122 uint16_t mincheck
; // minimum rc end
123 uint16_t maxcheck
; // maximum rc end
124 uint16_t rx_min_usec
;
125 uint16_t rx_max_usec
;
126 uint8_t rcFilterFrequency
; // RC filter cutoff frequency (smoothness vs response sharpness)
127 uint8_t autoSmooth
; // auto smooth rx input (0 = off, 1 = on)
128 uint8_t autoSmoothFactor
; // auto smooth rx input factor (1 = no smoothing, 100 = lots of smoothing)
129 uint16_t mspOverrideChannels
; // Channels to override with MSP RC when BOXMSPRCOVERRIDE is active
131 #ifdef USE_SERIALRX_SRXL2
132 uint8_t srxl2_unit_id
;
133 uint8_t srxl2_baud_fast
;
137 PG_DECLARE(rxConfig_t
, rxConfig
);
139 #define REMAPPABLE_CHANNEL_COUNT ARRAYLEN(((rxConfig_t *)0)->rcmap)
141 typedef struct rxLinkQualityTracker_s
{
142 timeMs_t lastUpdatedMs
;
143 uint32_t lqAccumulator
;
146 } rxLinkQualityTracker_e
;
149 struct rxRuntimeConfig_s
;
150 typedef struct rxRuntimeConfig_s rxRuntimeConfig_t
;
152 typedef uint16_t (*rcReadRawDataFnPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
, uint8_t chan
); // used by receiver driver to return channel data
153 typedef uint8_t (*rcFrameStatusFnPtr
)(rxRuntimeConfig_t
*rxRuntimeConfig
);
154 typedef bool (*rcProcessFrameFnPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
);
155 typedef uint16_t (*rcGetLinkQualityPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
);
157 typedef struct rxRuntimeConfig_s
{
158 uint8_t channelCount
; // number of rc channels as reported by current input driver
159 timeUs_t rxSignalTimeout
;
160 rcReadRawDataFnPtr rcReadRawFn
;
161 rcFrameStatusFnPtr rcFrameStatusFn
;
162 rcProcessFrameFnPtr rcProcessFrameFn
;
163 rxLinkQualityTracker_e
* lqTracker
; // Pointer to a
164 uint16_t *channelData
;
168 typedef struct rcChannel_s
{
169 int16_t raw
; // Value received via RX - [1000;2000]
170 int16_t data
; // Value after processing - [1000;2000]
171 timeMs_t expiresAt
; // Time when this value becomes too old and it's discarded
175 RSSI_SOURCE_NONE
= 0,
178 RSSI_SOURCE_RX_CHANNEL
,
179 RSSI_SOURCE_RX_PROTOCOL
,
183 typedef struct rxLinkStatistics_s
{
184 int16_t uplinkRSSI
; // RSSI value in dBm
185 uint8_t uplinkLQ
; // A protocol specific measure of the link quality in [0..100]
186 int8_t uplinkSNR
; // The SNR of the uplink in dB
187 uint8_t rfMode
; // A protocol specific measure of the transmission bandwidth [2 = 150Hz, 1 = 50Hz, 0 = 4Hz]
188 uint16_t uplinkTXPower
; // power in mW
189 uint8_t activeAntenna
;
190 } rxLinkStatistics_t
;
192 typedef uint16_t (*rcReadRawDataFnPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
, uint8_t chan
); // used by receiver driver to return channel data
193 typedef uint8_t (*rcFrameStatusFnPtr
)(rxRuntimeConfig_t
*rxRuntimeConfig
);
194 typedef bool (*rcProcessFrameFnPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
);
195 typedef uint16_t (*rcGetLinkQualityPtr
)(const rxRuntimeConfig_t
*rxRuntimeConfig
);
197 extern rxRuntimeConfig_t rxRuntimeConfig
; //!!TODO remove this extern, only needed once for channelCount
198 extern rxLinkStatistics_t rxLinkStatistics
;
199 void lqTrackerReset(rxLinkQualityTracker_e
* lqTracker
);
200 void lqTrackerAccumulate(rxLinkQualityTracker_e
* lqTracker
, uint16_t rawValue
);
201 void lqTrackerSet(rxLinkQualityTracker_e
* lqTracker
, uint16_t rawValue
);
202 uint16_t lqTrackerGet(rxLinkQualityTracker_e
* lqTracker
);
205 void rxUpdateRSSISource(void);
206 bool rxUpdateCheck(timeUs_t currentTimeUs
, timeDelta_t currentDeltaTime
);
207 bool rxIsReceivingSignal(void);
208 bool rxAreFlightChannelsValid(void);
209 bool calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs
);
210 bool isRxPulseValid(uint16_t pulseDuration
);
212 uint8_t calculateChannelRemapping(const uint8_t *channelMap
, uint8_t channelMapEntryCount
, uint8_t channelToRemap
);
213 void parseRcChannels(const char *input
);
215 void setRSSIFromMSP(uint8_t newMspRssi
);
216 void updateRSSI(timeUs_t currentTimeUs
);
217 // Returns RSSI in [0, RSSI_MAX_VALUE] range.
218 uint16_t getRSSI(void);
219 rssiSource_e
getRSSISource(void);
221 void resetAllRxChannelRangeConfigurations(void);
223 void suspendRxSignal(void);
224 void resumeRxSignal(void);
226 // Processed RC channel value. These values might include
227 // filtering and some extra processing like value holding
229 int16_t rxGetChannelValue(unsigned channelNumber
);