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/>.
27 #include "build/debug.h"
28 #include "drivers/io.h"
29 #include "fc/rc_controls.h"
30 #include "fc/runtime_config.h"
31 #include "flight/failsafe.h"
33 #include "fc/rc_modes.h"
34 #include "common/maths.h"
35 #include "common/utils.h"
36 #include "config/feature.h"
38 #include "pg/pg_ids.h"
39 #include "io/beeper.h"
41 boxBitmask_t rcModeActivationMask
;
42 int16_t debug
[DEBUG16_VALUE_COUNT
];
43 uint8_t debugMode
= 0;
44 uint8_t armingFlags
= 0;
46 bool isPulseValid(uint16_t pulseDuration
);
48 PG_RESET_TEMPLATE(featureConfig_t
, featureConfig
,
52 PG_REGISTER(flight3DConfig_t
, flight3DConfig
, PG_MOTOR_3D_CONFIG
, 0);
53 PG_REGISTER(failsafeConfig_t
, failsafeConfig
, PG_FAILSAFE_CONFIG
, 0);
56 #include "unittest_macros.h"
57 #include "gtest/gtest.h"
59 #define DE_ACTIVATE_ALL_BOXES 0
61 typedef struct testData_s
{
62 bool isPPMDataBeingReceived
;
63 bool isPWMDataBeingReceived
;
66 static testData_t testData
;
68 #if 0 //!! valid pulse handling has changed so these test now test removed functions
69 TEST(RxTest
, TestValidFlightChannels
)
72 memset(&testData
, 0, sizeof(testData
));
73 memset(&rcModeActivationMask
, 0, sizeof(rcModeActivationMask
)); // BOXFAILSAFE must be OFF
76 rxConfigMutable()->rx_min_usec
= 1000;
77 rxConfigMutable()->rx_max_usec
= 2000;
80 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
81 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
82 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN
);
83 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(1600);
85 analyzeModeActivationConditions();
90 // then (ARM channel should be positioned just 1 step above active range to init to OFF)
91 EXPECT_EQ(1625, rcData
[modeActivationConditions(0)->auxChannelIndex
+ NON_AUX_CHANNEL_COUNT
]);
94 rxResetFlightChannelStatus();
97 for (uint8_t channelIndex
= 0; channelIndex
< MAX_SUPPORTED_RC_CHANNEL_COUNT
; channelIndex
++) {
98 bool validPulse
= isPulseValid(1500);
99 rxUpdateFlightChannelStatus(channelIndex
, validPulse
);
103 EXPECT_TRUE(rxHaveValidFlightChannels());
106 TEST(RxTest
, TestValidFlightChannelsHighArm
)
109 memset(&testData
, 0, sizeof(testData
));
110 memset(&rcModeActivationMask
, 0, sizeof(rcModeActivationMask
)); // BOXFAILSAFE must be OFF
113 rxConfigMutable()->rx_min_usec
= 1000;
114 rxConfigMutable()->rx_max_usec
= 2000;
117 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
118 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
119 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1400);
120 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
122 analyzeModeActivationConditions();
127 // then (ARM channel should be positioned just 1 step below active range to init to OFF)
128 EXPECT_EQ(1375, rcData
[modeActivationConditions(0)->auxChannelIndex
+ NON_AUX_CHANNEL_COUNT
]);
131 rxResetFlightChannelStatus();
134 for (uint8_t channelIndex
= 0; channelIndex
< MAX_SUPPORTED_RC_CHANNEL_COUNT
; channelIndex
++) {
135 bool validPulse
= isPulseValid(1500);
136 rxUpdateFlightChannelStatus(channelIndex
, validPulse
);
140 EXPECT_TRUE(rxHaveValidFlightChannels());
143 TEST(RxTest
, TestInvalidFlightChannels
)
146 memset(&testData
, 0, sizeof(testData
));
149 rxConfigMutable()->rx_min_usec
= 1000;
150 rxConfigMutable()->rx_max_usec
= 2000;
153 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
154 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
155 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1400);
156 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
158 analyzeModeActivationConditions();
161 uint16_t channelPulses
[MAX_SUPPORTED_RC_CHANNEL_COUNT
];
162 memset(&channelPulses
, 1500, sizeof(channelPulses
));
167 // then (ARM channel should be positioned just 1 step below active range to init to OFF)
168 EXPECT_EQ(1375, rcData
[modeActivationConditions(0)->auxChannelIndex
+ NON_AUX_CHANNEL_COUNT
]);
171 for (uint8_t stickChannelIndex
= 0; stickChannelIndex
< STICK_CHANNEL_COUNT
; stickChannelIndex
++) {
173 rxResetFlightChannelStatus();
175 for (uint8_t otherStickChannelIndex
= 0; otherStickChannelIndex
< STICK_CHANNEL_COUNT
; otherStickChannelIndex
++) {
176 channelPulses
[otherStickChannelIndex
] = rxConfig()->rx_min_usec
;
178 channelPulses
[stickChannelIndex
] = rxConfig()->rx_min_usec
- 1;
181 for (uint8_t channelIndex
= 0; channelIndex
< MAX_SUPPORTED_RC_CHANNEL_COUNT
; channelIndex
++) {
182 bool validPulse
= isPulseValid(channelPulses
[channelIndex
]);
183 rxUpdateFlightChannelStatus(channelIndex
, validPulse
);
187 EXPECT_FALSE(rxHaveValidFlightChannels());
190 rxResetFlightChannelStatus();
192 for (uint8_t otherStickChannelIndex
= 0; otherStickChannelIndex
< STICK_CHANNEL_COUNT
; otherStickChannelIndex
++) {
193 channelPulses
[otherStickChannelIndex
] = rxConfig()->rx_max_usec
;
195 channelPulses
[stickChannelIndex
] = rxConfig()->rx_max_usec
+ 1;
198 for (uint8_t channelIndex
= 0; channelIndex
< MAX_SUPPORTED_RC_CHANNEL_COUNT
; channelIndex
++) {
199 bool validPulse
= isPulseValid(channelPulses
[channelIndex
]);
200 rxUpdateFlightChannelStatus(channelIndex
, validPulse
);
204 EXPECT_FALSE(rxHaveValidFlightChannels());
212 void failsafeOnValidDataFailed() {}
213 void failsafeOnValidDataReceived() {}
215 void failsafeOnRxSuspend(uint32_t ) {}
216 void failsafeOnRxResume(void) {}
217 bool failsafeIsActive(void) { return false; }
218 bool failsafeIsReceivingRxData(void) { return true; }
219 uint32_t failsafeFailurePeriodMs(void) { return 400; }
221 uint32_t micros(void) { return 0; }
222 uint32_t millis(void) { return 0; }
224 bool isPPMDataBeingReceived(void) {
225 return testData
.isPPMDataBeingReceived
;
228 bool isPWMDataBeingReceived(void) {
229 return testData
.isPWMDataBeingReceived
;
232 void resetPPMDataReceivedState(void) {}
233 bool rxMspFrameComplete(void) { return false; }
235 void crsfRxInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
236 void ibusInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
237 void jetiExBusInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
238 void sbusInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
239 void spektrumInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
240 void sumdInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
241 void sumhInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
242 void xBusInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
243 void rxMspInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
244 void rxPwmInit(const rxConfig_t
*, rxRuntimeState_t
*) {}
245 void setArmingDisabled(armingDisableFlags_e flag
) { UNUSED(flag
); }
246 void unsetArmingDisabled(armingDisableFlags_e flag
) { UNUSED(flag
); }
247 bool taskUpdateRxMainInProgress() { return true; }
248 float pt1FilterGain(float f_cut
, float dT
)
255 void pt1FilterInit(pt1Filter_t
*filter
, float k
)
261 float pt1FilterApply(pt1Filter_t
*filter
, float input
)
268 void pinioBoxTaskControl(void) {}