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/>.
25 #include "build/debug.h"
28 #include "pg/pg_ids.h"
31 #include "common/axis.h"
32 #include "common/maths.h"
33 #include "common/bitarray.h"
35 #include "fc/runtime_config.h"
36 #include "fc/rc_modes.h"
37 #include "fc/rc_controls.h"
40 #include "flight/failsafe.h"
42 #include "io/beeper.h"
44 #include "drivers/io.h"
47 extern boxBitmask_t rcModeActivationMask
;
50 #include "unittest_macros.h"
51 #include "gtest/gtest.h"
53 uint32_t testFeatureMask
= 0;
54 uint16_t testMinThrottle
= 0;
55 throttleStatus_e throttleStatus
= THROTTLE_HIGH
;
58 COUNTER_MW_DISARM
= 0,
60 #define CALL_COUNT_ITEM_COUNT 1
62 static int callCounts
[CALL_COUNT_ITEM_COUNT
];
64 #define CALL_COUNTER(item) (callCounts[item])
66 void resetCallCounters(void)
68 memset(&callCounts
, 0, sizeof(callCounts
));
71 #define TEST_MID_RC 1495 // something other than the default 1500 will suffice.
72 #define TEST_MIN_CHECK 1100;
73 #define PERIOD_OF_10_SCONDS 10000
74 #define DE_ACTIVATE_ALL_BOXES 0
76 uint32_t sysTickUptime
;
78 void configureFailsafe(void)
80 rxConfigMutable()->midrc
= TEST_MID_RC
;
81 rxConfigMutable()->mincheck
= TEST_MIN_CHECK
;
83 failsafeConfigMutable()->failsafe_delay
= 10; // 1 second
84 failsafeConfigMutable()->failsafe_off_delay
= 15; // 1.5 seconds
85 failsafeConfigMutable()->failsafe_switch_mode
= FAILSAFE_SWITCH_MODE_STAGE1
;
86 failsafeConfigMutable()->failsafe_throttle
= 1200;
87 failsafeConfigMutable()->failsafe_throttle_low_delay
= 100; // 10 seconds
88 failsafeConfigMutable()->failsafe_procedure
= FAILSAFE_PROCEDURE_AUTO_LANDING
;
89 // NB we don't have failsafe_recovery_delay so use PERIOD_RXDATA_RECOVERY (200ms)
93 void activateBoxFailsafe()
96 bitArraySet(&newMask
, BOXFAILSAFE
);
97 rcModeUpdate(&newMask
);
100 void deactivateBoxFailsafe()
102 boxBitmask_t newMask
;
103 memset(&newMask
, 0, sizeof(newMask
));
104 rcModeUpdate(&newMask
);
111 /****************************************************************************************/
112 TEST(FlightFailsafeTest
, TestFailsafeInitialState
)
117 DISABLE_ARMING_FLAG(ARMED
);
124 EXPECT_FALSE(failsafeIsMonitoring());
125 EXPECT_FALSE(failsafeIsActive());
126 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
129 /****************************************************************************************/
130 TEST(FlightFailsafeTest
, TestFailsafeStartMonitoring
)
133 failsafeStartMonitoring();
136 EXPECT_TRUE(failsafeIsMonitoring());
137 EXPECT_FALSE(failsafeIsActive());
138 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
141 /****************************************************************************************/
142 TEST(FlightFailsafeTest
, TestFailsafeFirstArmedCycle
)
145 ENABLE_ARMING_FLAG(ARMED
);
149 failsafeOnValidDataFailed(); // set last invalid sample to a non-zero value
150 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
+ 1; // adjust time to point just past the recovery time to
151 failsafeOnValidDataReceived(); // cause a recovered link
154 failsafeUpdateState();
157 EXPECT_FALSE(failsafeIsActive());
158 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
161 /****************************************************************************************/
162 TEST(FlightFailsafeTest
, TestFailsafeNotActivatedWhenReceivingData
)
165 for (sysTickUptime
= 0; sysTickUptime
< PERIOD_OF_10_SCONDS
; sysTickUptime
++) {
166 failsafeOnValidDataReceived();
168 failsafeUpdateState();
171 EXPECT_FALSE(failsafeIsActive());
172 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
176 /****************************************************************************************/
180 /****************************************************************************************/
181 TEST(FlightFailsafeTest
, TestFailsafeDetectsRxLossAndStartsLanding
)
187 DISABLE_ARMING_FLAG(ARMED
);
189 failsafeStartMonitoring();
192 EXPECT_TRUE(failsafeIsMonitoring());
193 EXPECT_FALSE(failsafeIsActive());
194 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
197 ENABLE_ARMING_FLAG(ARMED
);
198 throttleStatus
= THROTTLE_HIGH
; // throttle HIGH to go for a failsafe landing procedure
199 failsafeOnValidDataReceived();
202 failsafeUpdateState();
205 EXPECT_FALSE(failsafeIsActive());
206 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
207 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
208 EXPECT_FALSE(isArmingDisabled());
210 // simulate an Rx loss for the stage 1 duration
211 sysTickUptime
+= (failsafeConfig()->failsafe_delay
* MILLIS_PER_TENTH_SECOND
);
212 failsafeOnValidDataFailed();
213 failsafeUpdateState();
215 // should be in stage 1
216 EXPECT_FALSE(failsafeIsActive());
217 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
218 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
219 EXPECT_TRUE(isArmingDisabled());
221 sysTickUptime
++; // exceed the stage 1 period by one tick
222 failsafeOnValidDataFailed(); // confirm that we still have no valid data
224 failsafeUpdateState();
226 // we should now be in stage 2, landing phase
227 EXPECT_TRUE(failsafeIsActive());
228 EXPECT_EQ(FAILSAFE_LANDING
, failsafePhase());
231 /****************************************************************************************/
232 TEST(FlightFailsafeTest
, TestFailsafeCausesLanding
)
233 // note this test follows on from the previous test
235 // exceed the stage 2 landing time
236 sysTickUptime
+= (failsafeConfig()->failsafe_off_delay
* MILLIS_PER_TENTH_SECOND
);
237 failsafeOnValidDataFailed(); // confirm that we still have no valid data
240 failsafeUpdateState();
242 // expect to still be in landing phase
243 EXPECT_TRUE(failsafeIsActive());
244 EXPECT_EQ(FAILSAFE_LANDING
, failsafePhase());
246 // adjust time to point just past the landing time
248 failsafeOnValidDataFailed(); // confirm that we still have no valid data
251 failsafeUpdateState();
253 // expect to be in monitoring mode
254 EXPECT_TRUE(failsafeIsActive());
255 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
256 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
257 EXPECT_TRUE(isArmingDisabled());
259 // let's wait 3 seconds and still get no signal
260 sysTickUptime
+= PERIOD_OF_3_SECONDS
;
261 failsafeOnValidDataFailed(); // confirm that we still have no valid data
263 failsafeUpdateState();
265 // nothing should change
266 EXPECT_TRUE(failsafeIsActive());
267 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
268 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
269 EXPECT_TRUE(isArmingDisabled());
271 // now lets get a signal while in monitoring mode
272 failsafeOnValidDataReceived();
273 // we must clear the first delay in failsafeOnValidDataReceived(), for which 200ms 'works'
274 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
275 failsafeOnValidDataReceived();
276 failsafeUpdateState();
278 // nothing should change
279 EXPECT_TRUE(failsafeIsActive());
280 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
281 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
282 EXPECT_TRUE(isArmingDisabled());
284 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
285 failsafeOnValidDataReceived();
286 failsafeUpdateState();
288 // nothing should change
289 EXPECT_TRUE(failsafeIsActive());
290 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
291 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
292 EXPECT_TRUE(isArmingDisabled());
296 failsafeOnValidDataReceived();
298 failsafeUpdateState();
300 // we expect failsafe to finish and to revert to idle
301 EXPECT_FALSE(failsafeIsActive());
302 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
303 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
)); // disarm not called repeatedly.
304 EXPECT_FALSE(isArmingDisabled());
307 /****************************************************************************************/
308 TEST(FlightFailsafeTest
, TestFailsafeDetectsRxLossAndJustDisarms
)
309 // Just Disarm is when throttle is low for >10s before signal loss
310 // we should exit stage 1 directly into failsafe monitoring mode, and not enter landing mode
312 ENABLE_ARMING_FLAG(ARMED
);
314 failsafeStartMonitoring();
316 // set to normal initial state
317 throttleStatus
= THROTTLE_HIGH
; // throttle HIGH to go for a failsafe landing procedure
318 failsafeConfigMutable()->failsafe_switch_mode
= FAILSAFE_SWITCH_MODE_KILL
;
320 sysTickUptime
+= PERIOD_OF_3_SECONDS
; // 3s of normality
321 failsafeOnValidDataReceived(); // we have a valid signal
323 failsafeUpdateState();
325 // confirm that we are in idle mode
326 EXPECT_FALSE(failsafeIsActive());
327 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
328 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
329 EXPECT_FALSE(isArmingDisabled());
332 // run throttle_low for 11s
333 throttleStatus
= THROTTLE_LOW
; // for failsafe 'just-disarm' procedure
334 sysTickUptime
+= 11000;
335 failsafeOnValidDataReceived(); // set the last valid signal to now
337 failsafeUpdateState();
339 // check that we are still in idle mode
340 EXPECT_FALSE(failsafeIsActive());
341 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
342 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
343 EXPECT_FALSE(isArmingDisabled());
345 // simulate an Rx loss for the stage 1 duration
346 sysTickUptime
+= (failsafeConfig()->failsafe_delay
* MILLIS_PER_TENTH_SECOND
);
347 failsafeOnValidDataFailed();
348 failsafeUpdateState();
350 // should remain in stage 1
351 EXPECT_FALSE(failsafeIsActive());
352 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
353 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
354 EXPECT_TRUE(isArmingDisabled());
356 sysTickUptime
++; // now we exceed stage 1
357 failsafeOnValidDataFailed(); // we still have no valid data
358 failsafeUpdateState();
360 // we should now be in stage 2 via Just Disarm, going direct to monitoring mode.
361 EXPECT_TRUE(failsafeIsActive());
362 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
363 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
364 EXPECT_TRUE(isArmingDisabled());
366 // now lets get a signal while in monitoring mode
367 failsafeOnValidDataReceived();
368 // we must clear the first delay in failsafeOnValidDataReceived(), for which 200ms 'works'
369 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
370 failsafeOnValidDataReceived();
371 failsafeUpdateState();
373 // nothing should change
374 EXPECT_TRUE(failsafeIsActive());
375 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
376 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
377 EXPECT_TRUE(isArmingDisabled());
379 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
380 failsafeOnValidDataReceived();
381 failsafeUpdateState();
383 // nothing should change
384 EXPECT_TRUE(failsafeIsActive());
385 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
386 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
387 EXPECT_TRUE(isArmingDisabled());
391 failsafeOnValidDataReceived();
393 failsafeUpdateState();
395 // we expect failsafe to finish and to revert to idle
396 EXPECT_FALSE(failsafeIsActive());
397 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
398 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
)); // disarm not called repeatedly.
399 EXPECT_FALSE(isArmingDisabled());}
401 /****************************************************************************************/
402 TEST(FlightFailsafeTest
, TestFailsafeSwitchModeKill
)
405 ENABLE_ARMING_FLAG(ARMED
);
407 failsafeStartMonitoring();
409 // set to normal initial state
410 throttleStatus
= THROTTLE_HIGH
; // throttle HIGH to go for a failsafe landing procedure
411 failsafeConfigMutable()->failsafe_switch_mode
= FAILSAFE_SWITCH_MODE_KILL
;
413 sysTickUptime
+= PERIOD_OF_3_SECONDS
; // 3s of normality
414 failsafeOnValidDataReceived(); // we have a valid signal
416 failsafeUpdateState();
418 // confirm that we are in idle mode
419 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
420 EXPECT_FALSE(failsafeIsActive());
421 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
424 activateBoxFailsafe(); // activate the Kill swith
427 failsafeUpdateState(); // should failsafe immediately the kill switch is hit
430 EXPECT_TRUE(failsafeIsActive());
431 EXPECT_TRUE(isArmingDisabled());
432 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
433 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
436 failsafeOnValidDataReceived(); // the link is active the whole time
438 // deactivate the kill switch
439 deactivateBoxFailsafe(); // receivingRxData is immediately true
441 // we should go to failsafe monitoring mode, via Landing
442 EXPECT_TRUE(failsafeIsActive());
443 EXPECT_TRUE(isArmingDisabled());
444 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
445 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
447 // since we didn't enter stage 2, we have one rxDataRecoveryPeriod delay to deal with
448 // while within rxDataRecoveryPeriod in monitoring mode...
449 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
450 failsafeOnValidDataReceived();
453 failsafeUpdateState();
455 // we should still be in failsafe monitoring mode
456 EXPECT_TRUE(failsafeIsActive());
457 EXPECT_TRUE(isArmingDisabled());
458 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
459 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
465 failsafeUpdateState();
467 // we should now have exited failsafe
468 EXPECT_FALSE(failsafeIsActive());
469 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
470 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
)); // disarm not called repeatedly.
471 EXPECT_FALSE(isArmingDisabled());
474 /****************************************************************************************/
476 TEST(FlightFailsafeTest
, TestFailsafeSwitchModeStage1OrStage2Drop
)
477 // should immediately stop motors and go to monitoring mode diretly
479 // given a clean start
480 ENABLE_ARMING_FLAG(ARMED
);
482 failsafeStartMonitoring();
484 // and set initial states
485 throttleStatus
= THROTTLE_HIGH
; // throttle HIGH to go for a failsafe landing procedure
486 failsafeConfigMutable()->failsafe_switch_mode
= FAILSAFE_SWITCH_MODE_STAGE2
;
487 failsafeConfigMutable()->failsafe_procedure
= FAILSAFE_PROCEDURE_DROP_IT
;
489 sysTickUptime
= 0; // restart time from 0
490 failsafeOnValidDataReceived(); // we have a valid signal
491 sysTickUptime
+= 3000; // 3s of normality
494 failsafeUpdateState();
496 // confirm that we are in idle mode
497 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
498 EXPECT_FALSE(failsafeIsActive());
499 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
502 activateBoxFailsafe(); // activate the stage 2 Drop switch
503 failsafeOnValidDataFailed(); // immediate stage 2 switch sets failsafeOnValidDataFailed
506 failsafeUpdateState(); // should activate stage2 immediately, even though signal is good
508 // expect to be in monitoring mode, and to have disarmed
509 EXPECT_TRUE(failsafeIsActive());
510 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
511 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
512 EXPECT_TRUE(isArmingDisabled());
514 // deactivate the failsafe switch
515 deactivateBoxFailsafe();
517 EXPECT_TRUE(failsafeIsActive());
518 EXPECT_TRUE(isArmingDisabled());
519 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
520 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
522 // by next evaluation we should be out of failsafe
524 // receivingRxData is immediately true because signal exists
525 failsafeOnValidDataReceived();
528 failsafeUpdateState();
530 // we should now have exited failsafe
531 EXPECT_FALSE(failsafeIsActive());
532 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
533 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
)); // disarm not called repeatedly.
534 EXPECT_FALSE(isArmingDisabled());
537 /****************************************************************************************/
539 TEST(FlightFailsafeTest
, TestFailsafeSwitchModeStage2Land
)
541 // given a clean start
542 ENABLE_ARMING_FLAG(ARMED
);
544 failsafeStartMonitoring();
547 throttleStatus
= THROTTLE_HIGH
; // throttle HIGH to go for a failsafe landing procedure
548 failsafeConfigMutable()->failsafe_switch_mode
= FAILSAFE_SWITCH_MODE_STAGE2
;
549 failsafeConfigMutable()->failsafe_procedure
= FAILSAFE_PROCEDURE_AUTO_LANDING
;
551 sysTickUptime
= 0; // restart time from 0
552 failsafeOnValidDataReceived(); // we have a valid signal
553 sysTickUptime
+= 3000; // 3s of normality
556 failsafeUpdateState();
558 // confirm that we are in idle mode
559 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
560 EXPECT_FALSE(failsafeIsActive());
561 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
564 activateBoxFailsafe(); // activate the stage 2 Drop switch
565 failsafeOnValidDataFailed(); // immediate stage 2 switch sets failsafeOnValidDataFailed
568 failsafeUpdateState(); // should activate stage2 immediately
570 // expect to immediately be in landing mode, and not disarmed
571 EXPECT_TRUE(failsafeIsActive()); // stick induced failsafe allows re-arming
572 EXPECT_EQ(FAILSAFE_LANDING
, failsafePhase());
573 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
575 // should stay in landing for failsafe_off_delay (stage 2 period) of 1s
576 sysTickUptime
+= failsafeConfig()->failsafe_off_delay
* MILLIS_PER_TENTH_SECOND
;
579 failsafeUpdateState();
581 EXPECT_TRUE(failsafeIsActive()); // stick induced failsafe allows re-arming
582 EXPECT_EQ(FAILSAFE_LANDING
, failsafePhase());
583 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
585 // one tick later, landing time has elapsed
589 failsafeUpdateState();
591 // now should be in monitoring mode, with switch holding signalReceived false
592 EXPECT_TRUE(failsafeIsActive());
593 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
594 EXPECT_TRUE(isArmingDisabled());
595 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
598 sysTickUptime
+= PERIOD_OF_3_SECONDS
; // hang around a bit waiting for switch change
601 failsafeUpdateState();
603 // should still be in monitoring mode because switch is still forcing receivingRxData false
604 EXPECT_TRUE(failsafeIsActive());
605 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
606 EXPECT_TRUE(isArmingDisabled());
607 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
609 // deactivate the failsafe switch
610 deactivateBoxFailsafe();
612 // receivingRxData is immediately true
613 // we go directly to failsafe monitoring mode, via Landing
614 // however, because the switch also forces rxFlightChannelsValid false, emulating real failsafe
615 // we have two delays to deal with before we can re-arm
617 EXPECT_TRUE(failsafeIsActive());
618 EXPECT_TRUE(isArmingDisabled());
619 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
));
620 EXPECT_EQ(FAILSAFE_RX_LOSS_MONITORING
, failsafePhase());
625 failsafeOnValidDataReceived();
628 failsafeUpdateState();
630 // we should now have exited failsafe
631 EXPECT_FALSE(failsafeIsActive());
632 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
633 EXPECT_EQ(1, CALL_COUNTER(COUNTER_MW_DISARM
)); // disarm not called repeatedly.
634 EXPECT_FALSE(isArmingDisabled());
638 /****************************************************************************************/
642 /****************************************************************************************/
643 TEST(FlightFailsafeTest
, TestFailsafeNotActivatedWhenDisarmedAndRXLossIsDetected
)
652 // and ** WE ARE DISARMED **
653 DISABLE_ARMING_FLAG(ARMED
);
655 // when failsafe starts
656 failsafeStartMonitoring();
659 sysTickUptime
= 0; // restart time from 0
660 failsafeOnValidDataReceived(); // we have a valid signal
661 sysTickUptime
+= 3000; // 3s of normality
664 failsafeUpdateState();
666 // confirm that we are in idle mode
667 EXPECT_FALSE(failsafeIsActive());
668 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
669 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
671 // and that arming is not disabled
672 EXPECT_FALSE(isArmingDisabled());
674 // simulate an Rx loss for the stage 1 duration
675 sysTickUptime
+= (failsafeConfig()->failsafe_delay
* MILLIS_PER_TENTH_SECOND
);
676 failsafeOnValidDataFailed();
677 failsafeUpdateState();
679 // within stage 1 time from a true failsafe while disarmed, stage 2 should normally not be active
680 EXPECT_FALSE(failsafeIsActive());
681 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
682 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
684 // arming is disabled due to setArmingDisabled in stage 1 due to failsafeOnValidDataFailed()
685 EXPECT_FALSE(failsafeIsActive());
688 sysTickUptime
++; // adjust time to point just past stage 1
689 failsafeOnValidDataFailed(); // would normally enter stage 2, but we are disarmed
690 failsafeUpdateState();
692 // expect that we do not enter failsafe stage 2, ie no change from above
693 EXPECT_FALSE(failsafeIsActive());
694 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
695 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
697 // the lock on the aux channels persists at fixed stage 1 values until recovery time
698 EXPECT_TRUE(isArmingDisabled());
700 // allow signal received for the recovery time
701 sysTickUptime
+= PERIOD_RXDATA_RECOVERY
;
702 failsafeOnValidDataReceived();
703 failsafeUpdateState();
705 // no change in failsafe state (still idle)
706 EXPECT_FALSE(failsafeIsActive());
707 EXPECT_EQ(FAILSAFE_IDLE
, failsafePhase());
708 EXPECT_EQ(0, CALL_COUNTER(COUNTER_MW_DISARM
));
710 // but now arming is possible
711 EXPECT_FALSE(isArmingDisabled());
717 float rcData
[MAX_SUPPORTED_RC_CHANNEL_COUNT
];
719 int16_t debug
[DEBUG16_VALUE_COUNT
];
720 uint8_t debugMode
= 0;
721 bool isUsingSticksToArm
= true;
723 PG_REGISTER(rxConfig_t
, rxConfig
, PG_RX_CONFIG
, 0);
725 // Return system uptime in milliseconds (rollover in 49 days)
726 uint32_t millis(void)
728 return sysTickUptime
;
731 uint32_t micros(void)
733 return millis() * 1000;
736 throttleStatus_e
calculateThrottleStatus()
738 return throttleStatus
;
741 void delay(uint32_t) {}
743 bool featureIsEnabled(uint32_t mask
)
745 return (mask
& testFeatureMask
);
748 void disarm(flightLogDisarmReason_e
)
750 callCounts
[COUNTER_MW_DISARM
]++;
753 void beeper(beeperMode_e mode
)
758 uint16_t getCurrentMinthrottle(void)
760 return testMinThrottle
;
763 bool isUsingSticksForArming(void)
765 return isUsingSticksToArm
;
768 bool areSticksActive(uint8_t stickPercentLimit
)
770 UNUSED(stickPercentLimit
);
774 void beeperConfirmationBeeps(uint8_t beepCount
) { UNUSED(beepCount
); }
776 bool crashRecoveryModeActive(void) { return false; }
777 void pinioBoxTaskControl(void) {}