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/>.
22 //#define DEBUG_LEDSTRIP
26 #include "build/build_config.h"
28 #include "common/axis.h"
29 #include "common/color.h"
32 #include "pg/pg_ids.h"
35 #include "drivers/io.h"
36 #include "drivers/light_ws2811strip.h"
37 #include "drivers/timer.h"
38 #include "drivers/timer_def.h"
40 #include "config/config.h"
41 #include "fc/rc_controls.h"
42 #include "fc/rc_modes.h"
43 #include "fc/runtime_config.h"
46 #include "io/ledstrip.h"
50 #include "sensors/battery.h"
55 #include "unittest_macros.h"
56 #include "gtest/gtest.h"
59 extern uint8_t highestYValueForNorth
;
60 extern uint8_t lowestYValueForSouth
;
61 extern uint8_t highestXValueForWest
;
62 extern uint8_t lowestXValueForEast
;
64 extern uint8_t ledGridRows
;
66 extern ledCounts_t ledCounts
;
68 void reevaluateLedConfig();
70 PG_REGISTER(batteryConfig_t
, batteryConfig
, PG_BATTERY_CONFIG
, 0);
73 TEST(LedStripTest
, parseLedStripConfig
)
76 memset(&ledStripStatusModeConfigMutable()->ledConfigs
, 0, LED_MAX_STRIP_LENGTH
);
79 static const ledConfig_t expectedLedStripConfig
[WS2811_LED_STRIP_LENGTH
] = {
80 DEFINE_LED(9, 9, 0, LD(SOUTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
81 DEFINE_LED(10, 10, 0, LD(SOUTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
82 DEFINE_LED(11, 11, 0, LD(SOUTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
83 DEFINE_LED(11, 11, 0, LD(EAST
), LF(ARM_STATE
), LO(INDICATOR
), 0),
84 DEFINE_LED(10, 10, 0, LD(EAST
), LF(FLIGHT_MODE
), 0, 0),
86 DEFINE_LED(10, 5, 0, LD(SOUTH
), LF(FLIGHT_MODE
), 0, 0),
87 DEFINE_LED(11, 4, 0, LD(SOUTH
), LF(FLIGHT_MODE
), 0, 0),
88 DEFINE_LED(12, 3, 0, LD(SOUTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
89 DEFINE_LED(12, 2, 0, LD(NORTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
90 DEFINE_LED(11, 1, 0, LD(NORTH
), LF(FLIGHT_MODE
), 0, 0),
91 DEFINE_LED(10, 0, 0, LD(NORTH
), LF(FLIGHT_MODE
), 0, 0),
93 DEFINE_LED(7, 0, 0, LD(NORTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
94 DEFINE_LED(6, 0, 1, LD(NORTH
), LF(COLOR
), LO(WARNING
), 0),
95 DEFINE_LED(5, 0, 1, LD(NORTH
), LF(COLOR
), LO(WARNING
), 0),
96 DEFINE_LED(4, 0, 0, LD(NORTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
98 DEFINE_LED(2, 0, 0, LD(NORTH
), LF(FLIGHT_MODE
), 0, 0),
99 DEFINE_LED(1, 1, 0, LD(NORTH
), LF(FLIGHT_MODE
), 0, 0),
100 DEFINE_LED(0, 2, 0, LD(NORTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
101 DEFINE_LED(0, 3, 0, LD(WEST
), LF(ARM_STATE
), LO(INDICATOR
), 0),
102 DEFINE_LED(1, 4, 0, LD(WEST
), LF(FLIGHT_MODE
), 0, 0),
103 DEFINE_LED(2, 5, 0, LD(WEST
), LF(FLIGHT_MODE
), 0, 0),
105 DEFINE_LED(1, 10, 0, LD(WEST
), LF(FLIGHT_MODE
), 0, 0),
106 DEFINE_LED(0, 11, 0, LD(WEST
), LF(ARM_STATE
), LO(INDICATOR
), 0),
107 DEFINE_LED(0, 11, 0, LD(SOUTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
108 DEFINE_LED(1, 10, 0, LD(SOUTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
109 DEFINE_LED(2, 9, 0, LD(SOUTH
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
111 DEFINE_LED(7, 7, 14, 0, LF(THRUST_RING
), 0, 0),
112 DEFINE_LED(8, 7, 15, 0, LF(THRUST_RING
), 0, 0),
113 DEFINE_LED(8, 8, 14, 0, LF(THRUST_RING
), 0, 0),
114 DEFINE_LED(7, 8, 15, 0, LF(THRUST_RING
), 0, 0),
121 const char *ledStripConfigCommands
[] = {
124 // right rear cluster
131 // right front cluster
139 // center front cluster
145 // left front cluster
168 for (uint8_t index
= 0; index
< (sizeof(ledStripConfigCommands
) / sizeof(ledStripConfigCommands
[0])); index
++) {
169 EXPECT_TRUE(parseLedStripConfig(index
, ledStripConfigCommands
[index
]));
173 EXPECT_EQ(30, ledCounts
.count
);
174 EXPECT_EQ(4, ledCounts
.ring
);
177 for (uint8_t index
= 0; index
< WS2811_LED_STRIP_LENGTH
; index
++) {
178 #ifdef DEBUG_LEDSTRIP
179 printf("iteration: %d\n", index
);
181 EXPECT_EQ(expectedLedStripConfig
[index
], ledStripStatusModeConfig()->ledConfigs
[index
]);
185 EXPECT_EQ(12, ledGridRows
);
188 EXPECT_EQ(5, highestXValueForWest
);
189 EXPECT_EQ(7, lowestXValueForEast
);
190 EXPECT_EQ(5, highestYValueForNorth
);
191 EXPECT_EQ(6, lowestYValueForSouth
);
194 TEST(LedStripTest
, smallestGridWithCenter
)
197 memset(&ledStripStatusModeConfigMutable()->ledConfigs
, 0, LED_MAX_STRIP_LENGTH
);
200 static const ledConfig_t testLedConfigs
[] = {
201 DEFINE_LED(2, 2, 0, LD(EAST
), LF(ARM_STATE
), LO(INDICATOR
), 0),
202 DEFINE_LED(2, 1, 0, LD(NORTH
) | LD(EAST
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
203 DEFINE_LED(2, 0, 0, LD(NORTH
), LF(ARM_STATE
), LO(INDICATOR
), 0),
204 DEFINE_LED(1, 0, 0, LD(NORTH
) | LD(WEST
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
205 DEFINE_LED(0, 0, 0, LD(WEST
), LF(ARM_STATE
), LO(INDICATOR
), 0),
206 DEFINE_LED(0, 1, 0, LD(SOUTH
) | LD(WEST
), LF(FLIGHT_MODE
), LO(WARNING
), 0),
207 DEFINE_LED(0, 2, 0, LD(SOUTH
), LF(ARM_STATE
), LO(INDICATOR
), 0)
209 memcpy(&ledStripStatusModeConfigMutable()->ledConfigs
, &testLedConfigs
, sizeof(testLedConfigs
));
212 reevaluateLedConfig();
215 EXPECT_EQ(3, ledGridRows
);
216 EXPECT_EQ(0, highestXValueForWest
);
217 EXPECT_EQ(2, lowestXValueForEast
);
218 EXPECT_EQ(0, highestYValueForNorth
);
219 EXPECT_EQ(2, lowestYValueForSouth
);
222 TEST(LedStripTest
, smallestGrid
)
225 memset(&ledStripStatusModeConfigMutable()->ledConfigs
, 0, LED_MAX_STRIP_LENGTH
);
228 static const ledConfig_t testLedConfigs
[] = {
229 DEFINE_LED(1, 1, 0, LD(SOUTH
) | LD(EAST
), LF(FLIGHT_MODE
), LO(INDICATOR
), 0),
230 DEFINE_LED(1, 0, 0, LD(NORTH
) | LD(EAST
), LF(FLIGHT_MODE
), LO(INDICATOR
), 0),
231 DEFINE_LED(0, 0, 0, LD(NORTH
) | LD(WEST
), LF(FLIGHT_MODE
), LO(INDICATOR
), 0),
232 DEFINE_LED(0, 1, 0, LD(SOUTH
) | LD(WEST
), LF(FLIGHT_MODE
), LO(INDICATOR
), 0)
234 memcpy(&ledStripStatusModeConfigMutable()->ledConfigs
, &testLedConfigs
, sizeof(testLedConfigs
));
237 reevaluateLedConfig();
240 EXPECT_EQ(2, ledGridRows
);
241 EXPECT_EQ(0, highestXValueForWest
);
242 EXPECT_EQ(1, lowestXValueForEast
);
243 EXPECT_EQ(0, highestYValueForNorth
);
244 EXPECT_EQ(1, lowestYValueForSouth
);
247 hsvColor_t testColors
[LED_CONFIGURABLE_COLOR_COUNT
];
249 extern hsvColor_t
*colors
;
251 #define TEST_COLOR_COUNT 4
253 TEST(ColorTest
, parseColor
)
256 memset(ledStripStatusModeConfigMutable()->colors
, 0, sizeof(hsvColor_t
) * LED_CONFIGURABLE_COLOR_COUNT
);
259 const hsvColor_t expectedColors
[TEST_COLOR_COUNT
] = {
267 const char *testColors
[TEST_COLOR_COUNT
] = {
275 for (uint8_t index
= 0; index
< TEST_COLOR_COUNT
; index
++) {
276 #ifdef DEBUG_LEDSTRIP
277 printf("parse iteration: %d\n", index
);
280 parseColor(index
, testColors
[index
]);
285 for (uint8_t index
= 0; index
< TEST_COLOR_COUNT
; index
++) {
286 #ifdef DEBUG_LEDSTRIP
287 printf("iteration: %d\n", index
);
290 EXPECT_EQ(expectedColors
[index
].h
, ledStripStatusModeConfig()->colors
[index
].h
);
291 EXPECT_EQ(expectedColors
[index
].s
, ledStripStatusModeConfig()->colors
[index
].s
);
292 EXPECT_EQ(expectedColors
[index
].v
, ledStripStatusModeConfig()->colors
[index
].v
);
298 uint8_t armingFlags
= 0;
299 uint8_t stateFlags
= 0;
300 uint16_t flightModeFlags
= 0;
302 float rcData
[MAX_SUPPORTED_RC_CHANNEL_COUNT
];
303 boxBitmask_t rcModeActivationMask
;
304 gpsSolutionData_t gpsSol
;
306 batteryState_e
getBatteryState(void) {
310 void ws2811LedStripInit(ioTag_t ioTag
) {
314 void ws2811UpdateStrip(ledStripFormatRGB_e
, uint8_t) {}
316 void setLedValue(uint16_t index
, const uint8_t value
) {
321 void setLedHsv(uint16_t index
, const hsvColor_t
*color
) {
326 void getLedHsv(uint16_t index
, hsvColor_t
*color
) {
332 void scaleLedValue(uint16_t index
, const uint8_t scalePercent
) {
334 UNUSED(scalePercent
);
337 void setStripColor(const hsvColor_t
*color
) {
341 void setStripColors(const hsvColor_t
*colors
) {
345 bool isWS2811LedStripReady(void) { return false; }
347 void delay(uint32_t ms
)
353 uint32_t micros(void) { return 0; }
355 uint32_t millis(void) { return 0; }
357 bool shouldSoundBatteryAlarm(void) { return false; }
358 bool featureIsEnabled(uint32_t mask
) {
363 void tfp_sprintf(char *, char*, ...) { }
365 int scaleRange(int x
, int srcMin
, int srcMax
, int destMin
, int destMax
) {
375 bool failsafeIsActive() { return false; }
376 bool rxIsReceivingSignal() { return true; }
378 bool isBeeperOn() { return false; };
380 uint8_t calculateBatteryPercentageRemaining() { return 0; }
382 bool sensors(uint32_t mask
)
388 const timerHardware_t timerHardware
[USABLE_TIMER_CHANNEL_COUNT
] = {};
390 bool isArmingDisabled(void) { return false; }
392 uint8_t getRssiPercent(void) { return 0; }
394 bool isFlipOverAfterCrashActive(void) { return false; }
396 void ws2811LedStripEnable(void) { }
398 void setUsedLedCount(unsigned) { }
399 void pinioBoxTaskControl(void) {}
400 void schedulerIgnoreTaskExecTime(void) {}
401 bool schedulerGetIgnoreTaskExecTime() { return false; }
402 void schedulerSetNextStateTime(timeDelta_t
) {}