Silence unused-variable warning (#2872)
[ExpressLRS.git] / src / test / test_ota / test_switches.cpp
blob48632323f6e8cfd98b34ee0ec222bdade06f50df
1 /**
2 * This file is part of ExpressLRS
3 * See https://github.com/AlessandroAU/ExpressLRS
5 * Unit tests for over the air packet encoding, decoding and associated utilities
7 * Entry point is setup_switches()
8 */
11 #include <cstdint>
12 #include <iostream>
13 #include <unity.h>
15 #include "targets.h"
16 #include "common.h"
17 #include "CRSF.h"
18 #include "POWERMGNT.h"
19 #include <OTA.h>
20 #include "crsf_sysmocks.h"
22 CRSF crsf; // need an instance to provide the fields used by the code under test
23 uint32_t ChannelData[CRSF_NUM_CHANNELS]; // Current state of channels, CRSF format
24 uint8_t UID[6] = {1,2,3,4,5,6};
26 void test_crsf_endpoints()
28 // Validate 988us and 2012us convert to approprate CRSF values. Spoiler: They don't
29 TEST_ASSERT_EQUAL(-1024, Us_to_OpenTx(988));
30 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_MIN+1, OpenTx_to_Crsf(-1024)); // NOTE: 988 comes from OpenTX as 173, not 172!
31 TEST_ASSERT_EQUAL(1024, Us_to_OpenTx(2012));
32 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_MAX, OpenTx_to_Crsf(1024));
34 // Validate CRSF values convert to their expected values in OpenTX
35 TEST_ASSERT_EQUAL(988, Crsf_to_OpenTx_to_Us(CRSF_CHANNEL_VALUE_MIN));
36 TEST_ASSERT_EQUAL(2012-1, Crsf_to_OpenTx_to_Us(CRSF_CHANNEL_VALUE_MAX)); // NOTE: Feeding the 2012 CRSF value back into OpenTX would give 2011
38 // Validate CRSF values convert to their expected values in Betaflight
39 TEST_ASSERT_EQUAL(988, Crsf_to_BfUs(CRSF_CHANNEL_VALUE_MIN));
40 TEST_ASSERT_EQUAL(2012, Crsf_to_BfUs(CRSF_CHANNEL_VALUE_MAX));
42 // Validate important values are still the same value when mapped and umapped from their 10-bit representations
43 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_MIN, Crsf_to_Uint10_to_Crsf(CRSF_CHANNEL_VALUE_MIN));
44 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_1000, Crsf_to_Uint10_to_Crsf(CRSF_CHANNEL_VALUE_1000));
45 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_MID, Crsf_to_Uint10_to_Crsf(CRSF_CHANNEL_VALUE_MID));
46 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_2000, Crsf_to_Uint10_to_Crsf(CRSF_CHANNEL_VALUE_2000));
47 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_MAX, Crsf_to_Uint10_to_Crsf(CRSF_CHANNEL_VALUE_MAX));
50 void test_crsfToBit()
52 TEST_ASSERT_EQUAL(0, CRSF_to_BIT(CRSF_CHANNEL_VALUE_1000));
53 TEST_ASSERT_EQUAL(1, CRSF_to_BIT(CRSF_CHANNEL_VALUE_2000));
56 void test_bitToCrsf()
58 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_1000, BIT_to_CRSF(0));
59 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_2000, BIT_to_CRSF(1));
62 void test_crsfToN()
64 TEST_ASSERT_EQUAL(0, CRSF_to_N(CRSF_CHANNEL_VALUE_MIN, 64));
65 TEST_ASSERT_EQUAL(0, CRSF_to_N(CRSF_CHANNEL_VALUE_1000, 64));
66 TEST_ASSERT_EQUAL(0b100000, CRSF_to_N(CRSF_CHANNEL_VALUE_MID, 64));
67 TEST_ASSERT_EQUAL(0b111111, CRSF_to_N(CRSF_CHANNEL_VALUE_2000, 64));
68 TEST_ASSERT_EQUAL(0b111111, CRSF_to_N(CRSF_CHANNEL_VALUE_MAX, 64));
70 TEST_ASSERT_EQUAL(0, CRSF_to_N(CRSF_CHANNEL_VALUE_MIN, 128));
71 TEST_ASSERT_EQUAL(0, CRSF_to_N(CRSF_CHANNEL_VALUE_1000, 128));
72 TEST_ASSERT_EQUAL(0b1000000, CRSF_to_N(CRSF_CHANNEL_VALUE_MID, 128));
73 TEST_ASSERT_EQUAL(0b1111111, CRSF_to_N(CRSF_CHANNEL_VALUE_2000, 128));
74 TEST_ASSERT_EQUAL(0b1111111, CRSF_to_N(CRSF_CHANNEL_VALUE_MAX, 128));
77 void test_nToCrsf()
79 // 6-bit
80 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_1000, N_to_CRSF(0, 63));
81 TEST_ASSERT_EQUAL(1004, N_to_CRSF(0b100000, 63));
82 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_2000, N_to_CRSF(0b111111, 63));
84 // 7-bit
85 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_1000, N_to_CRSF(0, 127));
86 TEST_ASSERT_EQUAL(997, N_to_CRSF(0b1000000, 127));
87 TEST_ASSERT_EQUAL(CRSF_CHANNEL_VALUE_2000, N_to_CRSF(0b1111111, 127));
90 // ------------------------------------------------
91 // Test the hybrid8 encoding/decoding
93 /* Check the hybrid 8 encoding of a packet for OTA tx
95 void test_encodingHybrid8(bool highResChannel)
97 constexpr uint8_t N_SWITCHES = 8;
98 uint8_t UID[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE};
99 uint8_t TXdataBuffer[OTA4_PACKET_SIZE] = {0};
100 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
102 // Define the input data
103 // 4 channels of 11-bit analog data
104 ChannelData[0] = 0x0123 & 0b11111111111;
105 ChannelData[1] = 0x4567 & 0b11111111111;
106 ChannelData[2] = 0x89AB & 0b11111111111;
107 ChannelData[3] = 0xCDEF & 0b11111111111;
109 OTA_Packet8_s ota;
110 OTA_Channels_4x10 ch;
111 switch (OtaNonce)
113 case sizeof(ota.rc):
114 break;
115 case 13:
116 break;
117 case 17:
118 break;
119 case sizeof(ch):
120 break;
121 case 8:
122 break;
124 // 8 switches
125 for(int i = 0; i < N_SWITCHES; i++) {
126 constexpr int CHANNELS[] =
127 { CRSF_CHANNEL_VALUE_1000, CRSF_CHANNEL_VALUE_MID, CRSF_CHANNEL_VALUE_2000 };
128 ChannelData[4+i] = CHANNELS[i % 3];
131 // set the nextSwitchIndex so we know which switch to expect in the packet
132 if (highResChannel)
133 OtaSetHybrid8NextSwitchIndex(7-1);
134 else
135 OtaSetHybrid8NextSwitchIndex(3-1);
137 // encode it
138 OtaUpdateSerializers(smHybridOr16ch, OTA4_PACKET_SIZE);
139 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
141 // check it looks right
142 // 1st byte is CRC & packet type
143 uint8_t header = PACKET_TYPE_RCDATA;
144 TEST_ASSERT_EQUAL(header, TXdataBuffer[0]);
146 // bytes 1 through 5 are 10 bit packed analog channels representing 998-2012 (CRSF_CHANNEL_VALUE_MIN-CRSF_CHANNEL_VALUE_MAX)
147 uint8_t expected[5] = { 0x4a, 0xd0, 0xfb, 0x49, 0xd2 };
148 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[1], 5);
150 // byte 6 is the switch encoding
151 TEST_ASSERT_EQUAL(CRSF_to_BIT(ChannelData[4+0]), TXdataBuffer[6] >> 7);
152 // top bit is undefined
153 // expect switch 0 in bit 6
154 // index-1 in 3-5
155 // value in 0,1,2[,3]
156 if (highResChannel)
158 TEST_ASSERT_EQUAL(7, ((TXdataBuffer[6] & 0b110000)>>3) + 1);
159 TEST_ASSERT_EQUAL(CRSF_to_N(ChannelData[4+7], 16), TXdataBuffer[6] & 0b1111);
161 else
163 TEST_ASSERT_EQUAL(3, ((TXdataBuffer[6] & 0b111000)>>3) + 1);
164 TEST_ASSERT_EQUAL(CRSF_to_N(ChannelData[4+3], 6), TXdataBuffer[6] & 0b0111);
168 void test_encodingHybrid8_3()
170 test_encodingHybrid8(false);
173 void test_encodingHybrid8_7()
175 test_encodingHybrid8(true);
178 /* Check the decoding of a packet after rx
180 void test_decodingHybrid8(uint8_t forceSwitch, uint8_t switchval)
182 constexpr uint8_t N_SWITCHES = 8;
183 uint8_t UID[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE};
184 uint8_t TXdataBuffer[OTA4_PACKET_SIZE] = {0};
185 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
186 uint32_t ChannelsIn[16];
187 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
189 // Define the input data
190 // 4 channels of 11-bit analog data
191 ChannelData[0] = 0x0123 & 0b11111111111;
192 ChannelData[1] = 0x4567 & 0b11111111111;
193 ChannelData[2] = 0x89AB & 0b11111111111;
194 ChannelData[3] = 0xCDEF & 0b11111111111;
196 // 8 switches
197 for(int i = 0; i < N_SWITCHES; i++) {
198 constexpr int CHANNELS[] =
199 { CRSF_CHANNEL_VALUE_1000, CRSF_CHANNEL_VALUE_MID, CRSF_CHANNEL_VALUE_2000 };
200 ChannelData[4+i] = CHANNELS[i % 3];
202 if (forceSwitch == 0)
203 ChannelData[4+forceSwitch] = BIT_to_CRSF(switchval);
204 else if (forceSwitch == 7)
205 ChannelData[4+forceSwitch] = N_to_CRSF(switchval, 15);
206 else
207 ChannelData[4+forceSwitch] = SWITCH3b_to_CRSF(switchval);
209 // set the nextSwitchIndex so we know which switch to expect in the packet
210 if (forceSwitch == 0)
211 OtaSetHybrid8NextSwitchIndex(0);
212 else
213 OtaSetHybrid8NextSwitchIndex(forceSwitch-1);
215 // Save the channels since they go into the same place
216 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
217 // use the encoding method to pack it into TXdataBuffer
218 OtaUpdateSerializers(smHybridOr16ch, OTA4_PACKET_SIZE);
219 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
221 // run the decoder, results in crsf->PackedRCdataOut
222 OtaUnpackChannelData(otaPktPtr, ChannelData, 0);
224 // compare the unpacked results with the input data
225 TEST_ASSERT_EQUAL(ChannelsIn[0], ChannelData[0]);
226 TEST_ASSERT_EQUAL(ChannelsIn[1], ChannelData[1]);
227 TEST_ASSERT_EQUAL(ChannelsIn[2], ChannelData[2]);
228 TEST_ASSERT_EQUAL(ChannelsIn[3], ChannelData[3]);
230 TEST_ASSERT_EQUAL(ChannelsIn[4+0], ChannelData[4]); // Switch 0 is sent on every packet
231 if (forceSwitch == 7)
232 TEST_ASSERT_EQUAL(ChannelsIn[4+forceSwitch], ChannelData[11]); // We forced switch 1 to be sent as the sequential field
233 else if (forceSwitch != 0)
234 TEST_ASSERT_EQUAL(ChannelData[4+forceSwitch], ChannelData[4+forceSwitch]);
237 void test_decodingHybrid8_all()
239 // Switch 0 is 2 pos
240 test_decodingHybrid8(0, 0);
241 test_decodingHybrid8(0, 1);
242 // Switch X in 6-pos mode (includes 3-pos low/high)
243 for (uint8_t val=0; val<6; ++val)
244 test_decodingHybrid8(3, val);
245 // // Switch X in 3-pos mode center
246 // test_decodingHybrid8(3, 7);
247 // // Switch 7 is 16 pos
248 // for (uint8_t val=0; val<16; ++val)
249 // test_decodingHybrid8(7, val);
252 /* Check the HybridWide encoding of a packet for OTA tx
254 void test_encodingHybridWide(bool highRes, uint8_t nonce)
256 uint8_t UID[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE};
257 uint8_t TXdataBuffer[OTA4_PACKET_SIZE] = {0};
258 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
259 uint32_t ChannelsIn[16];
260 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
262 // Define the input data
263 // 4 channels of 11-bit analog data
264 ChannelData[0] = 0x0123 & 0b11111111111;
265 ChannelData[1] = 0x4567 & 0b11111111111;
266 ChannelData[2] = 0x89AB & 0b11111111111;
267 ChannelData[3] = 0xCDEF & 0b11111111111;
269 // 8 switches
270 constexpr int N_SWITCHES = 8;
271 for(int i = 0; i < N_SWITCHES; i++) {
272 constexpr unsigned CHANNELS[] =
273 { CRSF_CHANNEL_VALUE_1000, CRSF_CHANNEL_VALUE_MID, CRSF_CHANNEL_VALUE_2000 };
274 ChannelData[4+i] = CHANNELS[i % 3];
277 // Uplink data
278 CRSF::LinkStatistics.uplink_TX_Power = 3; // 100mW
280 // Save the channels since they go into the same place
281 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
282 // encode it
283 uint8_t tlmDenom = (highRes) ? 64 : 4;
284 OtaUpdateSerializers(smWideOr8ch, OTA4_PACKET_SIZE);
285 OtaNonce = nonce;
286 OtaPackChannelData(otaPktPtr, ChannelData, nonce % 2, tlmDenom);
288 // check it looks right
289 // 1st byte is CRC & packet type
290 uint8_t header = PACKET_TYPE_RCDATA;
291 TEST_ASSERT_EQUAL(header, TXdataBuffer[0]);
293 // bytes 1 through 5 are 10 bit packed analog channels representing 998-2012 (CRSF_CHANNEL_VALUE_MIN-CRSF_CHANNEL_VALUE_MAX)
294 uint8_t expected[5] = { 0x4a, 0xd0, 0xfb, 0x49, 0xd2 };
295 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[1], 5);
297 // byte 6 is the switches encoded
298 uint8_t switches = TXdataBuffer[6];
299 uint8_t switchIdx = nonce % 8;
301 // High bit should be AUX1
302 TEST_ASSERT_EQUAL(CRSF_to_BIT(ChannelsIn[4]), switches >> 7);
303 // If low res or slot 7, the bit 6 should be the telemetryack bit
304 if (!highRes || switchIdx == 7)
305 TEST_ASSERT_EQUAL(nonce % 2, (switches >> 6) & 1);
307 // If slot 7, the uplink_TX_Power should be in the low 6 bits
308 if (switchIdx == 7)
309 TEST_ASSERT_EQUAL(CRSF::LinkStatistics.uplink_TX_Power, switches & 0b111111);
310 else
312 uint16_t ch = ChannelData[5+switchIdx];
313 if (highRes)
314 TEST_ASSERT_EQUAL(CRSF_to_N(ch, 128), switches & 0b1111111); // 7-bit
315 else
316 TEST_ASSERT_EQUAL(CRSF_to_N(ch, 64), switches & 0b111111); // 6-bit
320 void test_encodingHybridWide_high()
322 constexpr int N_SWITCHES = 8;
323 for (int i=0; i<N_SWITCHES; ++i)
324 test_encodingHybridWide(true, i);
327 void test_encodingHybridWide_low()
329 constexpr int N_SWITCHES = 8;
330 for (int i=0; i<N_SWITCHES; ++i)
331 test_encodingHybridWide(false, i);
334 /* Check the decoding of a packet after rx in HybridWide mode
336 void test_decodingHybridWide(bool highRes, uint8_t nonce, uint8_t forceSwitch, uint16_t forceVal)
338 uint8_t UID[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE};
339 uint8_t TXdataBuffer[OTA4_PACKET_SIZE] = {0};
340 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
341 uint32_t ChannelsIn[16];
342 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
344 // Define the input data
345 // 4 channels of 11-bit analog data
346 ChannelData[0] = 0x0123 & 0b11111111111;
347 ChannelData[1] = 0x4567 & 0b11111111111;
348 ChannelData[2] = 0x89AB & 0b11111111111;
349 ChannelData[3] = 0xCDEF & 0b11111111111;
351 // 8 switches
352 constexpr int N_SWITCHES = 8;
353 for(int i = 0; i < N_SWITCHES; i++) {
354 constexpr unsigned CHANNELS[] =
355 { CRSF_CHANNEL_VALUE_1000, CRSF_CHANNEL_VALUE_MID, CRSF_CHANNEL_VALUE_2000 };
356 if (i == forceSwitch)
357 ChannelData[4+i] = forceVal;
358 else
359 ChannelData[4+i] = CHANNELS[i % 3];
362 // Uplink data
363 CRSF::LinkStatistics.uplink_TX_Power = 3; // 100mW
365 // Save the channels since they go into the same place
366 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
367 // encode it
368 uint8_t tlmDenom = (highRes) ? 64 : 4;
369 OtaUpdateSerializers(smWideOr8ch, OTA4_PACKET_SIZE);
370 OtaNonce = nonce;
371 OtaPackChannelData(otaPktPtr, ChannelData, nonce % 2, tlmDenom);
373 // Clear the LinkStatistics to receive it from the encoding
374 CRSF::LinkStatistics.uplink_TX_Power = 0;
376 // run the decoder, results in crsf->PackedRCdataOut
377 bool telemResult = OtaUnpackChannelData(otaPktPtr, ChannelData, tlmDenom);
379 // compare the unpacked results with the input data
380 TEST_ASSERT_EQUAL(ChannelsIn[0], ChannelData[0]);
381 TEST_ASSERT_EQUAL(ChannelsIn[1], ChannelData[1]);
382 TEST_ASSERT_EQUAL(ChannelsIn[2], ChannelData[2]);
383 TEST_ASSERT_EQUAL(ChannelsIn[3], ChannelData[3]);
385 // Switch 0 is sent on every packet
386 TEST_ASSERT_EQUAL(ChannelData[4], ChannelData[4]);
388 uint8_t switchIdx = nonce % 8;
389 // Validate the telemResult was unpacked properly
390 if (!highRes || switchIdx == 7)
391 TEST_ASSERT_EQUAL(telemResult, nonce % 2);
393 if (switchIdx == 7)
395 TEST_ASSERT_EQUAL(CRSF::LinkStatistics.uplink_TX_Power, 3);
397 else
399 if (highRes)
400 TEST_ASSERT_EQUAL(N_to_CRSF(CRSF_to_N(ChannelData[5+switchIdx], 128), 127), ChannelData[5+switchIdx]);
401 else
402 TEST_ASSERT_EQUAL(N_to_CRSF(CRSF_to_N(ChannelData[5+switchIdx], 64), 63), ChannelData[5+switchIdx]);
406 void fullres_fillChannelData()
408 // Define the input data
409 // 16 channels of 11-bit analog data
410 ChannelData[0] = 0x0123 & 0b11111111111;
411 ChannelData[1] = 0x4567 & 0b11111111111;
412 ChannelData[2] = 0x89AB & 0b11111111111;
413 ChannelData[3] = 0xCDEF & 0b11111111111;
414 ChannelData[4] = 0x3210 & 0b11111111111;
415 ChannelData[5] = 0x7654 & 0b11111111111;
416 ChannelData[6] = 0xBA98 & 0b11111111111;
417 ChannelData[7] = 0xFEDC & 0b11111111111;
419 ChannelData[8] = 0x2301 & 0b11111111111;
420 ChannelData[9] = 0x6745 & 0b11111111111;
421 ChannelData[10] = 0xAB89 & 0b11111111111;
422 ChannelData[11] = 0xEFCD & 0b11111111111;
423 ChannelData[12] = 0x1023 & 0b11111111111;
424 ChannelData[13] = 0x5476 & 0b11111111111;
425 ChannelData[14] = 0x98BA & 0b11111111111;
426 ChannelData[15] = 0xDCFE & 0b11111111111;
429 void test_encodingFullresPowerLevels()
431 uint8_t TXdataBuffer[OTA8_PACKET_SIZE] = {0};
432 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
433 uint32_t ChannelsIn[16];
434 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
436 OtaUpdateSerializers(smWideOr8ch, OTA8_PACKET_SIZE);
438 for (uint8_t pwr=PWR_10mW; pwr<PWR_COUNT; ++pwr)
440 memset(TXdataBuffer, 0, sizeof(TXdataBuffer));
441 fullres_fillChannelData();
443 // This is what we're testing here, just the power
444 uint8_t crsfPower = powerToCrsfPower((PowerLevels_e)pwr);
445 CRSF::LinkStatistics.uplink_TX_Power = crsfPower;
447 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
448 OtaUnpackChannelData(otaPktPtr, ChannelData, 0);
450 TEST_ASSERT_EQUAL(crsfPower, CRSF::LinkStatistics.uplink_TX_Power);
454 void test_encodingFullres8ch()
456 uint8_t TXdataBuffer[OTA8_PACKET_SIZE] = {0};
457 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
458 uint32_t ChannelsIn[16];
459 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
461 fullres_fillChannelData();
462 CRSF::LinkStatistics.uplink_TX_Power = PWR_250mW;
464 // Save the channels since they go into the same place
465 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
466 OtaUpdateSerializers(smWideOr8ch, OTA8_PACKET_SIZE);
467 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
469 // Low 4ch (CH1-CH4)
470 uint8_t expected[5];
471 expected[0] = ((ChannelsIn[0] >> 1) >> 0);
472 expected[1] = ((ChannelsIn[0] >> 1) >> 8) | ((ChannelsIn[1] >> 1) << 2);
473 expected[2] = ((ChannelsIn[1] >> 1) >> 6) | ((ChannelsIn[2] >> 1) << 4);
474 expected[3] = ((ChannelsIn[2] >> 1) >> 4) | ((ChannelsIn[3] >> 1) << 6);
475 expected[4] = ((ChannelsIn[3] >> 1) >> 2);
476 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chLow)], 5);
477 // High 4ch, skip AUX1 (CH6-CH9)
478 expected[0] = ((ChannelsIn[5] >> 1) >> 0);
479 expected[1] = ((ChannelsIn[5] >> 1) >> 8) | ((ChannelsIn[6] >> 1) << 2);
480 expected[2] = ((ChannelsIn[6] >> 1) >> 6) | ((ChannelsIn[7] >> 1) << 4);
481 expected[3] = ((ChannelsIn[7] >> 1) >> 4) | ((ChannelsIn[8] >> 1) << 6);
482 expected[4] = ((ChannelsIn[8] >> 1) >> 2);
483 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chHigh)], 5);
485 // Check the header bits
486 TEST_ASSERT_EQUAL(PACKET_TYPE_RCDATA, otaPktPtr->full.rc.packetType);
487 TEST_ASSERT_EQUAL(false, otaPktPtr->full.rc.telemetryStatus);
488 TEST_ASSERT_EQUAL(PWR_250mW, otaPktPtr->full.rc.uplinkPower + 1);
489 TEST_ASSERT_EQUAL(false, otaPktPtr->full.rc.isHighAux);
490 TEST_ASSERT_EQUAL(CRSF_to_BIT(ChannelsIn[4]), otaPktPtr->full.rc.ch4);
493 void test_encodingFullres16ch()
495 uint8_t TXdataBuffer[OTA8_PACKET_SIZE] = {0};
496 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
497 uint32_t ChannelsIn[16];
498 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
500 fullres_fillChannelData();
502 // Save the channels since they go into the same place
503 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
504 OtaUpdateSerializers(smHybridOr16ch, OTA8_PACKET_SIZE);
505 OtaSetFullResNextChannelSet(false);
507 // ** PACKET ONE **
508 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
509 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
510 // Low 4ch (CH1-CH4)
511 uint8_t expected[5];
512 expected[0] = ((ChannelsIn[0] >> 1) >> 0);
513 expected[1] = ((ChannelsIn[0] >> 1) >> 8) | ((ChannelsIn[1] >> 1) << 2);
514 expected[2] = ((ChannelsIn[1] >> 1) >> 6) | ((ChannelsIn[2] >> 1) << 4);
515 expected[3] = ((ChannelsIn[2] >> 1) >> 4) | ((ChannelsIn[3] >> 1) << 6);
516 expected[4] = ((ChannelsIn[3] >> 1) >> 2);
517 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chLow)], 5);
518 // High 4ch, includes AUX1 (CH5-CH8)
519 expected[0] = ((ChannelsIn[4] >> 1) >> 0);
520 expected[1] = ((ChannelsIn[4] >> 1) >> 8) | ((ChannelsIn[5] >> 1) << 2);
521 expected[2] = ((ChannelsIn[5] >> 1) >> 6) | ((ChannelsIn[6] >> 1) << 4);
522 expected[3] = ((ChannelsIn[6] >> 1) >> 4) | ((ChannelsIn[7] >> 1) << 6);
523 expected[4] = ((ChannelsIn[7] >> 1) >> 2);
524 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chHigh)], 5);
526 // ** PACKET TWO **
527 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
528 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
529 // Low 4ch (CH9-CH12)
530 expected[0] = ((ChannelsIn[8] >> 1) >> 0);
531 expected[1] = ((ChannelsIn[8] >> 1) >> 8) | ((ChannelsIn[9] >> 1) << 2);
532 expected[2] = ((ChannelsIn[9] >> 1) >> 6) | ((ChannelsIn[10] >> 1) << 4);
533 expected[3] = ((ChannelsIn[10] >> 1) >> 4) | ((ChannelsIn[11] >> 1) << 6);
534 expected[4] = ((ChannelsIn[11] >> 1) >> 2);
535 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chLow)], 5);
536 // High 4ch (CH13-CH16)
537 expected[0] = ((ChannelsIn[12] >> 1) >> 0);
538 expected[1] = ((ChannelsIn[12] >> 1) >> 8) | ((ChannelsIn[13] >> 1) << 2);
539 expected[2] = ((ChannelsIn[13] >> 1) >> 6) | ((ChannelsIn[14] >> 1) << 4);
540 expected[3] = ((ChannelsIn[14] >> 1) >> 4) | ((ChannelsIn[15] >> 1) << 6);
541 expected[4] = ((ChannelsIn[15] >> 1) >> 2);
542 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chHigh)], 5);
545 void test_encodingFullres12ch()
547 uint8_t TXdataBuffer[OTA8_PACKET_SIZE] = {0};
548 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
549 uint32_t ChannelsIn[16];
550 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
552 fullres_fillChannelData();
554 // Save the channels since they go into the same place
555 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
556 OtaUpdateSerializers(sm12ch, OTA8_PACKET_SIZE);
557 OtaSetFullResNextChannelSet(false);
559 // ** PACKET ONE **
560 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
561 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
562 // Low 4ch (CH1-CH4)
563 uint8_t expected[5];
564 expected[0] = ((ChannelsIn[0] >> 1) >> 0);
565 expected[1] = ((ChannelsIn[0] >> 1) >> 8) | ((ChannelsIn[1] >> 1) << 2);
566 expected[2] = ((ChannelsIn[1] >> 1) >> 6) | ((ChannelsIn[2] >> 1) << 4);
567 expected[3] = ((ChannelsIn[2] >> 1) >> 4) | ((ChannelsIn[3] >> 1) << 6);
568 expected[4] = ((ChannelsIn[3] >> 1) >> 2);
569 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chLow)], 5);
570 // High 4ch, skips AUX1 (CH6-CH9)
571 expected[0] = ((ChannelsIn[5] >> 1) >> 0);
572 expected[1] = ((ChannelsIn[5] >> 1) >> 8) | ((ChannelsIn[6] >> 1) << 2);
573 expected[2] = ((ChannelsIn[6] >> 1) >> 6) | ((ChannelsIn[7] >> 1) << 4);
574 expected[3] = ((ChannelsIn[7] >> 1) >> 4) | ((ChannelsIn[8] >> 1) << 6);
575 expected[4] = ((ChannelsIn[8] >> 1) >> 2);
576 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chHigh)], 5);
578 // ** PACKET TWO **
579 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
580 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
581 // Low 4ch (CH1-CH4)
582 expected[0] = ((ChannelsIn[0] >> 1) >> 0);
583 expected[1] = ((ChannelsIn[0] >> 1) >> 8) | ((ChannelsIn[1] >> 1) << 2);
584 expected[2] = ((ChannelsIn[1] >> 1) >> 6) | ((ChannelsIn[2] >> 1) << 4);
585 expected[3] = ((ChannelsIn[2] >> 1) >> 4) | ((ChannelsIn[3] >> 1) << 6);
586 expected[4] = ((ChannelsIn[3] >> 1) >> 2);
587 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chLow)], 5);
588 // Other high 4ch, skip AUX1 (CH10-CH13)
589 expected[0] = ((ChannelsIn[9] >> 1) >> 0);
590 expected[1] = ((ChannelsIn[9] >> 1) >> 8) | ((ChannelsIn[10] >> 1) << 2);
591 expected[2] = ((ChannelsIn[10] >> 1) >> 6) | ((ChannelsIn[11] >> 1) << 4);
592 expected[3] = ((ChannelsIn[11] >> 1) >> 4) | ((ChannelsIn[12] >> 1) << 6);
593 expected[4] = ((ChannelsIn[12] >> 1) >> 2);
594 TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, &TXdataBuffer[offsetof(OTA_Packet8_s, rc.chHigh)], 5);
597 void test_decodingFullres16chLow()
599 uint8_t TXdataBuffer[OTA8_PACKET_SIZE] = {0};
600 OTA_Packet_s * const otaPktPtr = (OTA_Packet_s *)TXdataBuffer;
601 uint32_t ChannelsIn[16];
602 TEST_ASSERT_EQUAL(sizeof(ChannelData), sizeof(ChannelsIn));
604 fullres_fillChannelData();
606 // Save the channels since they go into the same place
607 memcpy(ChannelsIn, ChannelData, sizeof(ChannelData));
608 OtaUpdateSerializers(smHybridOr16ch, OTA8_PACKET_SIZE);
609 OtaSetFullResNextChannelSet(false);
611 // ** PACKET ONE **
612 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
613 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
614 OtaUnpackChannelData(otaPktPtr, ChannelData, 0);
615 for (unsigned ch=0; ch<8; ++ch)
617 TEST_ASSERT_EQUAL(ChannelsIn[ch] & 0b11111111110, ChannelData[ch]);
620 // ** PACKET TWO **
621 memset(TXdataBuffer, 0, sizeof(TXdataBuffer)); // "destChannels4x10 must be zeroed"
622 OtaPackChannelData(otaPktPtr, ChannelData, false, 0);
623 OtaUnpackChannelData(otaPktPtr, ChannelData, 0);
624 for (unsigned ch=9; ch<16; ++ch)
626 TEST_ASSERT_EQUAL(ChannelsIn[ch] & 0b11111111110, ChannelData[ch]);
630 void test_decodingHybridWide_AUX1()
632 // Switch 0 is 2 pos, also tests the uplink_TX_Power
633 test_decodingHybridWide(true, 7, 0, CRSF_CHANNEL_VALUE_1000);
634 test_decodingHybridWide(true, 7, 0, CRSF_CHANNEL_VALUE_2000);
637 void test_decodingHybridWide_AUXX_high()
639 constexpr int N_SWITCHES = 8;
640 for (int i=0; i<N_SWITCHES; ++i)
641 test_decodingHybridWide(true, i, 0, CRSF_CHANNEL_VALUE_1000);
644 void test_decodingHybridWide_AUXX_low()
646 constexpr int N_SWITCHES = 8;
647 for (int i=0; i<N_SWITCHES; ++i)
648 test_decodingHybridWide(false, i, 0, CRSF_CHANNEL_VALUE_1000);
651 // Unity setup/teardown
652 void setUp() {}
653 void tearDown() {}
655 int main(int argc, char **argv)
657 UNITY_BEGIN();
658 RUN_TEST(test_crsf_endpoints);
659 RUN_TEST(test_crsfToBit);
660 RUN_TEST(test_bitToCrsf);
661 RUN_TEST(test_crsfToN);
662 RUN_TEST(test_nToCrsf);
664 RUN_TEST(test_encodingHybrid8_3);
665 RUN_TEST(test_encodingHybrid8_7);
666 RUN_TEST(test_decodingHybrid8_all);
668 RUN_TEST(test_encodingHybridWide_high);
669 RUN_TEST(test_encodingHybridWide_low);
670 RUN_TEST(test_decodingHybridWide_AUX1);
671 RUN_TEST(test_decodingHybridWide_AUXX_high);
672 RUN_TEST(test_decodingHybridWide_AUXX_low);
674 RUN_TEST(test_encodingFullresPowerLevels);
675 RUN_TEST(test_encodingFullres8ch);
676 RUN_TEST(test_encodingFullres16ch);
677 RUN_TEST(test_encodingFullres12ch);
678 RUN_TEST(test_decodingFullres16chLow);
680 UNITY_END();
682 return 0;