Transpose 2 lanes of data into interleaved dual-SPI format.
57 {
58
59 if (output.
size() % 2 != 0) {
60 if (error) {
61 *error = "Output buffer size must be divisible by 2";
62 }
63 return false;
64 }
65
66
67 const size_t max_size = output.
size() / 2;
68
69
70 if (max_size == 0) {
71 if (error) {
72 *error = nullptr;
73 }
74 return true;
75 }
76
77
79
80
81 u8 default_padding = 0x00;
82 for (size_t i = 0; i < 2; i++) {
83 if (lanes[i]->has_value() && !(*lanes[i])->padding_frame.empty()) {
84 default_padding = (*lanes[i])->padding_frame[0];
85 break;
86 }
87 }
88
89
90 fl::vector<u8> lane0_buffer(max_size);
91 fl::vector<u8> lane1_buffer(max_size);
92
93 for (size_t byte_idx = 0; byte_idx < max_size; byte_idx++) {
94 lane0_buffer[byte_idx] = lanes[0]->
has_value() ?
95 getLaneByte(**lanes[0], byte_idx, max_size) : default_padding;
96 lane1_buffer[byte_idx] = lanes[1]->
has_value() ?
97 getLaneByte(**lanes[1], byte_idx, max_size) : default_padding;
98 }
99
100
102
103 if (error) {
104 *error = nullptr;
105 }
106 return true;
107}
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 transpose_2lane_inline(const u8 *lane0_byte, const u8 *lane1_byte, u8 *output, size_t num_bytes) FL_NO_EXCEPT
Low-level bit-interleaving primitive for 2 lanes (ISR-safe)