STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_main.cpp
Go to the documentation of this file.
1// Tests for the SX1262 receive path, run against a pretend chip.
2#include <string.h>
3
4#include "fake_chip.h"
5#include "unity.h"
6
7// Build the code under test.
9
10using namespace radio_link;
11
13
14void setUp(void) {
15 chip.reset();
16}
17void tearDown(void) {
18}
19
20// The UN_ARM frame from the message-format examples.
21static const uint8_t kFrame[7] = {0x01, 0x11, 0x05, 0x00, 0x00, 0xBE, 0x3D};
22
24 Sx1262 radio(chip);
25 uint8_t buf[16];
26 uint8_t len = 0xAB;
27 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
28 TEST_ASSERT_EQUAL_UINT8(0xAB, len); // len is left alone on NoData
29 // Only the "what happened?" question was asked.
30 TEST_ASSERT_EQUAL_UINT(1, chip.commands_logged());
31 TEST_ASSERT_EQUAL_HEX8(kOpGetIrqStatus, chip.command_at(0));
32}
33
35 Sx1262 radio(chip);
36 chip.packet_arrives(kFrame, sizeof kFrame, 0);
37 uint8_t buf[16];
38 uint8_t len = 0;
39 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
40 TEST_ASSERT_EQUAL_UINT8(sizeof kFrame, len);
41 TEST_ASSERT_EQUAL_HEX8_ARRAY(kFrame, buf, sizeof kFrame);
42}
43
45 Sx1262 radio(chip);
46 chip.packet_arrives(kFrame, sizeof kFrame, 0);
47 uint8_t buf[16];
48 uint8_t len = 0;
49 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
50 TEST_ASSERT_EQUAL_UINT(4, chip.commands_logged());
51 TEST_ASSERT_EQUAL_HEX8(kOpGetIrqStatus, chip.command_at(0));
52 TEST_ASSERT_EQUAL_HEX8(kOpGetRxBufferStatus, chip.command_at(1));
53 TEST_ASSERT_EQUAL_HEX8(kOpReadBuffer, chip.command_at(2));
54 TEST_ASSERT_EQUAL_HEX8(kOpClearIrqStatus, chip.command_at(3));
55}
56
58 Sx1262 radio(chip);
59 chip.packet_arrives(kFrame, sizeof kFrame, 200); // not at position 0
60 uint8_t buf[16];
61 uint8_t len = 0;
62 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
63 TEST_ASSERT_EQUAL_HEX8_ARRAY(kFrame, buf, sizeof kFrame);
64}
65
67 Sx1262 radio(chip);
68 chip.packet_arrives(kFrame, sizeof kFrame, 0);
69 uint8_t buf[16];
70 uint8_t len = 0;
71 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
72 TEST_ASSERT_EQUAL_HEX16(0, chip.irq());
73 // The packet is used up, so the next call finds nothing.
74 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
75}
76
78 Sx1262 radio(chip);
79 uint8_t big[255];
80 for (unsigned i = 0; i < sizeof big; i++) {
81 big[i] = static_cast<uint8_t>(i * 7 + 1);
82 }
83 chip.packet_arrives(big, sizeof big, 100); // wraps past the buffer end
84 uint8_t buf[255];
85 uint8_t len = 0;
86 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
87 TEST_ASSERT_EQUAL_UINT8(255, len);
88 TEST_ASSERT_EQUAL_HEX8_ARRAY(big, buf, sizeof big);
89}
90
92 Sx1262 radio(chip);
93 chip.packet_arrives(kFrame, sizeof kFrame, 0);
94 uint8_t small[4];
95 uint8_t len = 0xAB;
96 TEST_ASSERT_EQUAL(RadioStatus::ErrTooLong,
97 radio.receive(small, sizeof small, len));
98 TEST_ASSERT_EQUAL_UINT8(0xAB, len);
99 // We never read the bytes, and the flag was cleared.
100 TEST_ASSERT_EQUAL_UINT(3, chip.commands_logged());
101 TEST_ASSERT_EQUAL_HEX8(kOpClearIrqStatus, chip.command_at(2));
102 TEST_ASSERT_EQUAL_HEX16(0, chip.irq());
103 TEST_ASSERT_EQUAL(RadioStatus::NoData,
104 radio.receive(small, sizeof small, len));
105}
106
108 Sx1262 radio(chip);
109 chip.packet_arrives(kFrame, sizeof kFrame, 0, kIrqCrcErr);
110 uint8_t buf[16];
111 uint8_t len = 0xAB;
112 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
113 TEST_ASSERT_EQUAL_UINT8(0xAB, len);
114 TEST_ASSERT_EQUAL_UINT(2, chip.commands_logged()); // asked, then cleared
115 TEST_ASSERT_EQUAL_HEX16(0, chip.irq());
116}
117
119 Sx1262 radio(chip);
120 chip.packet_arrives(kFrame, sizeof kFrame, 0, kIrqHeaderErr);
121 uint8_t buf[16];
122 uint8_t len = 0xAB;
123 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
124 TEST_ASSERT_EQUAL_UINT(2, chip.commands_logged());
125 TEST_ASSERT_EQUAL_HEX16(0, chip.irq());
126}
127
129 Sx1262 radio(chip);
130 chip.set_irq(kIrqRxDone); // "received", but the length stays 0
131 uint8_t buf[16];
132 uint8_t len = 0xAB;
133 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
134 TEST_ASSERT_EQUAL_UINT8(0xAB, len);
135 TEST_ASSERT_EQUAL_HEX16(0, chip.irq());
136}
137
139 Sx1262 radio(chip);
140 chip.packet_arrives(kFrame, sizeof kFrame, 0);
141 chip.set_never_ready();
142 uint8_t buf[16];
143 uint8_t len = 0xAB;
144 TEST_ASSERT_EQUAL(RadioStatus::ErrNotFound,
145 radio.receive(buf, sizeof buf, len));
146 TEST_ASSERT_EQUAL_UINT(0, chip.transfers()); // we never spoke to it
147 TEST_ASSERT_EQUAL_UINT8(0xAB, len);
148}
149
151 Sx1262 radio(chip);
152 chip.packet_arrives(kFrame, sizeof kFrame, 0);
153 uint8_t buf[16];
154 uint8_t len = 0;
155 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
156 TEST_ASSERT_EQUAL_UINT(chip.transfers(), chip.waits());
157}
158
159// No chip at all: MISO floats or is held at one level. Before the status
160// check, 0x00 read as "no flags" and 0xFF as "header + CRC error", so a dead
161// radio looked like a quiet one.
163 Sx1262 radio(chip);
164 chip.set_stuck(0x00);
165 uint8_t buf[16];
166 uint8_t len = 0;
167 TEST_ASSERT_EQUAL(RadioStatus::ErrNotFound,
168 radio.receive(buf, sizeof buf, len));
169}
170
172 Sx1262 radio(chip);
173 chip.set_stuck(0xFF);
174 uint8_t buf[16];
175 uint8_t len = 0;
176 TEST_ASSERT_EQUAL(RadioStatus::ErrNotFound,
177 radio.receive(buf, sizeof buf, len));
178}
179
180// A live chip reporting a failed command (mode RX, status 5 "failure to
181// execute": 0x5A) is not treated as "no packet".
183 Sx1262 radio(chip);
184 chip.set_status(0x5A);
185 uint8_t buf[16];
186 uint8_t len = 0;
187 TEST_ASSERT_EQUAL(RadioStatus::ErrNotFound,
188 radio.receive(buf, sizeof buf, len));
189}
190
191// A bad status in a later reply (GetRxBufferStatus) is caught too, and no
192// packet is handed out.
194 Sx1262 radio(chip);
195 chip.packet_arrives(kFrame, sizeof kFrame, 0);
196 chip.set_status(0x58); // mode RX, status 4 "processing error"
197 uint8_t buf[16];
198 uint8_t len = 0xAB;
199 TEST_ASSERT_EQUAL(RadioStatus::ErrNotFound,
200 radio.receive(buf, sizeof buf, len));
201 TEST_ASSERT_EQUAL_UINT8(0xAB, len);
202}
203
204// SetRx with timeout 0xFFFFFF = continuous RX (datasheet pages 62 and 70).
206 Sx1262 radio(chip);
207 TEST_ASSERT_TRUE(radio.start_rx_continuous());
208 const uint8_t expected[4] = {0x82, 0xFF, 0xFF, 0xFF};
209 TEST_ASSERT_EQUAL_UINT(4, chip.last_len());
210 for (unsigned i = 0; i < 4; i++) {
211 TEST_ASSERT_EQUAL_HEX8(expected[i], chip.last_byte(i));
212 }
213 TEST_ASSERT_EQUAL_UINT(1, chip.waits()); // BUSY checked first
214}
215
217 Sx1262 radio(chip);
218 chip.set_never_ready();
219 TEST_ASSERT_FALSE(radio.start_rx_continuous());
220 TEST_ASSERT_EQUAL_UINT(0, chip.transfers());
221}
222
224 Sx1262 radio(chip);
225 uint8_t buf[16];
226 uint8_t len = 0;
227 chip.set_irq(kIrqCrcErr);
228 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
229 chip.set_irq(kIrqHeaderErr);
230 TEST_ASSERT_EQUAL(RadioStatus::NoData, radio.receive(buf, sizeof buf, len));
231 TEST_ASSERT_EQUAL_UINT32(2, radio.crc_errors());
232 // A good packet does not count.
233 chip.packet_arrives(kFrame, sizeof kFrame, 0);
234 TEST_ASSERT_EQUAL(RadioStatus::Ok, radio.receive(buf, sizeof buf, len));
235 TEST_ASSERT_EQUAL_UINT32(2, radio.crc_errors());
236}
237
238// GetPacketStatus: 0x14 then four NOPs; RSSI = -RssiPkt/2 dBm, SNR =
239// SnrPkt/4 dB in two's complement (datasheet Rev 1.2, Table 13-80, p.96).
241 Sx1262 radio(chip);
242 PacketStatus ps;
243 TEST_ASSERT_TRUE(radio.packet_status(ps));
244 TEST_ASSERT_EQUAL_UINT(1, chip.commands_logged());
245 TEST_ASSERT_EQUAL_UINT(5, chip.last_len());
246 TEST_ASSERT_EQUAL_HEX8(kOpGetPacketStatus, chip.last_byte(0));
247 for (unsigned i = 1; i < 5; i++) {
248 TEST_ASSERT_EQUAL_HEX8(0x00, chip.last_byte(i));
249 }
250}
251
253 Sx1262 radio(chip);
254 // RssiPkt 0xB5 = 181 -> -90.5 dBm; SnrPkt 0xEC = -20 -> -5 dB;
255 // SignalRssiPkt 0xC8 = 200 -> -100 dBm.
256 chip.set_packet_status(0xB5, 0xEC, 0xC8);
257 PacketStatus ps;
258 TEST_ASSERT_TRUE(radio.packet_status(ps));
259 TEST_ASSERT_EQUAL_INT16(-181, ps.rssi_x2);
260 TEST_ASSERT_EQUAL_INT8(-20, ps.snr_x4);
261 TEST_ASSERT_EQUAL_INT16(-200, ps.signal_rssi_x2);
262}
263
265 Sx1262 radio(chip);
266 chip.set_packet_status(0x50, 0x28, 0x52); // -40 dBm, +10 dB, -41 dBm
267 PacketStatus ps;
268 TEST_ASSERT_TRUE(radio.packet_status(ps));
269 TEST_ASSERT_EQUAL_INT16(-80, ps.rssi_x2);
270 TEST_ASSERT_EQUAL_INT8(40, ps.snr_x4);
271 TEST_ASSERT_EQUAL_INT16(-82, ps.signal_rssi_x2);
272}
273
275 Sx1262 radio(chip);
276 chip.set_stuck(0x00);
277 PacketStatus ps = {7, 7, 7};
278 TEST_ASSERT_FALSE(radio.packet_status(ps));
279 TEST_ASSERT_EQUAL_INT16(7, ps.rssi_x2);
280 TEST_ASSERT_EQUAL_INT8(7, ps.snr_x4);
281}
282
284 Sx1262 radio(chip);
285 chip.set_never_ready();
286 PacketStatus ps;
287 TEST_ASSERT_FALSE(radio.packet_status(ps));
288 TEST_ASSERT_EQUAL_UINT(0, chip.transfers());
289}
290
int main()
static void test_start_rx_continuous_sends_setrx_ffffff(void)
static void test_header_error_drops_the_packet(void)
static const uint8_t kFrame[7]
Definition test_main.cpp:21
static void test_no_flags_returns_no_data(void)
Definition test_main.cpp:23
static void test_biggest_packet_255_bytes_is_read_whole(void)
Definition test_main.cpp:77
static void test_command_failure_status_reports_not_found(void)
static void test_radio_crc_error_drops_the_packet(void)
static void test_packet_flag_is_cleared_after_reading(void)
Definition test_main.cpp:66
static void test_the_four_exchanges_happen_in_order(void)
Definition test_main.cpp:44
static void test_zero_length_packet_is_dropped(void)
static void test_busy_is_checked_before_every_exchange(void)
void setUp(void)
Definition test_main.cpp:14
void tearDown(void)
Definition test_main.cpp:17
static FakeChip chip
Definition test_main.cpp:12
static void test_packet_status_missing_chip_leaves_output_alone(void)
static void test_packet_status_sends_0x14_and_four_nops(void)
static void test_damaged_packets_are_counted(void)
static void test_packet_bigger_than_the_box_is_dropped(void)
Definition test_main.cpp:91
static void test_packet_status_busy_never_clears(void)
static void test_chip_stuck_busy_reports_not_found(void)
static void test_bad_status_while_reading_a_packet_reports_not_found(void)
static void test_packet_is_read_with_the_right_bytes_and_length(void)
Definition test_main.cpp:34
static void test_missing_chip_reading_zeros_reports_not_found(void)
static void test_start_position_in_the_chip_buffer_is_used(void)
Definition test_main.cpp:57
static void test_packet_status_converts_rssi_and_negative_snr(void)
static void test_packet_status_positive_snr(void)
static void test_start_rx_continuous_fails_when_busy_never_clears(void)
static void test_missing_chip_reading_ones_reports_not_found(void)