Merge pull request #11430 from phobos-/crazybee-icm
[betaflight.git] / src / test / unit / rx_rx_unittest.cc
blobb2ecb580f1ad1b4af7b56775cdbf1cd572ce303d
1 /*
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/>.
18 #include <stdint.h>
19 #include <stdbool.h>
21 #include <limits.h>
23 extern "C" {
24 #include "platform.h"
26 #include "pg/rx.h"
27 #include "build/debug.h"
28 #include "drivers/io.h"
29 #include "fc/rc_controls.h"
30 #include "rx/rx.h"
31 #include "fc/rc_modes.h"
32 #include "common/maths.h"
33 #include "common/utils.h"
34 #include "config/feature.h"
35 #include "pg/pg.h"
36 #include "pg/pg_ids.h"
37 #include "io/beeper.h"
39 boxBitmask_t rcModeActivationMask;
40 int16_t debug[DEBUG16_VALUE_COUNT];
41 uint8_t debugMode = 0;
43 bool isPulseValid(uint16_t pulseDuration);
45 PG_RESET_TEMPLATE(featureConfig_t, featureConfig,
46 .enabledFeatures = 0
49 PG_REGISTER(flight3DConfig_t, flight3DConfig, PG_MOTOR_3D_CONFIG, 0);
52 #include "unittest_macros.h"
53 #include "gtest/gtest.h"
55 #define DE_ACTIVATE_ALL_BOXES 0
57 typedef struct testData_s {
58 bool isPPMDataBeingReceived;
59 bool isPWMDataBeingReceived;
60 } testData_t;
62 static testData_t testData;
64 #if 0 //!! valid pulse handling has changed so these test now test removed functions
65 TEST(RxTest, TestValidFlightChannels)
67 // given
68 memset(&testData, 0, sizeof(testData));
69 memset(&rcModeActivationMask, 0, sizeof(rcModeActivationMask)); // BOXFAILSAFE must be OFF
71 // and
72 rxConfigMutable()->rx_min_usec = 1000;
73 rxConfigMutable()->rx_max_usec = 2000;
75 // and
76 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
77 modeActivationConditionsMutable(0)->modeId = BOXARM;
78 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
79 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
81 analyzeModeActivationConditions();
83 // when
84 rxInit();
86 // then (ARM channel should be positioned just 1 step above active range to init to OFF)
87 EXPECT_EQ(1625, rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT]);
89 // given
90 rxResetFlightChannelStatus();
92 // and
93 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
94 bool validPulse = isPulseValid(1500);
95 rxUpdateFlightChannelStatus(channelIndex, validPulse);
98 // then
99 EXPECT_TRUE(rxHaveValidFlightChannels());
102 TEST(RxTest, TestValidFlightChannelsHighArm)
104 // given
105 memset(&testData, 0, sizeof(testData));
106 memset(&rcModeActivationMask, 0, sizeof(rcModeActivationMask)); // BOXFAILSAFE must be OFF
108 // and
109 rxConfigMutable()->rx_min_usec = 1000;
110 rxConfigMutable()->rx_max_usec = 2000;
112 // and
113 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
114 modeActivationConditionsMutable(0)->modeId = BOXARM;
115 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(1400);
116 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX);
118 analyzeModeActivationConditions();
120 // when
121 rxInit();
123 // then (ARM channel should be positioned just 1 step below active range to init to OFF)
124 EXPECT_EQ(1375, rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT]);
126 // given
127 rxResetFlightChannelStatus();
129 // and
130 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
131 bool validPulse = isPulseValid(1500);
132 rxUpdateFlightChannelStatus(channelIndex, validPulse);
135 // then
136 EXPECT_TRUE(rxHaveValidFlightChannels());
139 TEST(RxTest, TestInvalidFlightChannels)
141 // given
142 memset(&testData, 0, sizeof(testData));
144 // and
145 rxConfigMutable()->rx_min_usec = 1000;
146 rxConfigMutable()->rx_max_usec = 2000;
148 // and
149 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
150 modeActivationConditionsMutable(0)->modeId = BOXARM;
151 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(1400);
152 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX);
154 analyzeModeActivationConditions();
156 // and
157 uint16_t channelPulses[MAX_SUPPORTED_RC_CHANNEL_COUNT];
158 memset(&channelPulses, 1500, sizeof(channelPulses));
160 // and
161 rxInit();
163 // then (ARM channel should be positioned just 1 step below active range to init to OFF)
164 EXPECT_EQ(1375, rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT]);
166 // and
167 for (uint8_t stickChannelIndex = 0; stickChannelIndex < STICK_CHANNEL_COUNT; stickChannelIndex++) {
168 // given
169 rxResetFlightChannelStatus();
171 for (uint8_t otherStickChannelIndex = 0; otherStickChannelIndex < STICK_CHANNEL_COUNT; otherStickChannelIndex++) {
172 channelPulses[otherStickChannelIndex] = rxConfig()->rx_min_usec;
174 channelPulses[stickChannelIndex] = rxConfig()->rx_min_usec - 1;
176 // when
177 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
178 bool validPulse = isPulseValid(channelPulses[channelIndex]);
179 rxUpdateFlightChannelStatus(channelIndex, validPulse);
182 // then
183 EXPECT_FALSE(rxHaveValidFlightChannels());
185 // given
186 rxResetFlightChannelStatus();
188 for (uint8_t otherStickChannelIndex = 0; otherStickChannelIndex < STICK_CHANNEL_COUNT; otherStickChannelIndex++) {
189 channelPulses[otherStickChannelIndex] = rxConfig()->rx_max_usec;
191 channelPulses[stickChannelIndex] = rxConfig()->rx_max_usec + 1;
193 // when
194 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
195 bool validPulse = isPulseValid(channelPulses[channelIndex]);
196 rxUpdateFlightChannelStatus(channelIndex, validPulse);
199 // then
200 EXPECT_FALSE(rxHaveValidFlightChannels());
203 #endif
205 // STUBS
207 extern "C" {
208 void failsafeOnValidDataFailed() {}
209 void failsafeOnValidDataReceived() {}
211 void failsafeOnRxSuspend(uint32_t ) {}
212 void failsafeOnRxResume(void) {}
213 bool failsafeIsReceivingRxData(void) { return true; }
215 uint32_t micros(void) { return 0; }
216 uint32_t millis(void) { return 0; }
218 bool isPPMDataBeingReceived(void) {
219 return testData.isPPMDataBeingReceived;
222 bool isPWMDataBeingReceived(void) {
223 return testData.isPWMDataBeingReceived;
226 void resetPPMDataReceivedState(void) {}
227 bool rxMspFrameComplete(void) { return false; }
229 void crsfRxInit(const rxConfig_t *, rxRuntimeState_t *) {}
230 void ibusInit(const rxConfig_t *, rxRuntimeState_t *) {}
231 void jetiExBusInit(const rxConfig_t *, rxRuntimeState_t *) {}
232 void sbusInit(const rxConfig_t *, rxRuntimeState_t *) {}
233 void spektrumInit(const rxConfig_t *, rxRuntimeState_t *) {}
234 void sumdInit(const rxConfig_t *, rxRuntimeState_t *) {}
235 void sumhInit(const rxConfig_t *, rxRuntimeState_t *) {}
236 void xBusInit(const rxConfig_t *, rxRuntimeState_t *) {}
237 void rxMspInit(const rxConfig_t *, rxRuntimeState_t *) {}
238 void rxPwmInit(const rxConfig_t *, rxRuntimeState_t *) {}
239 bool taskUpdateRxMainInProgress() { return true; }
240 float pt1FilterGain(float f_cut, float dT)
242 UNUSED(f_cut);
243 UNUSED(dT);
244 return 0.0;
247 void pt1FilterInit(pt1Filter_t *filter, float k)
249 UNUSED(filter);
250 UNUSED(k);
253 float pt1FilterApply(pt1Filter_t *filter, float input)
255 UNUSED(filter);
256 UNUSED(input);
257 return 0.0;
260 void pinioBoxTaskControl(void) {}