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

Method wait

src/platforms/arm/lpc/rx_sct_capture.cpp.hpp:544–627  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

542}
543
544RxWaitResult LpcSctRxChannel::wait(u32 timeout_ms) FL_NOEXCEPT {
545#if defined(FASTLED_LPC_RX_SCT_DMA) && defined(FL_IS_ARM_LPC_845)
546 // DMA capture path. The two DMA channels are autonomously latching
547 // SCT->CAP[0..1] into the rings via the SCT_DMAn trigger lines —
548 // CPU just sleeps for the capture window, then halts the SCT and
549 // merges the two rings by timestamp into mEdges.
550 //
551 // ---- 1. Sleep for the capture window. ----
552 const fl::u32 start_ms = millis();
553 while ((millis() - start_ms) < timeout_ms) {
554 const fl::u32 rising_done = dmaChannelEdgeCount(0);
555 const fl::u32 falling_done = dmaChannelEdgeCount(1);
556 if (rising_done >= kDmaRingSize && falling_done >= kDmaRingSize) {
557 break; // both rings full — no point waiting longer
558 }
559 // No need to spin tight; the DMA work happens in hardware.
560 // A small idle keeps wakelet contention down. (millis() based
561 // throttle — we don't need precise pacing here.)
562 }
563
564 // ---- 2. Halt SCT to stop further captures. ----
565 sct(kOffCTRL) |= kCtrlHaltL;
566
567 // ---- 3. Snapshot how many entries each ring received. ----
568 const fl::u32 n_rising = dmaChannelEdgeCount(0);
569 const fl::u32 n_falling = dmaChannelEdgeCount(1);
570
571 // Disable channels so SETVALID can re-arm in the next begin().
572 dma(kOffDmaEnableClr0) = (1u << 0) | (1u << 1);
573
574 // ---- 4. Merge the two rings by timestamp into mEdges. ----
575 // The rings hold raw 32-bit SCT counter ticks. Walk both in parallel
576 // (they're already monotonic per-direction), pick the earlier tick,
577 // emit `EdgeTime{level, ns-delta-from-prior}`.
578 fl::u32 ir = 0, jf = 0;
579 fl::u32 prev_tick = 0;
580 bool prev_seen = false;
581 bool last_was_rising = false;
582 while (ir < n_rising || jf < n_falling) {
583 if (mEdges.size() >= mCapacity) break;
584
585 bool pick_rising;
586 if (ir >= n_rising) {
587 pick_rising = false;
588 } else if (jf >= n_falling) {
589 pick_rising = true;
590 } else {
591 // Both rings have unread entries; pick the earlier tick.
592 // Unsigned subtract treats wrap as modulo — assume neither
593 // ring's outstanding entries span a full 32-bit wrap (~143 s
594 // at 30 MHz, way beyond our test windows).
595 pick_rising = (g_dma_rising[ir] - g_dma_falling[jf]) >= 0x80000000u;
596 }
597
598 const fl::u32 tick = pick_rising ? g_dma_rising[ir] : g_dma_falling[jf];
599 if (prev_seen) {
600 const fl::u32 delta = tick - prev_tick;
601 mEdges.push_back(EdgeTime(last_was_rising, ticksToNs(delta)));

Callers 15

pthread_coro_thread_mainFunction · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45
showPixelsMethod · 0.45

Calls 7

dmaChannelEdgeCountFunction · 0.85
EdgeTimeClass · 0.85
ticksToNsFunction · 0.70
millisFunction · 0.50
sizeMethod · 0.45
push_backMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected