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