New led functions gps bar battery bar altitude (#13404)
[betaflight.git] / src / test / unit / ledstrip_unittest.cc
blob0179a25199bc2bd41b330f4147aea24074b1a2cd
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/>.
17 #include <stdint.h>
18 #include <stdlib.h>
20 #include <limits.h>
22 //#define DEBUG_LEDSTRIP
24 extern "C" {
25 #include "platform.h"
26 #include "build/build_config.h"
28 #include "common/axis.h"
29 #include "common/color.h"
30 #include "common/utils.h"
32 #include "pg/pg.h"
33 #include "pg/pg_ids.h"
34 #include "pg/rx.h"
36 #include "drivers/io.h"
37 #include "drivers/light_ws2811strip.h"
38 #include "drivers/timer.h"
39 #include "timer_def.h"
41 #include "config/config.h"
42 #include "fc/rc_controls.h"
43 #include "fc/rc_modes.h"
44 #include "fc/runtime_config.h"
46 #include "io/gps.h"
47 #include "io/ledstrip.h"
49 #include "rx/rx.h"
51 #include "sensors/battery.h"
53 #include "scheduler/scheduler.h"
55 #include "target.h"
58 #include "unittest_macros.h"
59 #include "gtest/gtest.h"
61 extern "C" {
62 extern uint8_t highestYValueForNorth;
63 extern uint8_t lowestYValueForSouth;
64 extern uint8_t highestXValueForWest;
65 extern uint8_t lowestXValueForEast;
67 extern uint8_t ledGridRows;
69 extern ledCounts_t ledCounts;
71 void reevaluateLedConfig();
73 PG_REGISTER(batteryConfig_t, batteryConfig, PG_BATTERY_CONFIG, 0);
76 TEST(LedStripTest, parseLedStripConfig)
78 // given
79 memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, sizeof(ledStripStatusModeConfigMutable()->ledConfigs));
81 // and
82 static const ledConfig_t expectedLedStripConfig[WS2811_LED_STRIP_LENGTH] = {
83 DEFINE_LED(9, 9, 0, LD(SOUTH), LF(FLIGHT_MODE), LO(WARNING)),
84 DEFINE_LED(10, 10, 0, LD(SOUTH), LF(FLIGHT_MODE), LO(WARNING)),
85 DEFINE_LED(11, 11, 0, LD(SOUTH), LF(ARM_STATE), LO(INDICATOR)),
86 DEFINE_LED(11, 11, 0, LD(EAST), LF(ARM_STATE), LO(INDICATOR)),
87 DEFINE_LED(10, 10, 0, LD(EAST), LF(FLIGHT_MODE), 0),
89 DEFINE_LED(10, 5, 0, LD(SOUTH), LF(FLIGHT_MODE), 0),
90 DEFINE_LED(11, 4, 0, LD(SOUTH), LF(FLIGHT_MODE), 0),
91 DEFINE_LED(12, 3, 0, LD(SOUTH), LF(ARM_STATE), LO(INDICATOR)),
92 DEFINE_LED(12, 2, 0, LD(NORTH), LF(ARM_STATE), LO(INDICATOR)),
93 DEFINE_LED(11, 1, 0, LD(NORTH), LF(FLIGHT_MODE), 0),
94 DEFINE_LED(10, 0, 0, LD(NORTH), LF(FLIGHT_MODE), 0),
96 DEFINE_LED(7, 0, 0, LD(NORTH), LF(FLIGHT_MODE), LO(WARNING)),
97 DEFINE_LED(6, 0, 1, LD(NORTH), LF(COLOR), LO(WARNING)),
98 DEFINE_LED(5, 0, 1, LD(NORTH), LF(COLOR), LO(WARNING)),
99 DEFINE_LED(4, 0, 0, LD(NORTH), LF(FLIGHT_MODE), LO(WARNING)),
101 DEFINE_LED(2, 0, 0, LD(NORTH), LF(FLIGHT_MODE), 0),
102 DEFINE_LED(1, 1, 0, LD(NORTH), LF(FLIGHT_MODE), 0),
103 DEFINE_LED(0, 2, 0, LD(NORTH), LF(ARM_STATE), LO(INDICATOR)),
104 DEFINE_LED(0, 3, 0, LD(WEST), LF(ARM_STATE), LO(INDICATOR)),
105 DEFINE_LED(1, 4, 0, LD(WEST), LF(FLIGHT_MODE), 0),
106 DEFINE_LED(2, 5, 0, LD(WEST), LF(FLIGHT_MODE), 0),
108 DEFINE_LED(1, 10, 0, LD(WEST), LF(FLIGHT_MODE), 0),
109 DEFINE_LED(0, 11, 0, LD(WEST), LF(ARM_STATE), LO(INDICATOR)),
110 DEFINE_LED(0, 11, 0, LD(SOUTH), LF(ARM_STATE), LO(INDICATOR)),
111 DEFINE_LED(1, 10, 0, LD(SOUTH), LF(FLIGHT_MODE), LO(WARNING)),
112 DEFINE_LED(2, 9, 0, LD(SOUTH), LF(FLIGHT_MODE), LO(WARNING)),
114 DEFINE_LED(7, 7, 14, 0, LF(THRUST_RING), 0),
115 DEFINE_LED(8, 7, 15, 0, LF(THRUST_RING), 0),
116 DEFINE_LED(8, 8, 14, 0, LF(THRUST_RING), 0),
117 DEFINE_LED(7, 8, 15, 0, LF(THRUST_RING), 0),
123 // and
124 const char *ledStripConfigCommands[] = {
125 // Spider quad
127 // right rear cluster
128 "9,9:S:FW:0",
129 "10,10:S:FW:0",
130 "11,11:S:IA:0",
131 "11,11:E:IA:0",
132 "10,10:E:F:0",
134 // right front cluster
135 "10,5:S:F:0",
136 "11,4:S:F:0",
137 "12,3:S:IA:0",
138 "12,2:N:IA:0",
139 "11,1:N:F:0",
140 "10,0:N:F:0",
142 // center front cluster
143 "7,0:N:FW:0",
144 "6,0:N:CW:1",
145 "5,0:N:CW:1",
146 "4,0:N:FW:0",
148 // left front cluster
149 "2,0:N:F:0",
150 "1,1:N:F:0",
151 "0,2:N:IA:0",
152 "0,3:W:IA:0",
153 "1,4:W:F:0",
154 "2,5:W:F:0",
156 // left rear cluster
157 "1,10:W:F:0",
158 "0,11:W:IA:0",
159 "0,11:S:IA:0",
160 "1,10:S:FW:0",
161 "2,9:S:FW:0",
163 // thrust ring
164 "7,7::R:14",
165 "8,7::R:15",
166 "8,8::R:14",
167 "7,8::R:15"
170 // when
171 for (uint8_t index = 0; index < ARRAYLEN(ledStripConfigCommands); index++) {
172 EXPECT_TRUE(parseLedStripConfig(index, ledStripConfigCommands[index]));
175 // then
176 EXPECT_EQ(30, ledCounts.count);
177 EXPECT_EQ(4, ledCounts.ring);
179 // and
180 for (uint8_t index = 0; index < WS2811_LED_STRIP_LENGTH; index++) {
181 #ifdef DEBUG_LEDSTRIP
182 printf("iteration: %d\n", index);
183 #endif
184 EXPECT_EQ(expectedLedStripConfig[index], ledStripStatusModeConfig()->ledConfigs[index]);
187 // then
188 EXPECT_EQ(12, ledGridRows);
190 // then
191 EXPECT_EQ(5, highestXValueForWest);
192 EXPECT_EQ(7, lowestXValueForEast);
193 EXPECT_EQ(5, highestYValueForNorth);
194 EXPECT_EQ(6, lowestYValueForSouth);
197 TEST(LedStripTest, smallestGridWithCenter)
199 // given
200 memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, sizeof(ledStripStatusModeConfigMutable()->ledConfigs));
202 // and
203 static const ledConfig_t testLedConfigs[] = {
204 DEFINE_LED(2, 2, 0, LD(EAST), LF(ARM_STATE), LO(INDICATOR)),
205 DEFINE_LED(2, 1, 0, LD(NORTH) | LD(EAST), LF(FLIGHT_MODE), LO(WARNING)),
206 DEFINE_LED(2, 0, 0, LD(NORTH), LF(ARM_STATE), LO(INDICATOR)),
207 DEFINE_LED(1, 0, 0, LD(NORTH) | LD(WEST), LF(FLIGHT_MODE), LO(WARNING)),
208 DEFINE_LED(0, 0, 0, LD(WEST), LF(ARM_STATE), LO(INDICATOR)),
209 DEFINE_LED(0, 1, 0, LD(SOUTH) | LD(WEST), LF(FLIGHT_MODE), LO(WARNING)),
210 DEFINE_LED(0, 2, 0, LD(SOUTH), LF(ARM_STATE), LO(INDICATOR))
212 memcpy(&ledStripStatusModeConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs));
214 // when
215 reevaluateLedConfig();
217 // then
218 EXPECT_EQ(3, ledGridRows);
219 EXPECT_EQ(0, highestXValueForWest);
220 EXPECT_EQ(2, lowestXValueForEast);
221 EXPECT_EQ(0, highestYValueForNorth);
222 EXPECT_EQ(2, lowestYValueForSouth);
225 TEST(LedStripTest, smallestGrid)
227 // given
228 memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, sizeof(ledStripStatusModeConfigMutable()->ledConfigs));
230 // and
231 static const ledConfig_t testLedConfigs[] = {
232 DEFINE_LED(1, 1, 0, LD(SOUTH) | LD(EAST), LF(FLIGHT_MODE), LO(INDICATOR)),
233 DEFINE_LED(1, 0, 0, LD(NORTH) | LD(EAST), LF(FLIGHT_MODE), LO(INDICATOR)),
234 DEFINE_LED(0, 0, 0, LD(NORTH) | LD(WEST), LF(FLIGHT_MODE), LO(INDICATOR)),
235 DEFINE_LED(0, 1, 0, LD(SOUTH) | LD(WEST), LF(FLIGHT_MODE), LO(INDICATOR))
237 memcpy(&ledStripStatusModeConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs));
239 // when
240 reevaluateLedConfig();
242 // then
243 EXPECT_EQ(2, ledGridRows);
244 EXPECT_EQ(0, highestXValueForWest);
245 EXPECT_EQ(1, lowestXValueForEast);
246 EXPECT_EQ(0, highestYValueForNorth);
247 EXPECT_EQ(1, lowestYValueForSouth);
250 hsvColor_t testColors[LED_CONFIGURABLE_COLOR_COUNT];
252 extern hsvColor_t *colors;
254 #define TEST_COLOR_COUNT 4
256 TEST(ColorTest, parseColor)
258 // given
259 memset(ledStripStatusModeConfigMutable()->colors, 0, sizeof(hsvColor_t) * LED_CONFIGURABLE_COLOR_COUNT);
261 // and
262 const hsvColor_t expectedColors[TEST_COLOR_COUNT] = {
263 // H S V
264 { 0, 0, 0 },
265 { 1, 1, 1 },
266 { 359, 255, 255 },
267 { 333, 22, 1 }
270 const char *testColors[TEST_COLOR_COUNT] = {
271 "0,0,0",
272 "1,1,1",
273 "359,255,255",
274 "333,22,1"
277 // when
278 for (uint8_t index = 0; index < TEST_COLOR_COUNT; index++) {
279 #ifdef DEBUG_LEDSTRIP
280 printf("parse iteration: %d\n", index);
281 #endif
283 parseColor(index, testColors[index]);
286 // then
288 for (uint8_t index = 0; index < TEST_COLOR_COUNT; index++) {
289 #ifdef DEBUG_LEDSTRIP
290 printf("iteration: %d\n", index);
291 #endif
293 EXPECT_EQ(expectedColors[index].h, ledStripStatusModeConfig()->colors[index].h);
294 EXPECT_EQ(expectedColors[index].s, ledStripStatusModeConfig()->colors[index].s);
295 EXPECT_EQ(expectedColors[index].v, ledStripStatusModeConfig()->colors[index].v);
299 extern "C" {
301 uint8_t armingFlags = 0;
302 uint8_t stateFlags = 0;
303 uint16_t flightModeFlags = 0;
304 float rcCommand[4];
305 float rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT];
306 extern boxBitmask_t rcModeActivationMask;
307 gpsSolutionData_t gpsSol;
309 batteryState_e getBatteryState(void)
311 return BATTERY_OK;
314 void ws2811LedStripInit(ioTag_t ioTag)
316 UNUSED(ioTag);
319 bool ws2811UpdateStrip(ledStripFormatRGB_e, uint8_t) {return true;}
321 void setLedValue(uint16_t index, const uint8_t value)
323 UNUSED(index);
324 UNUSED(value);
327 void setLedHsv(uint16_t index, const hsvColor_t *color)
329 UNUSED(index);
330 UNUSED(color);
333 void getLedHsv(uint16_t index, hsvColor_t *color)
335 UNUSED(index);
336 UNUSED(color);
340 void scaleLedValue(uint16_t index, const uint8_t scalePercent)
342 UNUSED(index);
343 UNUSED(scalePercent);
346 void setStripColor(const hsvColor_t *color)
348 UNUSED(color);
351 void setStripColors(const hsvColor_t *colors)
353 UNUSED(colors);
356 bool isWS2811LedStripReady(void) { return false; }
358 void delay(uint32_t ms)
360 UNUSED(ms);
361 return;
364 uint32_t micros(void) { return 0; }
366 uint32_t millis(void) { return 0; }
368 bool shouldSoundBatteryAlarm(void) { return false; }
369 bool featureIsEnabled(uint32_t mask)
371 UNUSED(mask);
372 return false;
375 void tfp_sprintf(char *, char*, ...) { }
377 int scaleRange(int x, int srcMin, int srcMax, int destMin, int destMax)
379 UNUSED(x);
380 UNUSED(srcMin);
381 UNUSED(srcMax);
382 UNUSED(destMin);
383 UNUSED(destMax);
385 return 0;
388 bool failsafeIsActive() { return false; }
389 bool rxIsReceivingSignal() { return true; }
391 bool isBeeperOn() { return false; };
393 uint8_t calculateBatteryPercentageRemaining() { return 0; }
394 uint32_t getEstimatedAltitudeCm() { return 0; }
396 bool sensors(uint32_t mask)
398 UNUSED(mask);
399 return false;
402 bool isArmingDisabled(void) { return false; }
404 uint8_t getRssiPercent(void) { return 0; }
406 bool isFlipOverAfterCrashActive(void) { return false; }
408 void ws2811LedStripEnable(void) { }
410 void setUsedLedCount(unsigned) { }
411 void pinioBoxTaskControl(void) {}
412 void rescheduleTask(taskId_e, timeDelta_t){}
413 void schedulerIgnoreTaskExecTime(void) {}
414 void schedulerIgnoreTaskExecRate(void) {}
415 bool schedulerGetIgnoreTaskExecTime() { return false; }
416 void schedulerSetNextStateTime(timeDelta_t) {}