27 t = (
x ^ (
x >> 7)) & 0x00AA00AA;
x =
x ^
t ^ (
t << 7);
28 t = (
x ^ (
x >>14)) & 0x0000CCCC;
x =
x ^
t ^ (
t <<14);
31 t = (
y ^ (
y >> 7)) & 0x00AA00AA;
y =
y ^
t ^ (
t << 7);
32 t = (
y ^ (
y >>14)) & 0x0000CCCC;
y =
y ^
t ^ (
t <<14);
35 t = (
x & 0xF0F0F0F0) | ((
y >> 4) & 0x0F0F0F0F);
36 y = ((
x << 4) & 0xF0F0F0F0) | (
y & 0x0F0F0F0F);
58 if (output.size() % 2 != 0) {
60 *error =
"Output buffer size must be divisible by 2";
66 const size_t max_size = output.size() / 2;
80 u8 default_padding = 0x00;
81 for (
size_t i = 0; i < 2; i++) {
82 if (lanes[i]->has_value() && !(*lanes[i])->padding_frame.
empty()) {
83 default_padding = (*lanes[i])->padding_frame[0];
92 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
93 lane0_buffer[byte_idx] = lanes[0]->
has_value() ?
95 lane1_buffer[byte_idx] = lanes[1]->
has_value() ?
119 const char** error) {
121 if (output.size() % 4 != 0) {
123 *error =
"Output buffer size must be divisible by 4";
129 const size_t max_size = output.size() / 4;
143 u8 default_padding = 0x00;
144 for (
size_t i = 0; i < 4; i++) {
145 if (lanes[i]->has_value() && !(*lanes[i])->padding_frame.
empty()) {
146 default_padding = (*lanes[i])->padding_frame[0];
153 const u8* lane_ptrs[4];
155 for (
size_t lane = 0; lane < 4; lane++) {
157 lane_ptrs[lane] = lane_buffers[lane].
data();
159 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
160 lane_buffers[lane][byte_idx] = lanes[lane]->
has_value() ?
182 const char** error) {
184 if (output.size() % 8 != 0) {
186 *error =
"Output buffer size must be divisible by 8";
192 const size_t max_size = output.size() / 8;
203 u8 default_padding = 0x00;
204 for (
size_t i = 0; i < 8; i++) {
205 if (lanes[i].has_value() && !lanes[i]->padding_frame.
empty()) {
206 default_padding = lanes[i]->padding_frame[0];
213 const u8* lane_ptrs[8];
215 for (
size_t lane = 0; lane < 8; lane++) {
217 lane_ptrs[lane] = lane_buffers[lane].
data();
219 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
220 lane_buffers[lane][byte_idx] = lanes[lane].
has_value() ?
242 const char** error) {
244 if (output.size() % 16 != 0) {
246 *error =
"Output buffer size must be divisible by 16";
252 const size_t max_size = output.size() / 16;
263 u8 default_padding = 0x00;
264 for (
size_t i = 0; i < 16; i++) {
265 if (lanes[i].has_value() && !lanes[i]->padding_frame.
empty()) {
266 default_padding = lanes[i]->padding_frame[0];
273 const u8* lane_ptrs[16];
275 for (
size_t lane = 0; lane < 16; lane++) {
277 lane_ptrs[lane] = lane_buffers[lane].
data();
279 for (
size_t byte_idx = 0; byte_idx <
max_size; byte_idx++) {
280 lane_buffers[lane][byte_idx] = lanes[lane].
has_value() ?
303 const size_t padding_bytes =
max_size - lane_size;
306 if (byte_idx < padding_bytes) {
315 const size_t data_idx = byte_idx - padding_bytes;
316 if (data_idx < lane_size) {
bool empty() const FL_NOEXCEPT
bool has_value() const FL_NOEXCEPT
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)
Lane data structure: payload + padding frame.
constexpr bool empty() const FL_NOEXCEPT
constexpr fl::size size() const FL_NOEXCEPT
void resize(fl::size n) FL_NOEXCEPT
FL_DISABLE_WARNING_PUSH unsigned char * B
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)
void transpose8x1_noinline(unsigned char *A, unsigned char *B) FL_NOEXCEPT
Simplified 8x1 bit transpose (non-inline version)
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)
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)
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 FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_DISABLE_WARNING_POP
#define FL_OPTIMIZE_FUNCTION
Unified bit transposition functions for FastLED.