MCPcopy Create free account
hub / github.com/FastLED/FastLED / decodeSpiEdges

Function decodeSpiEdges

examples/AutoResearch/AutoResearchTest.cpp:174–309  ·  view source on GitHub ↗

Decode SPI bit stream from raw RMT edges into LED RGB bytes The SPI data pin carries APA102 encoded data clocked by PCLK. RMT RX captures edges on the data pin. Each edge duration / bit_period_ns gives the number of consecutive same-value bits. Returns number of LED RGB bytes written to rx_buffer, or 0 on error.

Source from the content-addressed store, hash-verified

172// gives the number of consecutive same-value bits.
173// Returns number of LED RGB bytes written to rx_buffer, or 0 on error.
174static size_t decodeSpiEdges(fl::shared_ptr<fl::RxChannel> rx_channel,
175 fl::span<uint8_t> rx_buffer,
176 uint32_t clock_hz) {
177 if (!rx_channel || clock_hz == 0) {
178 FL_WARN("[SPI DECODE] Invalid parameters");
179 return 0;
180 }
181
182 const uint32_t bit_period_ns = static_cast<uint32_t>(1000000000ULL / clock_hz);
183 const uint32_t half_bit_ns = bit_period_ns / 2;
184 FL_WARN("[SPI DECODE] clock=" << clock_hz << " Hz, bit_period=" << bit_period_ns << " ns");
185
186 // Read raw edges (up to 4096 to handle large strips)
187 constexpr size_t MAX_EDGES = 4096;
188 fl::vector<fl::EdgeTime> edges(MAX_EDGES);
189 fl::span<fl::EdgeTime> edge_span(edges.data(), edges.size());
190 size_t edge_count = rx_channel->getRawEdgeTimes(edge_span, 0);
191
192 if (edge_count == 0) {
193 FL_WARN("[SPI DECODE] No edges captured");
194 return 0;
195 }
196 FL_WARN("[SPI DECODE] Captured " << edge_count << " edges");
197
198 // Reconstruct bit stream from edges
199 // Each edge has a level (high/low) and duration in ns.
200 // Number of bits = round(duration_ns / bit_period_ns)
201 fl::vector<uint8_t> bits;
202 bits.reserve(edge_count * 4); // Rough estimate
203
204 for (size_t i = 0; i < edge_count; i++) {
205 uint32_t duration = edges[i].ns;
206 uint32_t num_bits = (duration + half_bit_ns) / bit_period_ns;
207 if (num_bits == 0) num_bits = 1; // At least 1 bit per edge
208 uint8_t bit_val = edges[i].high ? 1 : 0;
209 for (uint32_t b = 0; b < num_bits; b++) {
210 bits.push_back(bit_val);
211 }
212 }
213
214 FL_WARN("[SPI DECODE] Reconstructed " << bits.size() << " bits");
215
216 if (bits.size() < 32) {
217 FL_WARN("[SPI DECODE] Too few bits for APA102 frame");
218 return 0;
219 }
220
221 // Convert bits to bytes (MSB first)
222 size_t total_bytes = bits.size() / 8;
223 fl::vector<uint8_t> raw_bytes(total_bytes);
224 for (size_t i = 0; i < total_bytes; i++) {
225 uint8_t byte_val = 0;
226 for (int bit = 7; bit >= 0; bit--) {
227 size_t bit_idx = i * 8 + (7 - bit);
228 if (bit_idx < bits.size() && bits[bit_idx]) {
229 byte_val |= (1 << bit);
230 }
231 }

Callers 1

captureFunction · 0.85

Calls 6

dataMethod · 0.45
sizeMethod · 0.45
getRawEdgeTimesMethod · 0.45
reserveMethod · 0.45
push_backMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected