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

◆ transpose4()

bool fl::SPITransposer::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 )
static

Transpose 4 lanes of data into interleaved quad-SPI format.

Parameters
lane0Lane 0 data (use fl::nullopt for unused lane)
lane1Lane 1 data (use fl::nullopt for unused lane)
lane2Lane 2 data (use fl::nullopt for unused lane)
lane3Lane 3 data (use fl::nullopt for unused lane)
outputOutput buffer to write interleaved data (size must be divisible by 4)
errorOptional pointer to receive error message (set to nullptr if unused)
Returns
true on success, false if output buffer size is invalid
Note
Output buffer size determines max lane size: max_size = output.size() / 4
Shorter lanes are padded at the beginning with repeating padding_frame pattern
Empty lanes (nullopt) are filled with zeros or first lane's padding
Examples
/home/runner/work/FastLED/FastLED/src/fl/math/transposition.h.

Definition at line 115 of file transposition.cpp.hpp.

120 {
121 // Validate output buffer size (must be divisible by 4)
122 if (output.size() % 4 != 0) {
123 if (error) {
124 *error = "Output buffer size must be divisible by 4";
125 }
126 return false;
127 }
128
129 // Calculate max lane size from output buffer
130 const size_t max_size = output.size() / 4;
131
132 // Handle empty case
133 if (max_size == 0) {
134 if (error) {
135 *error = nullptr; // No error, just empty
136 }
137 return true;
138 }
139
140 // Create array of lane references for easier iteration
141 const fl::optional<LaneData>* lanes[4] = {&lane0, &lane1, &lane2, &lane3};
142
143 // Determine default padding byte from first available lane
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];
148 break;
149 }
150 }
151
152 // Gather all bytes from each lane into temporary buffers
153 fl::vector<u8> lane_buffers[4];
154 const u8* lane_ptrs[4];
155
156 for (size_t lane = 0; lane < 4; lane++) {
157 lane_buffers[lane].resize(max_size);
158 lane_ptrs[lane] = lane_buffers[lane].data();
159
160 for (size_t byte_idx = 0; byte_idx < max_size; byte_idx++) {
161 lane_buffers[lane][byte_idx] = lanes[lane]->has_value() ?
162 getLaneByte(**lanes[lane], byte_idx, max_size) : default_padding;
163 }
164 }
165
166 // Perform transposition using ISR-safe primitive
167 transpose_4lane_inline(lane_ptrs, output.data(), max_size);
168
169 if (error) {
170 *error = nullptr; // Success, no error
171 }
172 return true;
173}
bool has_value() const FL_NO_EXCEPT
Definition optional.h:42
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.
const T * data() const FL_NO_EXCEPT
Definition span.h:486
constexpr fl::size size() const FL_NO_EXCEPT
Definition span.h:483
void resize(fl::size n) FL_NO_EXCEPT
Definition vector.h:593
T * data() FL_NO_EXCEPT
Definition vector.h:619
unsigned char u8
Definition stdint.h:131
Optional< T > optional
Definition optional.h:16
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)

References fl::vector< T >::data(), fl::Optional< T >::empty(), fl::FL_NO_EXCEPT, getLaneByte(), fl::Optional< T >::has_value(), fl::vector< T >::resize(), and fl::transpose_4lane_inline().

Referenced by fl::spi::MultiLaneDevice::flush().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: