FastLED 3.9.15
Loading...
Searching...
No Matches

◆ decodeWs2812Edges()

fl::result< u32, DecodeError > fl::channels::rx::decodeWs2812Edges ( const ChipsetTiming4Phase & timing,
fl::span< const EdgeTime > edges,
fl::span< u8 > out )

Decode a WS2812 edge-pair stream into bytes.

Parameters
timing4-phase timing thresholds (T0H/T0L/T1H/T1L windows + reset).
edgesCaptured edge stream. Each WS2812 bit is one HIGH edge followed by one LOW edge, both labelled with their duration in ns.
outDestination byte buffer. MSB-first per WS2812 wire order.
Returns
Number of decoded bytes on success, or a DecodeError on buffer overflow / >10 % error rate. An empty edges span returns INVALID_ARGUMENT so callers can distinguish "no data captured" from "captured but garbage".

Definition at line 17 of file decode_ws2812.cpp.hpp.

19 {
20 const size_t edge_count = edges.size();
21 if (edge_count == 0) {
23 }
24
25 size_t bytes_written = 0;
26 size_t bit_index = 0;
27 u8 current_byte = 0;
28 u32 error_count = 0;
29
30 size_t i = 0;
31 while (i + 1 < edge_count) {
32 const EdgeTime high_edge = edges[i];
33 const EdgeTime low_edge = edges[i + 1];
34
35 if (!high_edge.high || low_edge.high) {
36 error_count++;
37 i++;
38 continue;
39 }
40
41 const u32 high_ns = high_edge.ns;
42 const u32 low_ns = low_edge.ns;
43
44 bool is_bit1 = (high_ns >= timing.t1h_min_ns && high_ns <= timing.t1h_max_ns &&
45 low_ns >= timing.t1l_min_ns && low_ns <= timing.t1l_max_ns);
46 bool is_bit0 = (high_ns >= timing.t0h_min_ns && high_ns <= timing.t0h_max_ns &&
47 low_ns >= timing.t0l_min_ns && low_ns <= timing.t0l_max_ns);
48
49 if (!is_bit0 && !is_bit1) {
50 if (low_ns >= static_cast<u32>(timing.reset_min_us) * 1000u) {
51 break; // WS2812 reset pulse -> end of frame
52 }
53 if (timing.gap_tolerance_ns > 0 && low_ns <= timing.gap_tolerance_ns) {
54 if (high_ns >= timing.t1h_min_ns && high_ns <= timing.t1h_max_ns) {
55 is_bit1 = true;
56 } else if (high_ns >= timing.t0h_min_ns && high_ns <= timing.t0h_max_ns) {
57 is_bit0 = true;
58 }
59 }
60 if (!is_bit0 && !is_bit1) {
61 error_count++;
62 i += 2;
63 continue;
64 }
65 }
66
67 const u8 bit = is_bit1 ? u8{1} : u8{0};
68 current_byte = static_cast<u8>((current_byte << 1) | bit);
69 bit_index++;
70
71 if (bit_index == 8) {
72 if (bytes_written >= out.size()) {
74 }
75 out[bytes_written++] = current_byte;
76 current_byte = 0;
77 bit_index = 0;
78 }
79
80 i += 2;
81 }
82
83 if (bytes_written > 0 && error_count * 10 > bytes_written * 8) {
85 }
86
87 return fl::result<u32, DecodeError>::success(static_cast<u32>(bytes_written));
88}
static expected failure(E err, const char *msg=nullptr) FL_NOEXCEPT
Create error result.
Definition expected.h:115
static expected success(T value) FL_NOEXCEPT
Create successful result.
Definition expected.h:108
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
unsigned char u8
Definition stdint.h:131
@ HIGH_ERROR_RATE
Symbol decode error rate too high (>10%)
Definition rx.h:70
@ BUFFER_OVERFLOW
Output buffer overflow.
Definition rx.h:71
@ INVALID_ARGUMENT
Invalid input arguments.
Definition rx.h:72
u32 t1h_min_ns
Bit 1 high time minimum (e.g., 650ns)
Definition rx.h:95
u32 reset_min_us
Reset pulse minimum duration (e.g., 50us)
Definition rx.h:101
u32 gap_tolerance_ns
Maximum gap duration to tolerate (0 = no gap tolerance, treat as error)
Definition rx.h:104
u32 t0l_min_ns
Bit 0 low time minimum (e.g., 700ns)
Definition rx.h:91
u32 t1l_min_ns
Bit 1 low time minimum (e.g., 300ns)
Definition rx.h:97
u32 t1h_max_ns
Bit 1 high time maximum (e.g., 950ns)
Definition rx.h:96
u32 t0h_min_ns
Bit 0 high time minimum (e.g., 250ns)
Definition rx.h:89
u32 t0h_max_ns
Bit 0 high time maximum (e.g., 550ns)
Definition rx.h:90
u32 t1l_max_ns
Bit 1 low time maximum (e.g., 600ns)
Definition rx.h:98
u32 t0l_max_ns
Bit 0 low time maximum (e.g., 1000ns)
Definition rx.h:92
u32 ns
Duration in nanoseconds (31 bits, max ~2.1s)
Definition rx.h:35
u32 high
High/low level (1 bit: 1=high, 0=low)
Definition rx.h:36
Universal edge timing representation (platform-agnostic)
Definition rx.h:34

References fl::BUFFER_OVERFLOW, fl::expected< T, E >::failure(), FL_NOEXCEPT, fl::EdgeTime::high, fl::HIGH_ERROR_RATE, fl::INVALID_ARGUMENT, fl::EdgeTime::ns, and fl::expected< T, E >::success().

+ Here is the call graph for this function: