28 t = (
x ^ (
x >> 7)) & 0x00AA00AA;
x =
x ^
t ^ (
t << 7);
29 t = (
x ^ (
x >>14)) & 0x0000CCCC;
x =
x ^
t ^ (
t <<14);
32 t = (
y ^ (
y >> 7)) & 0x00AA00AA;
y =
y ^
t ^ (
t << 7);
33 t = (
y ^ (
y >>14)) & 0x0000CCCC;
y =
y ^
t ^ (
t <<14);
36 t = (
x & 0xF0F0F0F0) | ((
y >> 4) & 0x0F0F0F0F);
37 y = ((
x << 4) & 0xF0F0F0F0) | (
y & 0x0F0F0F0F);
59 if (output.size() % 2 != 0) {
61 *error =
"Output buffer size must be divisible by 2";
67 const size_t max_size = output.size() / 2;
81 u8 default_padding = 0x00;
82 for (
size_t i = 0; i < 2; i++) {
83 if (lanes[i]->has_value() && !(*lanes[i])->padding_frame.
empty()) {
84 default_padding = (*lanes[i])->padding_frame[0];
93 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
94 lane0_buffer[byte_idx] = lanes[0]->
has_value() ?
96 lane1_buffer[byte_idx] = lanes[1]->
has_value() ?
122 if (output.size() % 4 != 0) {
124 *error =
"Output buffer size must be divisible by 4";
130 const size_t max_size = output.size() / 4;
144 u8 default_padding = 0x00;
145 for (
size_t i = 0; i < 4; i++) {
146 if (lanes[i]->has_value() && !(*lanes[i])->padding_frame.
empty()) {
147 default_padding = (*lanes[i])->padding_frame[0];
154 const u8* lane_ptrs[4];
156 for (
size_t lane = 0; lane < 4; lane++) {
158 lane_ptrs[lane] = lane_buffers[lane].
data();
160 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
161 lane_buffers[lane][byte_idx] = lanes[lane]->
has_value() ?
185 if (output.size() % 8 != 0) {
187 *error =
"Output buffer size must be divisible by 8";
193 const size_t max_size = output.size() / 8;
204 u8 default_padding = 0x00;
205 for (
size_t i = 0; i < 8; i++) {
206 if (lanes[i].has_value() && !lanes[i]->padding_frame.empty()) {
207 default_padding = lanes[i]->padding_frame[0];
214 const u8* lane_ptrs[8];
216 for (
size_t lane = 0; lane < 8; lane++) {
218 lane_ptrs[lane] = lane_buffers[lane].
data();
220 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
221 lane_buffers[lane][byte_idx] = lanes[lane].has_value() ?
245 if (output.size() % 16 != 0) {
247 *error =
"Output buffer size must be divisible by 16";
253 const size_t max_size = output.size() / 16;
264 u8 default_padding = 0x00;
265 for (
size_t i = 0; i < 16; i++) {
266 if (lanes[i].has_value() && !lanes[i]->padding_frame.empty()) {
267 default_padding = lanes[i]->padding_frame[0];
274 const u8* lane_ptrs[16];
276 for (
size_t lane = 0; lane < 16; lane++) {
278 lane_ptrs[lane] = lane_buffers[lane].
data();
280 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
281 lane_buffers[lane][byte_idx] = lanes[lane].has_value() ?
303 const size_t lane_size = lane.payload.size();
304 const size_t padding_bytes =
max_size - lane_size;
307 if (byte_idx < padding_bytes) {
309 if (!lane.padding_frame.empty()) {
310 return lane.padding_frame[byte_idx % lane.padding_frame.size()];
316 const size_t data_idx = byte_idx - padding_bytes;
317 if (data_idx < lane_size) {
318 return lane.payload[data_idx];
bool empty() const FL_NO_EXCEPT
bool has_value() const FL_NO_EXCEPT
static bool transpose8(const fl::optional< LaneData > lanes[8], fl::span< u8 > output, const char **error=nullptr) FL_NO_EXCEPT
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_NO_EXCEPT
Transpose 4 lanes of data into interleaved quad-SPI format.
static bool transpose2(const fl::optional< LaneData > &lane0, const fl::optional< LaneData > &lane1, fl::span< u8 > output, const char **error=nullptr) FL_NO_EXCEPT
Transpose 2 lanes of data into interleaved dual-SPI format.
static bool transpose16(const fl::optional< LaneData > lanes[16], fl::span< u8 > output, const char **error=nullptr) FL_NO_EXCEPT
Transpose 16 lanes of data into interleaved hex-SPI format.
static u8 getLaneByte(const LaneData &lane, size_t byte_idx, size_t max_size) FL_NO_EXCEPT
Get byte from lane at given index, handling padding automatically.
Lane data structure: payload + padding frame.
void resize(fl::size n) FL_NO_EXCEPT
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_DISABLE_WARNING_POP
#define FL_OPTIMIZE_FUNCTION
u8 u8 fract8 blur_amount FL_NO_EXCEPT
void transpose8x1_noinline(unsigned char *A, unsigned char *B) FL_NO_EXCEPT
Simplified 8x1 bit transpose (non-inline version)
void transpose_8lane_inline(const u8 *const lanes[8], u8 *output, size_t num_bytes) FL_NO_EXCEPT
Low-level bit-interleaving primitive for 8 lanes (ISR-safe)
void transpose_2lane_inline(const u8 *lane0_byte, const u8 *lane1_byte, u8 *output, size_t num_bytes) FL_NO_EXCEPT
Low-level bit-interleaving primitive for 2 lanes (ISR-safe)
void transpose_4lane_inline(const u8 *const lanes[4], u8 *output, size_t num_bytes) FL_NO_EXCEPT
Low-level bit-interleaving primitive for 4 lanes (ISR-safe)
void transpose_16lane_inline(const u8 *const lanes[16], u8 *output, size_t num_bytes) FL_NO_EXCEPT
Low-level bit-interleaving primitive for 16 lanes (ISR-safe)
Base definition for an LED controller.
Unified bit transposition functions for FastLED.