Transpose 8 lanes of data into interleaved octal-SPI format.
183 {
184
185 if (output.
size() % 8 != 0) {
186 if (error) {
187 *error = "Output buffer size must be divisible by 8";
188 }
189 return false;
190 }
191
192
193 const size_t max_size = output.
size() / 8;
194
195
196 if (max_size == 0) {
197 if (error) {
198 *error = nullptr;
199 }
200 return true;
201 }
202
203
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];
208 break;
209 }
210 }
211
212
213 fl::vector<u8> lane_buffers[8];
214 const u8* lane_ptrs[8];
215
216 for (size_t lane = 0; lane < 8; lane++) {
217 lane_buffers[lane].
resize(max_size);
218 lane_ptrs[lane] = lane_buffers[lane].
data();
219
220 for (size_t byte_idx = 0; byte_idx < max_size; byte_idx++) {
221 lane_buffers[lane][byte_idx] = lanes[lane].
has_value() ?
222 getLaneByte(*lanes[lane], byte_idx, max_size) : default_padding;
223 }
224 }
225
226
228
229 if (error) {
230 *error = nullptr;
231 }
232 return true;
233}
bool has_value() const FL_NO_EXCEPT
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
constexpr fl::size size() const FL_NO_EXCEPT
void resize(fl::size n) FL_NO_EXCEPT
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)