FastLED 3.9.15
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 114 of file transposition.cpp.hpp.

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

References fl::vector< T >::data(), fl::Optional< T >::empty(), 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: