Transpose Wave8Byte waveforms into PARLIO bit-parallel format (ISR-safe) This function transposes Wave8Byte waveform data (8 bytes per lane representing 64 pulses) into PARLIO's bit-packed parallel format for multi-lane transmission.
#pragma once
typedef union {
struct {
fl::u32 a0:1;
fl::u32 a1:1;
fl::u32 a2:1;
fl::u32 a3:1;
fl::u32 a4:1;
fl::u32 a5:1;
fl::u32 a6:1;
fl::u32 a7:1;
};
} just8bits;
typedef struct {
fl::u32 a0:1;
fl::u32 a1:1;
fl::u32 a2:1;
fl::u32 a3:1;
fl::u32 a4:1;
fl::u32 a5:1;
fl::u32 a6:1;
fl::u32 a7:1;
fl::u32 b0:1;
fl::u32 b1:1;
fl::u32 b2:1;
fl::u32 b3:1;
fl::u32 b4:1;
fl::u32 b5:1;
fl::u32 b6:1;
fl::u32 b7:1;
fl::u32 c0:1;
fl::u32 c1:1;
fl::u32 c2:1;
fl::u32 c3:1;
fl::u32 c4:1;
fl::u32 c5:1;
fl::u32 c6:1;
fl::u32 c7:1;
fl::u32 d0:1;
fl::u32 d1:1;
fl::u32 d2:1;
fl::u32 d3:1;
fl::u32 d4:1;
fl::u32 d5:1;
fl::u32 d6:1;
fl::u32 d7:1;
} sub4;
typedef union {
fl::u32 word[2];
struct {
sub4 a;
sub4 b;
};
} bitswap_type;
t = (
x ^ (
x >> 7)) & 0x00AA00AA;
x =
x ^
t ^ (
t << 7);
t = (
x ^ (
x >>14)) & 0x0000CCCC;
x =
x ^
t ^ (
t <<14);
t = (
y ^ (
y >> 7)) & 0x00AA00AA;
y =
y ^
t ^ (
t << 7);
t = (
y ^ (
y >>14)) & 0x0000CCCC;
y =
y ^
t ^ (
t <<14);
t = (
x & 0xF0F0F0F0) | ((
y >> 4) & 0x0F0F0F0F);
y = ((
x << 4) & 0xF0F0F0F0) | (
y & 0x0F0F0F0F);
}
t = (
x ^ (
x >> 7)) & 0x00AA00AA;
x =
x ^
t ^ (
t << 7);
t = (
x ^ (
x >>14)) & 0x0000CCCC;
x =
x ^
t ^ (
t <<14);
t = (
y ^ (
y >> 7)) & 0x00AA00AA;
y =
y ^
t ^ (
t << 7);
t = (
y ^ (
y >>14)) & 0x0000CCCC;
y =
y ^
t ^ (
t <<14);
t = (
x & 0xF0F0F0F0) | ((
y >> 4) & 0x0F0F0F0F);
y = ((
x << 4) & 0xF0F0F0F0) | (
y & 0x0F0F0F0F);
}
template<int m, int n>
if(m == 1) {
} else {
x = (fl::u32(A[0])<<24) | (fl::u32(A[m])<<16) | (fl::u32(A[2*m])<<8) | A[3*m];
y = (fl::u32(A[4*m])<<24) | (fl::u32(A[5*m])<<16) | (fl::u32(A[6*m])<<8) | A[7*m];
}
t = (
x ^ (
x >> 7)) & 0x00AA00AA;
x =
x ^
t ^ (
t << 7);
t = (
x ^ (
x >>14)) & 0x0000CCCC;
x =
x ^
t ^ (
t <<14);
t = (
y ^ (
y >> 7)) & 0x00AA00AA;
y =
y ^
t ^ (
t << 7);
t = (
y ^ (
y >>14)) & 0x0000CCCC;
y =
y ^
t ^ (
t <<14);
t = (
x & 0xF0F0F0F0) | ((
y >> 4) & 0x0F0F0F0F);
y = ((
x << 4) & 0xF0F0F0F0) | (
y & 0x0F0F0F0F);
}
size_t num_bytes
const u8*
const lanes[4],
size_t num_bytes
const u8*
const lanes[8],
size_t num_bytes
const u8*
const lanes[16],
size_t num_bytes
template<typename TSource>
const TSource* const lanes[],
size_t num_lanes,
size_t num_items
size_t num_bytes
for (size_t byte_idx = 0; byte_idx < num_bytes; byte_idx++) {
u8 a = lane0_byte[byte_idx];
u8 b = lane1_byte[byte_idx];
output[byte_idx * 2 + 0] =
((a >> 7) & 0x01) << 0 | ((b >> 7) & 0x01) << 1 |
((a >> 6) & 0x01) << 2 | ((b >> 6) & 0x01) << 3 |
((a >> 5) & 0x01) << 4 | ((b >> 5) & 0x01) << 5 |
((a >> 4) & 0x01) << 6 | ((b >> 4) & 0x01) << 7;
output[byte_idx * 2 + 1] =
((a >> 3) & 0x01) << 0 | ((b >> 3) & 0x01) << 1 |
((a >> 2) & 0x01) << 2 | ((b >> 2) & 0x01) << 3 |
((a >> 1) & 0x01) << 4 | ((b >> 1) & 0x01) << 5 |
((a >> 0) & 0x01) << 6 | ((b >> 0) & 0x01) << 7;
}
}
const u8*
const lanes[4],
size_t num_bytes
for (size_t byte_idx = 0; byte_idx < num_bytes; byte_idx++) {
u8 a = lanes[0][byte_idx];
u8 b = lanes[1][byte_idx];
u8 c = lanes[2][byte_idx];
u8 d = lanes[3][byte_idx];
u8* dest = &output[byte_idx * 4];
dest[0] = ((a >> 7) & 0x01) << 0 | ((b >> 7) & 0x01) << 1 | ((c >> 7) & 0x01) << 2 | ((d >> 7) & 0x01) << 3 |
((a >> 6) & 0x01) << 4 | ((b >> 6) & 0x01) << 5 | ((c >> 6) & 0x01) << 6 | ((d >> 6) & 0x01) << 7;
dest[1] = ((a >> 5) & 0x01) << 0 | ((b >> 5) & 0x01) << 1 | ((c >> 5) & 0x01) << 2 | ((d >> 5) & 0x01) << 3 |
((a >> 4) & 0x01) << 4 | ((b >> 4) & 0x01) << 5 | ((c >> 4) & 0x01) << 6 | ((d >> 4) & 0x01) << 7;
dest[2] = ((a >> 3) & 0x01) << 0 | ((b >> 3) & 0x01) << 1 | ((c >> 3) & 0x01) << 2 | ((d >> 3) & 0x01) << 3 |
((a >> 2) & 0x01) << 4 | ((b >> 2) & 0x01) << 5 | ((c >> 2) & 0x01) << 6 | ((d >> 2) & 0x01) << 7;
dest[3] = ((a >> 1) & 0x01) << 0 | ((b >> 1) & 0x01) << 1 | ((c >> 1) & 0x01) << 2 | ((d >> 1) & 0x01) << 3 |
((a >> 0) & 0x01) << 4 | ((b >> 0) & 0x01) << 5 | ((c >> 0) & 0x01) << 6 | ((d >> 0) & 0x01) << 7;
}
}
const u8*
const lanes[8],
size_t num_bytes
for (size_t byte_idx = 0; byte_idx < num_bytes; byte_idx++) {
((
u64)lanes[0][byte_idx] << 0) |
((
u64)lanes[1][byte_idx] << 8) |
((
u64)lanes[2][byte_idx] << 16) |
((
u64)lanes[3][byte_idx] << 24) |
((
u64)lanes[4][byte_idx] << 32) |
((
u64)lanes[5][byte_idx] << 40) |
((
u64)lanes[6][byte_idx] << 48) |
((
u64)lanes[7][byte_idx] << 56);
u8* dest = &output[byte_idx * 8];
for (int bit = 7; bit >= 0; bit--) {
dest[7 - bit] =
((packed >> (bit + 0)) & 0x01) << 0 |
((packed >> (bit + 8)) & 0x01) << 1 |
((packed >> (bit + 16)) & 0x01) << 2 |
((packed >> (bit + 24)) & 0x01) << 3 |
((packed >> (bit + 32)) & 0x01) << 4 |
((packed >> (bit + 40)) & 0x01) << 5 |
((packed >> (bit + 48)) & 0x01) << 6 |
((packed >> (bit + 56)) & 0x01) << 7;
}
}
}
const u8*
const lanes[16],
size_t num_bytes
for (size_t byte_idx = 0; byte_idx < num_bytes; byte_idx++) {
((
u64)lanes[0][byte_idx] << 0) |
((
u64)lanes[1][byte_idx] << 8) |
((
u64)lanes[2][byte_idx] << 16) |
((
u64)lanes[3][byte_idx] << 24) |
((
u64)lanes[4][byte_idx] << 32) |
((
u64)lanes[5][byte_idx] << 40) |
((
u64)lanes[6][byte_idx] << 48) |
((
u64)lanes[7][byte_idx] << 56);
((
u64)lanes[8][byte_idx] << 0) |
((
u64)lanes[9][byte_idx] << 8) |
((
u64)lanes[10][byte_idx] << 16) |
((
u64)lanes[11][byte_idx] << 24) |
((
u64)lanes[12][byte_idx] << 32) |
((
u64)lanes[13][byte_idx] << 40) |
((
u64)lanes[14][byte_idx] << 48) |
((
u64)lanes[15][byte_idx] << 56);
u8* dest = &output[byte_idx * 16];
for (int bit = 7; bit >= 0; bit--) {
dest[7 - bit] =
((packed_lo >> (bit + 0)) & 0x01) << 0 |
((packed_lo >> (bit + 8)) & 0x01) << 1 |
((packed_lo >> (bit + 16)) & 0x01) << 2 |
((packed_lo >> (bit + 24)) & 0x01) << 3 |
((packed_lo >> (bit + 32)) & 0x01) << 4 |
((packed_lo >> (bit + 40)) & 0x01) << 5 |
((packed_lo >> (bit + 48)) & 0x01) << 6 |
((packed_lo >> (bit + 56)) & 0x01) << 7;
dest[15 - bit] =
((packed_hi >> (bit + 0)) & 0x01) << 0 |
((packed_hi >> (bit + 8)) & 0x01) << 1 |
((packed_hi >> (bit + 16)) & 0x01) << 2 |
((packed_hi >> (bit + 24)) & 0x01) << 3 |
((packed_hi >> (bit + 32)) & 0x01) << 4 |
((packed_hi >> (bit + 40)) & 0x01) << 5 |
((packed_hi >> (bit + 48)) & 0x01) << 6 |
((packed_hi >> (bit + 56)) & 0x01) << 7;
}
}
}
template<typename TSource>
const TSource* const lanes[],
size_t num_lanes,
size_t num_items
constexpr size_t bits_per_item = sizeof(TSource) * 8;
for (size_t item_idx = 0; item_idx < num_items; item_idx++) {
u8* dest = &output[item_idx * bits_per_item];
for (size_t bit_pos = 0; bit_pos < bits_per_item; bit_pos++) {
size_t src_bit = (bits_per_item - 1) - bit_pos;
for (size_t lane = 0; lane < num_lanes && lane < 8; lane++) {
TSource src_value = lanes[lane][item_idx];
u8 bit = (src_value >> src_bit) & 0x01;
output_byte |= (bit << (7 - lane));
}
dest[bit_pos] = output_byte;
}
}
}
class SPITransposer {
public:
struct LaneData {
};
private:
};
const u8*
const input[8],
u16 num_leds,
for (u16 led = 0; led < num_leds; led++) {
for (
u8 byte_idx = 0; byte_idx < bytes_per_led; byte_idx++) {
for (int strip = 0; strip < 8; strip++) {
temp_input[strip] = input[strip][led * bytes_per_led + byte_idx];
}
output += 8;
}
}
}
const u8*
const input[4],
u16 num_leds,
for (u16 led = 0; led < num_leds; led++) {
for (
u8 byte_idx = 0; byte_idx < bytes_per_led; byte_idx++) {
for (int strip = 0; strip < 4; strip++) {
strip_bytes[strip] = input[strip][led * bytes_per_led + byte_idx];
}
for (int bit = 7; bit >= 0; bit--) {
for (int strip = 0; strip < 4; strip++) {
output_byte |= ((strip_bytes[strip] >> bit) & 1) << strip;
}
*output++ = output_byte;
}
}
}
}
const u8*
const input[2],
u16 num_leds,
for (u16 led = 0; led < num_leds; led++) {
for (
u8 byte_idx = 0; byte_idx < bytes_per_led; byte_idx++) {
strip_bytes[0] = input[0][led * bytes_per_led + byte_idx];
strip_bytes[1] = input[1][led * bytes_per_led + byte_idx];
for (int bit = 7; bit >= 0; bit--) {
((strip_bytes[0] >> bit) & 1) |
(((strip_bytes[1] >> bit) & 1) << 1);
*output++ = output_byte;
}
}
}
}
return num_leds * bytes_per_led * 8;
}
u16 num_leds,
switch (num_strips) {
case 8:
return true;
case 4:
return true;
case 2:
return true;
default:
return false;
}
}
template<size_t DATA_WIDTH>
constexpr size_t bytes_per_lane = 8;
constexpr size_t pulsesPerByte = 64;
size_t outputIdx = 0;
if (DATA_WIDTH == 8) {
for (size_t bit_pos = 0; bit_pos < 8; bit_pos++) {
((
u64)laneWaveforms[0 * bytes_per_lane + bit_pos] << 0) |
((
u64)laneWaveforms[1 * bytes_per_lane + bit_pos] << 8) |
((
u64)laneWaveforms[2 * bytes_per_lane + bit_pos] << 16) |
((
u64)laneWaveforms[3 * bytes_per_lane + bit_pos] << 24) |
((
u64)laneWaveforms[4 * bytes_per_lane + bit_pos] << 32) |
((
u64)laneWaveforms[5 * bytes_per_lane + bit_pos] << 40) |
((
u64)laneWaveforms[6 * bytes_per_lane + bit_pos] << 48) |
((
u64)laneWaveforms[7 * bytes_per_lane + bit_pos] << 56);
for (size_t pulse_bit = 0; pulse_bit < 8; pulse_bit++) {
outputBuffer[outputIdx++] =
((packed >> (7 - pulse_bit + 0)) & 0x01) << 0 |
((packed >> (7 - pulse_bit + 8)) & 0x01) << 1 |
((packed >> (7 - pulse_bit + 16)) & 0x01) << 2 |
((packed >> (7 - pulse_bit + 24)) & 0x01) << 3 |
((packed >> (7 - pulse_bit + 32)) & 0x01) << 4 |
((packed >> (7 - pulse_bit + 40)) & 0x01) << 5 |
((packed >> (7 - pulse_bit + 48)) & 0x01) << 6 |
((packed >> (7 - pulse_bit + 56)) & 0x01) << 7;
}
}
} else if (DATA_WIDTH <= 8) {
const size_t ticksPerByte = (DATA_WIDTH > 8) ? 1 : (8 / DATA_WIDTH);
const size_t numOutputBytes = (pulsesPerByte + ticksPerByte - 1) / ticksPerByte;
for (size_t outputByteIdx = 0; outputByteIdx < numOutputBytes; outputByteIdx++) {
for (
size_t t = 0;
t < ticksPerByte;
t++) {
size_t pulse_idx = outputByteIdx * ticksPerByte +
t;
if (pulse_idx >= pulsesPerByte)
break;
size_t bit_pos = pulse_idx / 8;
size_t pulse_bit = pulse_idx % 8;
for (size_t lane = 0; lane < DATA_WIDTH; lane++) {
const u8* laneWaveform = laneWaveforms + (lane * bytes_per_lane);
u8 wave8_byte = laneWaveform[bit_pos];
u8 pulse = (wave8_byte >> (7 - pulse_bit)) & 1;
size_t bitPos =
t * DATA_WIDTH + lane;
outputByte |= (pulse << bitPos);
}
}
outputBuffer[outputIdx++] = outputByte;
}
} else if (DATA_WIDTH == 16) {
size_t writeIdx = 0;
for (size_t bit_pos = 0; bit_pos < 8; bit_pos += 2) {
((
u64)laneWaveforms[0 * bytes_per_lane + bit_pos + 0] << 0) |
((
u64)laneWaveforms[1 * bytes_per_lane + bit_pos + 0] << 8) |
((
u64)laneWaveforms[2 * bytes_per_lane + bit_pos + 0] << 16) |
((
u64)laneWaveforms[3 * bytes_per_lane + bit_pos + 0] << 24) |
((
u64)laneWaveforms[4 * bytes_per_lane + bit_pos + 0] << 32) |
((
u64)laneWaveforms[5 * bytes_per_lane + bit_pos + 0] << 40) |
((
u64)laneWaveforms[6 * bytes_per_lane + bit_pos + 0] << 48) |
((
u64)laneWaveforms[7 * bytes_per_lane + bit_pos + 0] << 56);
((
u64)laneWaveforms[8 * bytes_per_lane + bit_pos + 0] << 0) |
((
u64)laneWaveforms[9 * bytes_per_lane + bit_pos + 0] << 8) |
((
u64)laneWaveforms[10 * bytes_per_lane + bit_pos + 0] << 16) |
((
u64)laneWaveforms[11 * bytes_per_lane + bit_pos + 0] << 24) |
((
u64)laneWaveforms[12 * bytes_per_lane + bit_pos + 0] << 32) |
((
u64)laneWaveforms[13 * bytes_per_lane + bit_pos + 0] << 40) |
((
u64)laneWaveforms[14 * bytes_per_lane + bit_pos + 0] << 48) |
((
u64)laneWaveforms[15 * bytes_per_lane + bit_pos + 0] << 56);
((
u64)laneWaveforms[0 * bytes_per_lane + bit_pos + 1] << 0) |
((
u64)laneWaveforms[1 * bytes_per_lane + bit_pos + 1] << 8) |
((
u64)laneWaveforms[2 * bytes_per_lane + bit_pos + 1] << 16) |
((
u64)laneWaveforms[3 * bytes_per_lane + bit_pos + 1] << 24) |
((
u64)laneWaveforms[4 * bytes_per_lane + bit_pos + 1] << 32) |
((
u64)laneWaveforms[5 * bytes_per_lane + bit_pos + 1] << 40) |
((
u64)laneWaveforms[6 * bytes_per_lane + bit_pos + 1] << 48) |
((
u64)laneWaveforms[7 * bytes_per_lane + bit_pos + 1] << 56);
((
u64)laneWaveforms[8 * bytes_per_lane + bit_pos + 1] << 0) |
((
u64)laneWaveforms[9 * bytes_per_lane + bit_pos + 1] << 8) |
((
u64)laneWaveforms[10 * bytes_per_lane + bit_pos + 1] << 16) |
((
u64)laneWaveforms[11 * bytes_per_lane + bit_pos + 1] << 24) |
((
u64)laneWaveforms[12 * bytes_per_lane + bit_pos + 1] << 32) |
((
u64)laneWaveforms[13 * bytes_per_lane + bit_pos + 1] << 40) |
((
u64)laneWaveforms[14 * bytes_per_lane + bit_pos + 1] << 48) |
((
u64)laneWaveforms[15 * bytes_per_lane + bit_pos + 1] << 56);
for (size_t pulse_bit = 0; pulse_bit < 8; pulse_bit++) {
u16 outputWord_0 =
((packed_lo_0 >> (7 - pulse_bit + 0)) & 0x01) << 0 |
((packed_lo_0 >> (7 - pulse_bit + 8)) & 0x01) << 1 |
((packed_lo_0 >> (7 - pulse_bit + 16)) & 0x01) << 2 |
((packed_lo_0 >> (7 - pulse_bit + 24)) & 0x01) << 3 |
((packed_lo_0 >> (7 - pulse_bit + 32)) & 0x01) << 4 |
((packed_lo_0 >> (7 - pulse_bit + 40)) & 0x01) << 5 |
((packed_lo_0 >> (7 - pulse_bit + 48)) & 0x01) << 6 |
((packed_lo_0 >> (7 - pulse_bit + 56)) & 0x01) << 7 |
((packed_hi_0 >> (7 - pulse_bit + 0)) & 0x01) << 8 |
((packed_hi_0 >> (7 - pulse_bit + 8)) & 0x01) << 9 |
((packed_hi_0 >> (7 - pulse_bit + 16)) & 0x01) << 10 |
((packed_hi_0 >> (7 - pulse_bit + 24)) & 0x01) << 11 |
((packed_hi_0 >> (7 - pulse_bit + 32)) & 0x01) << 12 |
((packed_hi_0 >> (7 - pulse_bit + 40)) & 0x01) << 13 |
((packed_hi_0 >> (7 - pulse_bit + 48)) & 0x01) << 14 |
((packed_hi_0 >> (7 - pulse_bit + 56)) & 0x01) << 15;
u16 outputWord_1 =
((packed_lo_1 >> (7 - pulse_bit + 0)) & 0x01) << 0 |
((packed_lo_1 >> (7 - pulse_bit + 8)) & 0x01) << 1 |
((packed_lo_1 >> (7 - pulse_bit + 16)) & 0x01) << 2 |
((packed_lo_1 >> (7 - pulse_bit + 24)) & 0x01) << 3 |
((packed_lo_1 >> (7 - pulse_bit + 32)) & 0x01) << 4 |
((packed_lo_1 >> (7 - pulse_bit + 40)) & 0x01) << 5 |
((packed_lo_1 >> (7 - pulse_bit + 48)) & 0x01) << 6 |
((packed_lo_1 >> (7 - pulse_bit + 56)) & 0x01) << 7 |
((packed_hi_1 >> (7 - pulse_bit + 0)) & 0x01) << 8 |
((packed_hi_1 >> (7 - pulse_bit + 8)) & 0x01) << 9 |
((packed_hi_1 >> (7 - pulse_bit + 16)) & 0x01) << 10 |
((packed_hi_1 >> (7 - pulse_bit + 24)) & 0x01) << 11 |
((packed_hi_1 >> (7 - pulse_bit + 32)) & 0x01) << 12 |
((packed_hi_1 >> (7 - pulse_bit + 40)) & 0x01) << 13 |
((packed_hi_1 >> (7 - pulse_bit + 48)) & 0x01) << 14 |
((packed_hi_1 >> (7 - pulse_bit + 56)) & 0x01) << 15;
writeBuffer[writeIdx++] = outputWord_0 & 0xFF;
writeBuffer[writeIdx++] = (outputWord_0 >> 8) & 0xFF;
writeBuffer[writeIdx++] = outputWord_1 & 0xFF;
writeBuffer[writeIdx++] = (outputWord_1 >> 8) & 0xFF;
}
if (writeIdx == 32) {
fl::memcpy(&outputBuffer[outputIdx], writeBuffer, 32);
outputIdx += 32;
writeIdx = 0;
}
}
} else {
return 0;
}
return outputIdx;
}
size_t data_width,
switch (data_width) {
case 1:
case 2:
case 4:
case 8:
case 16:
default:
return 0;
}
}
}
static bool transpose8(const fl::optional< LaneData > lanes[8], fl::span< u8 > output, const char **error=nullptr) FL_NOEXCEPT
Transpose 8 lanes of data into interleaved octal-SPI format.
static bool transpose4(const fl::optional< LaneData > &lane0, const fl::optional< LaneData > &lane1, const fl::optional< LaneData > &lane2, const fl::optional< LaneData > &lane3, fl::span< u8 > output, const char **error=nullptr) FL_NOEXCEPT
Transpose 4 lanes of data into interleaved quad-SPI format.
static bool transpose16(const fl::optional< LaneData > lanes[16], fl::span< u8 > output, const char **error=nullptr) FL_NOEXCEPT
Transpose 16 lanes of data into interleaved hex-SPI format.
static bool transpose2(const fl::optional< LaneData > &lane0, const fl::optional< LaneData > &lane1, fl::span< u8 > output, const char **error=nullptr) FL_NOEXCEPT
Transpose 2 lanes of data into interleaved dual-SPI format.
static u8 getLaneByte(const LaneData &lane, size_t byte_idx, size_t max_size) FL_NOEXCEPT
Get byte from lane at given index, handling padding automatically.
fl::span< const u8 > payload
Actual LED data for this lane.
fl::span< const u8 > padding_frame
Black LED frame for padding (repeating pattern)
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT
FASTLED_FORCE_INLINE FL_IRAM size_t transpose_wave8byte_parlio(const u8 *FL_RESTRICT_PARAM laneWaveforms, size_t data_width, u8 *FL_RESTRICT_PARAM outputBuffer) FL_NOEXCEPT
FASTLED_FORCE_INLINE void transpose8x1_MSB(unsigned char *A, unsigned char *B) FL_NOEXCEPT
Simplified 8x1 bit transpose with MSB-first output.
FL_DISABLE_WARNING_PUSH unsigned char * B
FASTLED_FORCE_INLINE void transpose_2strips(const u8 *const input[2], u8 *output, u16 num_leds, u8 bytes_per_led) FL_NOEXCEPT
Transpose 2 LED strips into parallel bit format.
void transpose_2lane_inline(const u8 *lane0_byte, const u8 *lane1_byte, u8 *output, size_t num_bytes) FL_NOEXCEPT
Low-level bit-interleaving primitive for 2 lanes (ISR-safe)
FASTLED_FORCE_INLINE void transpose8(unsigned char *A, unsigned char *B) FL_NOEXCEPT
Templated 8x8 bit transpose with custom stride.
void transpose8x1_noinline(unsigned char *A, unsigned char *B) FL_NOEXCEPT
Simplified 8x1 bit transpose (non-inline version)
bool transpose_strips(u8 num_strips, const u8 *const *input, u8 *output, u16 num_leds, u8 bytes_per_led) FL_NOEXCEPT
Helper to transpose N strips with automatic dispatch.
void transpose_8lane_inline(const u8 *const lanes[8], u8 *output, size_t num_bytes) FL_NOEXCEPT
Low-level bit-interleaving primitive for 8 lanes (ISR-safe)
FASTLED_FORCE_INLINE void transpose8x1(unsigned char *A, unsigned char *B) FL_NOEXCEPT
Simplified 8x1 bit transpose (inline version)
FASTLED_FORCE_INLINE void transpose_4strips(const u8 *const input[4], u8 *output, u16 num_leds, u8 bytes_per_led) FL_NOEXCEPT
Transpose 4 LED strips into parallel bit format.
FASTLED_FORCE_INLINE u32 calculate_transpose_buffer_size(u16 num_leds, u8 bytes_per_led) FL_NOEXCEPT
Calculate output buffer size needed for transposed data.
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION size_t transpose_wave8byte_parlio_template(const u8 *FL_RESTRICT_PARAM laneWaveforms, u8 *FL_RESTRICT_PARAM outputBuffer) FL_NOEXCEPT
Template specialization of transpose for compile-time data_width (optimization)
void transpose_generic_inline(const TSource *const lanes[], size_t num_lanes, u8 *output, size_t num_items) FL_NOEXCEPT
Generic bit-interleaving primitive for N lanes with M-bit source data (ISR-safe)
void transpose_16lane_inline(const u8 *const lanes[16], u8 *output, size_t num_bytes) FL_NOEXCEPT
Low-level bit-interleaving primitive for 16 lanes (ISR-safe)
FASTLED_FORCE_INLINE void transpose_8strips(const u8 *const input[8], u8 *output, u16 num_leds, u8 bytes_per_led) FL_NOEXCEPT
Transpose 8 LED strips into parallel bit format.
void transpose_4lane_inline(const u8 *const lanes[4], u8 *output, size_t num_bytes) FL_NOEXCEPT
Low-level bit-interleaving primitive for 4 lanes (ISR-safe)
Base definition for an LED controller.
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FASTLED_FORCE_INLINE
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_OPTIMIZE_FUNCTION
#define FL_RESTRICT_PARAM