8 FL_WARN(
"Verifying jumper wire connection between GPIO " << pin_tx <<
" and GPIO " << pin_rx <<
"...");
10 pinMode(pin_tx, OUTPUT);
11 pinMode(pin_rx, INPUT);
14 digitalWrite(pin_tx, HIGH);
16 int rx_high = digitalRead(pin_rx);
19 digitalWrite(pin_tx, LOW);
21 int rx_low = digitalRead(pin_rx);
23 if (rx_high != HIGH || rx_low != LOW) {
24 FL_ERROR(
"Jumper wire sanity check FAILED!");
25 FL_ERROR(
" digitalWrite(TX=" << pin_tx <<
", HIGH) → digitalRead(RX=" << pin_rx <<
") = " << rx_high <<
" (expected HIGH=1)");
26 FL_ERROR(
" digitalWrite(TX=" << pin_tx <<
", LOW) → digitalRead(RX=" << pin_rx <<
") = " << rx_low <<
" (expected LOW=0)");
28 FL_ERROR(
"REQUIRED: Physically connect GPIO " << pin_tx <<
" to GPIO " << pin_rx <<
" with a jumper wire!");
32 FL_WARN(
"✓ Jumper wire verified: GPIO " << pin_tx <<
" → GPIO " << pin_rx <<
" signal path working");
63 uint32_t tolerance_percent) {
65 FL_WARN(
"[TEST] Captured " << edge_count <<
" edges");
67 if (edge_count == 0) {
73 FL_WARN(
"[TEST] Edge timings:");
74 for (
size_t i = 0; i < edge_count; i++) {
75 FL_WARN(
" [" << i <<
"] " << (edges[i].high ?
"HIGH" :
"LOW ")
76 <<
" " << edges[i].ns <<
"ns (" << (edges[i].ns / 1000) <<
"us)");
80 bool alternation_valid =
true;
81 for (
size_t i = 1; i < edge_count; i++) {
82 if (edges[i].high == edges[i-1].high) {
83 FL_ERROR(
"Sequential " << (edges[i].high ?
"HIGH" :
"LOW")
84 <<
" values at indices " << (i-1) <<
" and " << i
85 <<
" - edges should alternate HIGH/LOW");
86 alternation_valid =
false;
91 bool timing_valid =
true;
92 FL_WARN(
"[TEST] Validating timing accuracy (±" << tolerance_percent <<
"% tolerance):");
96 size_t expected_edge_count = expected_pattern.
size() - 1;
97 if (edge_count != expected_edge_count) {
98 FL_WARN(
"WARNING: Edge count mismatch - expected " << expected_edge_count
99 <<
", got " << edge_count);
100 timing_valid =
false;
103 size_t compare_count = edge_count < expected_edge_count ? edge_count : expected_edge_count;
104 for (
size_t i = 0; i < compare_count; i++) {
105 uint32_t expected_us = expected_pattern[i].delay_us;
106 uint32_t actual_us = edges[i].ns / 1000;
107 bool expected_high = expected_pattern[i].is_high;
108 bool actual_high = edges[i].high;
111 uint32_t tolerance_us = (expected_us * tolerance_percent) / 100;
112 uint32_t min_us = expected_us - tolerance_us;
113 uint32_t max_us = expected_us + tolerance_us;
116 bool timing_ok = (actual_us >= min_us) && (actual_us <= max_us);
117 bool level_ok = (expected_high == actual_high);
119 if (timing_ok && level_ok) {
120 FL_WARN(
" [" << i <<
"] ✓ " << (actual_high ?
"HIGH" :
"LOW ")
121 <<
" " << actual_us <<
"us (expected " << expected_us
122 <<
"us ±" << tolerance_us <<
"us)");
125 FL_WARN(
" [" << i <<
"] ✗ Level mismatch: expected "
126 << (expected_high ?
"HIGH" :
"LOW") <<
", got "
127 << (actual_high ?
"HIGH" :
"LOW"));
128 timing_valid =
false;
131 FL_WARN(
" [" << i <<
"] ✗ Timing out of range: " << actual_us
132 <<
"us (expected " << expected_us <<
"us ±" << tolerance_us
133 <<
"us, range: " << min_us <<
"-" << max_us <<
"us)");
134 timing_valid =
false;
140 if (!alternation_valid) {
141 FL_ERROR(
"Edge timings are not properly alternating");
142 FL_ERROR(
"Expected pattern: HIGH, LOW, HIGH, LOW, ...");
143 FL_ERROR(
"Actual pattern contains sequential identical states");
145 }
else if (!timing_valid) {
146 FL_ERROR(
"Captured edge timings do not match expected pattern");
147 FL_ERROR(
"Check timing accuracy and tolerance settings");
149 }
else if (edge_count >= 5) {
150 FL_WARN(
"[TEST] ✓ PASS: Captured " << edge_count <<
" edges with proper alternation");
151 FL_WARN(
"[TEST] ✓ PASS: All timing values match expected pattern within tolerance");
152 FL_WARN(
"[TEST] ✓ RX channel working correctly!");
155 FL_WARN(
"WARNING: Only captured " << edge_count <<
" edges (expected >=5)");
161 FL_WARN(
"Testing RX channel with low-frequency pattern...");
164 FL_ERROR(
"Failed to test RX channel - null channel provided");
168 int pin_rx = rx->getPin();
177 pinMode(pin_tx, OUTPUT);
178 pinMode(pin_rx, INPUT);
179 digitalWrite(pin_tx, LOW);
182 if (!rx->begin(config)) {
183 FL_ERROR(
"Failed to initialize RX channel");
189 FL_WARN(
"Generating test pattern on GPIO " << pin_tx <<
"...");
190 digitalWrite(pin_tx, HIGH);
192 digitalWrite(pin_tx, LOW);
194 digitalWrite(pin_tx, HIGH);
196 digitalWrite(pin_tx, LOW);
199 FL_WARN(
"Waiting for RX capture...");
200 auto wait_result = rx->wait(100);
203 FL_ERROR(
"RX channel test FAILED - timeout waiting for data");
204 FL_ERROR(
" No edges captured within 100ms");
205 FL_ERROR(
" This suggests the RX channel cannot read from GPIO " << pin_rx);
211 size_t edge_count = rx->getRawEdgeTimes(edge_buffer);
213 if (edge_count < 3) {
214 FL_ERROR(
"RX channel test FAILED - insufficient edges captured");
215 FL_ERROR(
" Expected at least 3 edges, got " << edge_count);
216 FL_ERROR(
" Pin loopback may not be working correctly");
221 bool timing_ok =
true;
222 for (
size_t i = 0; i < edge_count && i < 3; i++) {
223 uint32_t duration_ms = edge_buffer[i].ns / 1000000;
224 if (duration_ms < 5 || duration_ms > 20) {
225 FL_WARN(
"WARNING: Edge " << i <<
" timing unusual: " << duration_ms <<
"ms (expected ~10ms)");
231 FL_WARN(
"✓ RX channel test PASSED");
232 FL_WARN(
" Captured " << edge_count <<
" edges");
233 FL_WARN(
" Timing appears correct (~10ms per edge)");
236 FL_WARN(
"✓ RX channel test PASSED (with timing warnings)");
237 FL_WARN(
" Captured " << edge_count <<
" edges");
238 FL_WARN(
" Timing may be affected by system load");
void executeToggles(fl::RxChannel &rx, fl::span< const PinToggle > toggles, int pin_tx, uint32_t wait_ms)
Execute pin toggles and initialize RX channel for capture.
bool validateEdgeTiming(fl::span< const fl::EdgeTime > edges, size_t edge_count, fl::span< const PinToggle > expected_pattern, uint32_t tolerance_percent)
Validate captured edge timings against expected pattern.