FastLED 3.10.8
Loading...
Searching...
No Matches
decode_ws2812.cpp.hpp
Go to the documentation of this file.
1
7
8// IWYU pragma: private
9
11
12namespace fl {
13namespace channels {
14namespace rx {
15
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 // #3416 RX-HIGH-5: also break on a long HIGH between frames.
54 // The FlexIO RX path observed sustained HIGH-state between
55 // frames (#3066, FlexIO TX shifter latch retention) where
56 // the line stayed high for many milliseconds. Without this
57 // branch a single stray falling edge after the long HIGH
58 // would misclassify a phantom bit cell of arbitrary
59 // duration as a real WS2812 bit.
60 if (high_ns >= static_cast<u32>(timing.reset_min_us) * 1000u) {
61 break;
62 }
63 if (timing.gap_tolerance_ns > 0 && low_ns <= timing.gap_tolerance_ns) {
64 if (high_ns >= timing.t1h_min_ns && high_ns <= timing.t1h_max_ns) {
65 is_bit1 = true;
66 } else if (high_ns >= timing.t0h_min_ns && high_ns <= timing.t0h_max_ns) {
67 is_bit0 = true;
68 }
69 }
70 if (!is_bit0 && !is_bit1) {
71 error_count++;
72 i += 2;
73 continue;
74 }
75 }
76
77 const u8 bit = is_bit1 ? u8{1} : u8{0};
78 current_byte = static_cast<u8>((current_byte << 1) | bit);
79 bit_index++;
80
81 if (bit_index == 8) {
82 if (bytes_written >= out.size()) {
84 }
85 out[bytes_written++] = current_byte;
86 current_byte = 0;
87 bit_index = 0;
88 }
89
90 i += 2;
91 }
92
93 if (bytes_written > 0 && error_count * 10 > bytes_written * 8) {
95 }
96
97 return fl::result<u32, DecodeError>::success(static_cast<u32>(bytes_written));
98}
99
100} // namespace rx
101} // namespace channels
102} // namespace fl
static expected failure(E err, const char *msg=nullptr) FL_NO_EXCEPT
Create error result.
Definition expected.h:115
static expected success(T value) FL_NO_EXCEPT
Create successful result.
Definition expected.h:108
Shared 4-phase WS2812 edge-pair -> byte decoder (declaration).
fl::result< u32, DecodeError > decodeWs2812Edges(const ChipsetTiming4Phase &timing, fl::span< const EdgeTime > edges, fl::span< u8 > out) FL_NO_EXCEPT
Decode a WS2812 edge-pair stream into bytes.
unsigned char u8
Definition stdint.h:131
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
@ 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
Base definition for an LED controller.
Definition crgb.hpp:179
4-phase RX timing thresholds for chipset detection
Definition rx.h:88
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