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 "io/rc_controls.h"
28 #include "common/maths.h"
30 uint32_t rcModeActivationMask;
32 void rxInit(rxConfig_t *rxConfig, modeActivationCondition_t *modeActivationConditions);
33 void rxResetFlightChannelStatus(void);
34 bool rxHaveValidFlightChannels(void);
35 bool isPulseValid(uint16_t pulseDuration);
36 void rxUpdateFlightChannelStatus(uint8_t channel, uint16_t pulseDuration);
39 #include "unittest_macros.h"
40 #include "gtest/gtest.h"
42 #define DE_ACTIVATE_ALL_BOXES 0
44 typedef struct testData_s {
45 bool isPPMDataBeingReceived;
46 bool isPWMDataBeingReceived;
49 static testData_t testData;
51 TEST(RxTest, TestValidFlightChannels)
54 memset(&testData, 0, sizeof(testData));
55 rcModeActivationMask = DE_ACTIVATE_ALL_BOXES; // BOXFAILSAFE must be OFF
59 modeActivationCondition_t modeActivationConditions[MAX_MODE_ACTIVATION_CONDITION_COUNT];
61 memset(&rxConfig, 0, sizeof(rxConfig));
62 rxConfig.rx_min_usec = 1000;
63 rxConfig.rx_max_usec = 2000;
65 memset(&modeActivationConditions, 0, sizeof(modeActivationConditions));
66 modeActivationConditions[0].auxChannelIndex = 0;
67 modeActivationConditions[0].modeId = BOXARM;
68 modeActivationConditions[0].range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
69 modeActivationConditions[0].range.endStep = CHANNEL_VALUE_TO_STEP(1600);
72 rxInit(&rxConfig, modeActivationConditions);
74 // then (ARM channel should be positioned just 1 step above active range to init to OFF)
75 EXPECT_EQ(1625, rcData[modeActivationConditions[0].auxChannelIndex + NON_AUX_CHANNEL_COUNT]);
78 rxResetFlightChannelStatus();
81 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
82 bool validPulse = isPulseValid(1500);
83 rxUpdateFlightChannelStatus(channelIndex, validPulse);
87 EXPECT_TRUE(rxHaveValidFlightChannels());
90 TEST(RxTest, TestInvalidFlightChannels)
93 memset(&testData, 0, sizeof(testData));
97 modeActivationCondition_t modeActivationConditions[MAX_MODE_ACTIVATION_CONDITION_COUNT];
99 memset(&rxConfig, 0, sizeof(rxConfig));
100 rxConfig.rx_min_usec = 1000;
101 rxConfig.rx_max_usec = 2000;
103 memset(&modeActivationConditions, 0, sizeof(modeActivationConditions));
104 modeActivationConditions[0].auxChannelIndex = 0;
105 modeActivationConditions[0].modeId = BOXARM;
106 modeActivationConditions[0].range.startStep = CHANNEL_VALUE_TO_STEP(1400);
107 modeActivationConditions[0].range.endStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX);
110 uint16_t channelPulses[MAX_SUPPORTED_RC_CHANNEL_COUNT];
111 memset(&channelPulses, 1500, sizeof(channelPulses));
114 rxInit(&rxConfig, modeActivationConditions);
116 // then (ARM channel should be positioned just 1 step below active range to init to OFF)
117 EXPECT_EQ(1375, rcData[modeActivationConditions[0].auxChannelIndex + NON_AUX_CHANNEL_COUNT]);
120 for (uint8_t stickChannelIndex = 0; stickChannelIndex < STICK_CHANNEL_COUNT; stickChannelIndex++) {
123 rxResetFlightChannelStatus();
125 for (uint8_t otherStickChannelIndex = 0; otherStickChannelIndex < STICK_CHANNEL_COUNT; otherStickChannelIndex++) {
126 channelPulses[otherStickChannelIndex] = rxConfig.rx_min_usec;
128 channelPulses[stickChannelIndex] = rxConfig.rx_min_usec - 1;
131 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
132 bool validPulse = isPulseValid(channelPulses[channelIndex]);
133 rxUpdateFlightChannelStatus(channelIndex, validPulse);
137 EXPECT_FALSE(rxHaveValidFlightChannels());
140 rxResetFlightChannelStatus();
142 for (uint8_t otherStickChannelIndex = 0; otherStickChannelIndex < STICK_CHANNEL_COUNT; otherStickChannelIndex++) {
143 channelPulses[otherStickChannelIndex] = rxConfig.rx_max_usec;
145 channelPulses[stickChannelIndex] = rxConfig.rx_max_usec + 1;
148 for (uint8_t channelIndex = 0; channelIndex < MAX_SUPPORTED_RC_CHANNEL_COUNT; channelIndex++) {
149 bool validPulse = isPulseValid(channelPulses[channelIndex]);
150 rxUpdateFlightChannelStatus(channelIndex, validPulse);
154 EXPECT_FALSE(rxHaveValidFlightChannels());
162 void failsafeOnValidDataFailed() {}
163 void failsafeOnValidDataReceived() {}
165 void failsafeOnRxSuspend(uint32_t ) {}
166 void failsafeOnRxResume(void) {}
168 uint32_t micros(void) { return 0; }
169 uint32_t millis(void) { return 0; }
171 bool feature(uint32_t mask) {
176 bool isPPMDataBeingReceived(void) {
177 return testData.isPPMDataBeingReceived;
180 bool isPWMDataBeingReceived(void) {
181 return testData.isPWMDataBeingReceived;
184 void resetPPMDataReceivedState(void) {}
186 bool rxMspFrameComplete(void) { return false; }
188 void rxMspInit(rxConfig_t *, rxRuntimeConfig_t *, rcReadRawDataPtr *) {}
190 void rxPwmInit(rxRuntimeConfig_t *, rcReadRawDataPtr *) {}