| 28 | #include "test.h" |
| 29 | |
| 30 | FL_TEST_FILE(FL_FILEPATH) { |
| 31 | |
| 32 | using namespace fl; |
| 33 | |
| 34 | namespace { |
| 35 | |
| 36 | // WS2812B 4-phase decoder timings. Same nominal values as `WS2812Chipset`: |
| 37 | // T0H = 400 ns, T0L = 850 ns, T1H = 800 ns, T1L = 450 ns. |
| 38 | // We use ±150 ns tolerance so an idealised generator (no jitter) is |
| 39 | // comfortably inside the window without making bit-1 / bit-0 ambiguous. |
| 40 | ChipsetTiming4Phase ws2812_timing() { |
| 41 | ChipsetTiming4Phase t{}; |
| 42 | t.t0h_min_ns = 250; t.t0h_max_ns = 550; |
| 43 | t.t0l_min_ns = 700; t.t0l_max_ns = 1000; |
| 44 | t.t1h_min_ns = 650; t.t1h_max_ns = 950; |
| 45 | t.t1l_min_ns = 300; t.t1l_max_ns = 600; |
| 46 | t.reset_min_us = 50; |
| 47 | t.gap_tolerance_ns = 0; |
| 48 | return t; |
| 49 | } |
| 50 | |
| 51 | // Emit one byte's worth of edge pairs (MSB first) into the buffer. |
| 52 | template <fl::size N> |
| 53 | void appendByte(fl::vector<EdgeTime>& edges, u8 byte) { |
| 54 | for (int bit = 7; bit >= 0; --bit) { |
| 55 | bool one = ((byte >> bit) & 0x1) != 0; |
| 56 | edges.push_back(EdgeTime(true, one ? 800u : 400u)); // HIGH |
| 57 | edges.push_back(EdgeTime(false, one ? 450u : 850u)); // LOW |
| 58 | } |
| 59 | (void)N; |
| 60 | } |
| 61 | |
| 62 | // Wrap a `fl::vector<EdgeTime>` as a span for injectEdges(). |
| 63 | fl::span<const EdgeTime> toSpan(const fl::vector<EdgeTime>& v) { |
| 64 | return fl::span<const EdgeTime>(v.data(), v.size()); // ok span from pointer — fl::vector → span<const T> conversion does not exist on this code path |
| 65 | } |
| 66 | |
| 67 | } // namespace |
| 68 | |
| 69 | FL_TEST_CASE("RxBackend toString includes LPC_SCT_CAPTURE") { |
| 70 | FL_CHECK(fl::strcmp(toString(RxBackend::LPC_SCT_CAPTURE), "LPC_SCT_CAPTURE") == 0); |
| 71 | FL_CHECK(fl::strcmp(toString(RxDeviceType::LPC_SCT_CAPTURE), "LPC_SCT_CAPTURE") == 0); |
| 72 | } |
| 73 | |
| 74 | FL_TEST_CASE("RxDevice::create<LPC_SCT_CAPTURE> returns a non-null device on every platform") { |
| 75 | auto device = RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(11); // P0_11 on LPC845-BRK |
| 76 | FL_REQUIRE(device != nullptr); |
| 77 | FL_REQUIRE(device->name() != nullptr); |
| 78 | FL_CHECK(device->getPin() == 11); |
| 79 | } |
| 80 | |
| 81 | FL_TEST_CASE("LPC SCT-capture: injectEdges -> decode round-trips a known WS2812 GRB byte stream") { |
| 82 | auto device = RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(11); |
| 83 | FL_REQUIRE(device != nullptr); |
| 84 | |
| 85 | RxConfig config; |
| 86 | config.buffer_size = 256; |
| 87 | config.start_low = true; |
nothing calls this directly
no test coverage detected