FastLED 3.10.8
Loading...
Searching...
No Matches

◆ decodeFlexPwmEdges()

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

Batch decoder over an edge list (HIGH, LOW, HIGH, ... with a LOW left out after a gap).

Used for injectEdges() and as the reference the streaming decoder must match.

Definition at line 16 of file ws2812_stream_decoder.cpp.hpp.

18 {
19 if (edges.size() == 0 || bytes_out.size() == 0) {
21 }
22
23 // Pre-pass: the adaptive midpoint from the observed HIGH widths.
24 u32 high_min = 0xFFFFFFFFu;
25 u32 high_max = 0u;
26 u32 high_samples = 0;
27 for (size_t k = 0; k + 1 < edges.size(); k += 2) {
28 if (!edges[k].high) continue;
29 const u32 h = edges[k].ns;
30 if (!flexPwmIsMidpointSample(h)) continue;
31 if (h < high_min) high_min = h;
32 if (h > high_max) high_max = h;
33 ++high_samples;
34 }
35 const u32 midpoint =
36 flexPwmAdaptiveMidpointNs(timing, high_min, high_max, high_samples);
37
38 u32 byte_index = 0;
39 u8 current_byte = 0;
40 u32 bit_count = 0;
41 u32 error_count = 0;
42 u32 total_bits = 0;
43
44 size_t i = 0;
45 while (i < edges.size()) {
46 if (!edges[i].high) {
47 ++i; // polarity error: resync on the next HIGH
48 continue;
49 }
50 const u32 high_ns = edges[i].ns;
51 int bit = -1;
52 if (i + 1 == edges.size()) {
53 // The frame's last HIGH: its LOW is the reset, so classify by
54 // HIGH width alone, like a mid-frame bit. (Stopping at the last
55 // edge dropped the frame's final bit: LSB 1 decoded as 0.)
56 bit = flexPwmBitFromMidpoint(high_ns, midpoint);
57 i += 1;
58 } else if (!edges[i + 1].high) {
59 bit = flexPwmBitFromMidpoint(high_ns, midpoint);
60 i += 2;
61 } else {
62 bit = flexPwmBitFromHigh(high_ns, timing);
63 i += 1;
64 }
65 ++total_bits;
66 if (bit < 0) {
67 ++error_count;
68 continue;
69 }
70 current_byte = static_cast<u8>((current_byte << 1) | static_cast<u8>(bit));
71 if (++bit_count == 8) {
72 if (byte_index >= bytes_out.size()) {
75 }
76 bytes_out[byte_index++] = current_byte;
77 current_byte = 0;
78 bit_count = 0;
79 }
80 }
81
82 // Partial final byte, left-aligned.
83 if (bit_count > 0 && byte_index < bytes_out.size()) {
84 bytes_out[byte_index++] = static_cast<u8>(current_byte << (8 - bit_count));
85 }
86 if (total_bits > 0 && (error_count * 10) > total_bits) {
88 }
90}
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
constexpr fl::size size() const FL_NO_EXCEPT
Definition span.h:483
bool flexPwmIsMidpointSample(u32 high_ns) FL_NO_EXCEPT
Whether a HIGH width contributes to the adaptive-midpoint pre-pass (idle and glitch widths are exclud...
int flexPwmBitFromHigh(u32 high_ns, const ChipsetTiming4Phase &timing) FL_NO_EXCEPT
Bit from a HIGH whose LOW was a gap/reset or was not captured: range check against the T0H / T1H wind...
int flexPwmBitFromMidpoint(u32 high_ns, u32 midpoint_ns) FL_NO_EXCEPT
Bit from a HIGH followed by a normal LOW: HIGH-only midpoint split.
u32 flexPwmAdaptiveMidpointNs(const ChipsetTiming4Phase &timing, u32 high_min, u32 high_max, u32 samples) FL_NO_EXCEPT
#3416 adaptive midpoint: (min + max) / 2 of the observed HIGH widths once there are enough samples sp...
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

References fl::BUFFER_OVERFLOW, fl::expected< T, E >::failure(), fl::FL_NO_EXCEPT, flexPwmAdaptiveMidpointNs(), flexPwmBitFromHigh(), flexPwmBitFromMidpoint(), flexPwmIsMidpointSample(), fl::HIGH_ERROR_RATE, and fl::expected< T, E >::success().

+ Here is the call graph for this function: