25 const Wave8BitExpansionLut& lut,
27 const Wave8Bit* high_nibble_data = lut.lut[(byte_value >> 4) & 0xF];
32 const Wave8Bit* low_nibble_data = lut.lut[byte_value & 0xF];
40 const Wave8ByteExpansionLut& lut,
50 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
53 lane_waves[1].symbols[symbol_idx].data,
56 output[symbol_idx * 2] = (
u8)(interleaved >> 8);
57 output[symbol_idx * 2 + 1] = (
u8)(interleaved & 0xFF);
64 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
65 u8 l0 = lane_waves[0].symbols[symbol_idx].data;
66 u8 l1 = lane_waves[1].symbols[symbol_idx].data;
67 u8 l2 = lane_waves[2].symbols[symbol_idx].data;
68 u8 l3 = lane_waves[3].symbols[symbol_idx].data;
70 output[symbol_idx * 4 + 0] =
71 ((l3 >> 7) & 1) << 7 |
72 ((l2 >> 7) & 1) << 6 |
73 ((l1 >> 7) & 1) << 5 |
74 ((l0 >> 7) & 1) << 4 |
75 ((l3 >> 6) & 1) << 3 |
76 ((l2 >> 6) & 1) << 2 |
77 ((l1 >> 6) & 1) << 1 |
80 output[symbol_idx * 4 + 1] =
81 ((l3 >> 5) & 1) << 7 |
82 ((l2 >> 5) & 1) << 6 |
83 ((l1 >> 5) & 1) << 5 |
84 ((l0 >> 5) & 1) << 4 |
85 ((l3 >> 4) & 1) << 3 |
86 ((l2 >> 4) & 1) << 2 |
87 ((l1 >> 4) & 1) << 1 |
90 output[symbol_idx * 4 + 2] =
91 ((l3 >> 3) & 1) << 7 |
92 ((l2 >> 3) & 1) << 6 |
93 ((l1 >> 3) & 1) << 5 |
94 ((l0 >> 3) & 1) << 4 |
95 ((l3 >> 2) & 1) << 3 |
96 ((l2 >> 2) & 1) << 2 |
97 ((l1 >> 2) & 1) << 1 |
100 output[symbol_idx * 4 + 3] =
101 ((l3 >> 1) & 1) << 7 |
102 ((l2 >> 1) & 1) << 6 |
103 ((l1 >> 1) & 1) << 5 |
104 ((l0 >> 1) & 1) << 4 |
105 ((l3 >> 0) & 1) << 3 |
106 ((l2 >> 0) & 1) << 2 |
107 ((l1 >> 0) & 1) << 1 |
115 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
117 for (
int lane = 0; lane < 8; lane++) {
118 l[lane] = lane_waves[lane].symbols[symbol_idx].data;
127 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
129 for (
int lane = 0; lane < 16; lane++) {
130 l[lane] = lane_waves[lane].symbols[symbol_idx].data;
138 const Wave8Byte lane_waves_b[16],
139 u8 output_a[16 *
sizeof(Wave8Byte)],
141 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
144 for (
int lane = 0; lane < 16; lane++) {
145 la[lane] = lane_waves_a[lane].symbols[symbol_idx].data;
146 lb[lane] = lane_waves_b[lane].symbols[symbol_idx].data;
155 const Wave8Byte lane_waves_b[16],
156 const Wave8Byte lane_waves_c[16],
157 const Wave8Byte lane_waves_d[16],
158 u8 output_a[16 *
sizeof(Wave8Byte)],
159 u8 output_b[16 *
sizeof(Wave8Byte)],
160 u8 output_c[16 *
sizeof(Wave8Byte)],
162 for (
int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
167 for (
int lane = 0; lane < 16; lane++) {
168 la[lane] = lane_waves_a[lane].symbols[symbol_idx].data;
169 lb[lane] = lane_waves_b[lane].symbols[symbol_idx].data;
170 lc[lane] = lane_waves_c[lane].symbols[symbol_idx].data;
171 ld[lane] = lane_waves_d[lane].symbols[symbol_idx].data;
186 const u8 D_byte =
W0 ^
W1;
187 for (
int p = 0; p < 8; ++p) {
188 const int shift = 7 - p;
189 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
190 m0_mask[p] = ((
W0 >> shift) & 1) ? 0xFFu : 0x00u;
194 for (
int s = 0; s < 8; ++s) {
195 const u8 col_lo = cols[2 * s + 0];
196 const u8 col_hi = cols[2 * s + 1];
197 for (
int p = 0; p < 8; ++p) {
198 output[s * 16 + p * 2 + 0] = m0_mask[p] ^ (col_lo & d_mask[p]);
199 output[s * 16 + p * 2 + 1] = m0_mask[p] ^ (col_hi & d_mask[p]);
210 const u8 D_byte =
W0 ^
W1;
211 for (
int p = 0; p < 8; ++p) {
212 const int shift = 7 - p;
213 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
214 m0_mask[p] = ((
W0 >> shift) & 1) ? 0xFFu : 0x00u;
218 for (
int s = 0; s < 8; ++s) {
219 const u8 col = cols[s];
220 for (
int p = 0; p < 8; ++p) {
221 output[s * 8 + p] = m0_mask[p] ^ (col & d_mask[p]);
232 const u8 D_byte =
W0 ^
W1;
233 for (
int p = 0; p < 8; ++p) {
234 const int shift = 7 - p;
235 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
236 m0_mask[p] = ((
W0 >> shift) & 1) ? 0xFFu : 0x00u;
243 cols[0] =
static_cast<u8>(aLo);
244 cols[1] =
static_cast<u8>(aLo >> 8);
245 cols[2] =
static_cast<u8>(aLo >> 16);
246 cols[3] =
static_cast<u8>(aLo >> 24);
247 cols[4] =
static_cast<u8>(bLo);
248 cols[5] =
static_cast<u8>(bLo >> 8);
249 cols[6] =
static_cast<u8>(bLo >> 16);
250 cols[7] =
static_cast<u8>(bLo >> 24);
251 for (
int s = 0; s < 8; ++s) {
252 const u8 col = cols[s];
253 for (
int k = 0; k < 4; ++k) {
254 const int p_hi = 2 * k;
255 const int p_lo = 2 * k + 1;
256 const u8 hi =
static_cast<u8>((m0_mask[p_hi] & 0xF0u) ^ ((col << 4) & d_mask[p_hi]));
257 const u8 lo =
static_cast<u8>((m0_mask[p_lo] & 0x0Fu) ^ (col & d_mask[p_lo]));
258 output[s * 4 + k] =
static_cast<u8>(hi | lo);
269 const u8 D_byte =
W0 ^
W1;
270 for (
int p = 0; p < 8; ++p) {
271 const int shift = 7 - p;
272 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
273 m0_mask[p] = ((
W0 >> shift) & 1) ? 0xFFu : 0x00u;
275 for (
int s = 0; s < 8; ++s) {
276 const int bit_idx = 7 - s;
277 const u8 b0 =
static_cast<u8>((lanes[0] >> bit_idx) & 1u);
278 const u8 b1 =
static_cast<u8>((lanes[1] >> bit_idx) & 1u);
281 for (
int q = 0; q < 4; ++q) {
282 const int p_hi = 3 - q;
283 const int p_lo = 7 - q;
284 const u8 m0_p_hi =
static_cast<u8>(m0_mask[p_hi] & 1u);
285 const u8 d_p_hi =
static_cast<u8>(d_mask[p_hi] & 1u);
286 const u8 m0_p_lo =
static_cast<u8>(m0_mask[p_lo] & 1u);
287 const u8 d_p_lo =
static_cast<u8>(d_mask[p_lo] & 1u);
288 const u8 v0_hi =
static_cast<u8>(m0_p_hi ^ (b0 & d_p_hi));
289 const u8 v1_hi =
static_cast<u8>(m0_p_hi ^ (b1 & d_p_hi));
290 const u8 v0_lo =
static_cast<u8>(m0_p_lo ^ (b0 & d_p_lo));
291 const u8 v1_lo =
static_cast<u8>(m0_p_lo ^ (b1 & d_p_lo));
292 byte_hi |=
static_cast<u8>((v1_hi << (2 * q)) | (v0_hi << (2 * q + 1)));
293 byte_lo |=
static_cast<u8>((v1_lo << (2 * q)) | (v0_lo << (2 * q + 1)));
295 output[s * 2 + 0] = byte_hi;
296 output[s * 2 + 1] = byte_lo;
302 const u8 lanes_b[16],
303 const u8 lanes_c[16],
304 const u8 lanes_d[16],
306 u8 output_a[16 *
sizeof(Wave8Byte)],
307 u8 output_b[16 *
sizeof(Wave8Byte)],
308 u8 output_c[16 *
sizeof(Wave8Byte)],
312 const u8 D_byte =
W0 ^
W1;
313 for (
int p = 0; p < 8; ++p) {
314 const int shift = 7 - p;
315 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
316 m0_mask[p] = ((
W0 >> shift) & 1) ? 0xFFu : 0x00u;
318 u8 cols_a[16], cols_b[16], cols_c[16], cols_d[16];
323 for (
int s = 0; s < 8; ++s) {
324 const u8 al = cols_a[2*s + 0], ah = cols_a[2*s + 1];
325 const u8 bl = cols_b[2*s + 0], bh = cols_b[2*s + 1];
326 const u8 cl = cols_c[2*s + 0], ch = cols_c[2*s + 1];
327 const u8 dl = cols_d[2*s + 0], dh = cols_d[2*s + 1];
328 for (
int p = 0; p < 8; ++p) {
329 const u8 dm = d_mask[p], mm = m0_mask[p];
330 output_a[s*16 + p*2 + 0] = mm ^ (al & dm);
331 output_a[s*16 + p*2 + 1] = mm ^ (ah & dm);
332 output_b[s*16 + p*2 + 0] = mm ^ (bl & dm);
333 output_b[s*16 + p*2 + 1] = mm ^ (bh & dm);
334 output_c[s*16 + p*2 + 0] = mm ^ (cl & dm);
335 output_c[s*16 + p*2 + 1] = mm ^ (ch & dm);
336 output_d[s*16 + p*2 + 0] = mm ^ (dl & dm);
337 output_d[s*16 + p*2 + 1] = mm ^ (dh & dm);
346 const Wave8BitExpansionLut& lut,
348 Wave8Byte waveformSymbol;
Shared u32 "spread LUT" bit-matrix transpose primitive (no SIMD, no u64).
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_OPTIMIZE_FUNCTION
#define FL_RESTRICT_PARAM
#define FL_WAVE8_SPREAD_TO_16(lane_u8_0, lane_u8_1, out_16)
Out-of-line declarations for wave8 transposition internals.
ISR-safe memory operations (inline, header-only)
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16_bf1(const u8 lanes[16], u8 W0, u8 W1, u8 output[16 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x2_pipe2(const Wave8Byte lane_waves_a[16], const Wave8Byte lane_waves_b[16], u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose16_symbol(const u8 l[16], u8 out[16])
Transpose one symbol of 16 lanes (16 input bytes) into 16 output bytes: 8 pulses × 2 bytes,...
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_4(const Wave8Byte lane_waves[4], u8 output[4 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x4_pipe4(const Wave8Byte lane_waves_a[16], const Wave8Byte lane_waves_b[16], const Wave8Byte lane_waves_c[16], const Wave8Byte lane_waves_d[16], u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)], u8 output_c[16 *sizeof(Wave8Byte)], u8 output_d[16 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_8(const Wave8Byte lane_waves[8], u8 output[8 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16(const Wave8Byte lane_waves[16], u8 output[16 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x4_bf1_pipe4(const u8 lanes_a[16], const u8 lanes_b[16], const u8 lanes_c[16], const u8 lanes_d[16], u8 W0, u8 W1, u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)], u8 output_c[16 *sizeof(Wave8Byte)], u8 output_d[16 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FASTLED_FORCE_INLINE u32 spreadA(u8 v)
Pulses 7,6,5,4 of v (byte j = bit (7-j)). Depends only on the high nibble.
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_4_bf1(const u8 lanes[4], u8 W0, u8 W1, u8 output[4 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_8_bf1(const u8 lanes[8], u8 W0, u8 W1, u8 output[8 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose8_symbol(const u8 l[8], u8 out[8])
Transpose one symbol of 8 lanes (8 input bytes) into 8 output bytes: 8 pulses × 1 byte (bit L = lane ...
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_2(const Wave8Byte lane_waves[2], u8 output[2 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_convert_byte_to_wave8byte(u8 byte_value, const Wave8BitExpansionLut &lut, Wave8Byte *output) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_2_bf1(const u8 lanes[2], u8 W0, u8 W1, u8 output[2 *sizeof(Wave8Byte)]) FL_NO_EXCEPT
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_expand_byte(u8 byte_value, const Wave8ByteExpansionLut &lut, Wave8Byte *output) FL_NO_EXCEPT
FASTLED_FORCE_INLINE u32 spreadB(u8 v)
Pulses 3,2,1,0 of v (byte j = bit (3-j)). Depends only on the low nibble.
Compile-time linker keep-alive hook for a single fl::Bus.
FL_OPTIMIZE_FUNCTION FL_IRAM FASTLED_FORCE_INLINE void memcpy_32(u32 *FL_RESTRICT_PARAM dst, const u32 *FL_RESTRICT_PARAM src, size_t count)
ISR-optimized 32-bit block copy for 4-byte aligned memory.
FL_IRAM FL_OPTIMIZE_FUNCTION void wave8(u8 lane, const Wave8BitExpansionLut &lut, u8(&FL_RESTRICT_PARAM output)[sizeof(Wave8Byte)]) FL_NO_EXCEPT
Public single-lane wave8 encoder.
InputGamut g FL_NO_EXCEPT
To * bit_cast_ptr(void *storage) FL_NO_EXCEPT
Base definition for an LED controller.
Type-safe container for packed 8-bit wave pulse pattern.