Transpose 16 lanes of data into interleaved hex-SPI format.
243 {
244
245 if (output.
size() % 16 != 0) {
246 if (error) {
247 *error = "Output buffer size must be divisible by 16";
248 }
249 return false;
250 }
251
252
253 const size_t max_size = output.
size() / 16;
254
255
256 if (max_size == 0) {
257 if (error) {
258 *error = nullptr;
259 }
260 return true;
261 }
262
263
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];
268 break;
269 }
270 }
271
272
273 fl::vector<u8> lane_buffers[16];
274 const u8* lane_ptrs[16];
275
276 for (size_t lane = 0; lane < 16; lane++) {
277 lane_buffers[lane].
resize(max_size);
278 lane_ptrs[lane] = lane_buffers[lane].
data();
279
280 for (size_t byte_idx = 0; byte_idx < max_size; byte_idx++) {
281 lane_buffers[lane][byte_idx] = lanes[lane].
has_value() ?
282 getLaneByte(*lanes[lane], byte_idx, max_size) : default_padding;
283 }
284 }
285
286
288
289 if (error) {
290 *error = nullptr;
291 }
292 return true;
293}
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_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)