FastLED 3.9.15
Loading...
Searching...
No Matches

◆ loop()

void loop ( )

Definition at line 558 of file AutoResearch.ino.

558 {
559 // Unified watchdog guard. First iteration: arms the WDT, prints any
560 // prior-boot reset/crash info, pauses 3 s on a crash. Every iteration:
561 // feeds on construction (now) and again on destruction (end of scope).
563
564 // Aggressively pump async tasks (including JSON-RPC task)
565 // This ensures RPC commands are processed frequently even without delay() calls
566 for (int i = 0; i < 100; i++) {
568 }
569
570 // ========================================================================
571 // Watchdog autoresearch trigger (FastLED#2731) — when the host RPC sends
572 // `deliberateHang`, the handler flips this flag. We let one more pass of
573 // task::run() drain the response queue so the host sees the ACK, then
574 // we disable interrupts (so no async machinery can keep the WDT happy)
575 // and spin forever. The next watchdog tick must fire and reset the chip.
576 // The host's recovery test passes if the device re-enumerates afterward
577 // and is reflashable.
578 // ========================================================================
579 if (g_autoresearch_state->deliberate_hang_requested) {
580 FL_WARN("[deliberateHang] entering forced-hang loop NOW");
581 delay(200); // give Serial TX FIFO time to flush
582 // noInterrupts() is an Arduino-only macro; guard it so the host stub
583 // build (which compiles this .ino for the unit-test framework) doesn't
584 // hit an undeclared identifier. On host the while(1) below still spins
585 // and prevents feed(), which is the actual hang we want to test.
586#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
587 noInterrupts();
588#endif
589 while (true) { /* deliberate hang */ }
590 }
591
592 // Feed the watchdog at the end of every loop iteration. On platforms
593 // where begin() was a no-op the feed is also a no-op. The mark-clean
594 // shutdown zeros the consecutive-crash counter so a transient hang
595 // doesn't eventually push the board into safe mode.
596 FastLED.watchdog().feed();
597 FastLED.watchdog().markCleanShutdown();
598
599 // Run GPIO baseline test once after device is ready (allows JSON-RPC to be operational first)
600 // This test is informational only - we continue regardless of pass/fail
601 if (!g_autoresearch_state->gpio_baseline_test_done) {
602 // Wait 500ms after boot to ensure JSON-RPC is fully operational
603 if (millis() > 500) {
604 g_autoresearch_state->gpio_baseline_test_done = true;
605
606 FL_PRINT("\n[GPIO BASELINE TEST] Testing GPIO " << PIN_TX << " → GPIO " << PIN_RX << " connectivity");
607
608 // Test RX channel with manual GPIO toggle to confirm hardware path works
609 // This isolates GPIO/hardware issues from PARLIO driver issues
610 // Buffer size = 100 symbols, hz = 40MHz (same as LED autoresearch)
611 if (!testRxChannel(g_autoresearch_state->rx_channel, PIN_TX, PIN_RX, 40000000, 100)) {
612 FL_WARN("[GPIO BASELINE TEST] FAILED - RX did not capture manual GPIO toggles");
613 FL_WARN("[GPIO BASELINE TEST] Possible causes:");
614 FL_WARN(" 1. GPIO " << PIN_TX << " and GPIO " << PIN_RX << " are not physically connected");
615 FL_WARN(" 2. RX channel initialization failed");
616 FL_WARN(" 3. GPIO conflict with other peripherals (USB Serial JTAG on C6 uses certain GPIOs)");
617 FL_WARN("[GPIO BASELINE TEST] Continuing - JSON-RPC pin discovery/testing available");
618 } else {
619 FL_WARN("\n[GPIO BASELINE TEST] ✓ PASSED - GPIO path confirmed working");
620 FL_WARN("[GPIO BASELINE TEST] ✓ RX successfully captured manual GPIO toggles");
621 FL_WARN("[GPIO BASELINE TEST] ✓ Hardware connectivity verified (GPIO " << PIN_TX << " → GPIO " << PIN_RX << ")");
622 }
623 }
624 }
625
626 // Emit periodic ready status (every 5 seconds) for Python connection detection
627 static uint32_t last_status_ms = 0;
628 uint32_t now = millis();
629 if (now - last_status_ms >= 5000) {
630 fl::json status = fl::json::object();
631 status.set("ready", true);
632 status.set("uptimeMs", static_cast<int64_t>(now));
633 printStreamRaw("status", status);
634 last_status_ms = now;
635 }
636}
fl::shared_ptr< AutoResearchState > g_autoresearch_state
#define PIN_TX
static constexpr uint32_t AUTORESEARCH_WATCHDOG_TIMEOUT_MS
#define PIN_RX
bool testRxChannel(fl::shared_ptr< fl::RxChannel > rx_channel, int pin_tx, int pin_rx, uint32_t hz, size_t buffer_size)
Test RX channel with manual GPIO toggle.
void printStreamRaw(const char *messageType, const fl::json &data)
Print JSONL stream message directly to Serial, bypassing fl::println.
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
void set(const fl::string &key, const json &value) FL_NOEXCEPT
Definition json.h:701
static json object() FL_NOEXCEPT
Definition json.h:692
#define FL_WARN(X)
Definition log.h:276
#define FL_PRINT(X)
Print without prefix (like FL_WARN but without "WARN: " prefix) Uses sstream for dynamic formatting (...
Definition log.h:457
void run(fl::u32 microseconds, ExecFlags flags)
Run selected task subsystems.
fl::u32 uint32_t
Definition s16x16x4.h:219
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
void delay(u32 ms, bool run_async=true) FL_NOEXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
Definition delay.h:98
#define FL_WATCHDOG_AUTO(...)
Definition watchdog.h:260

References AUTORESEARCH_WATCHDOG_TIMEOUT_MS, FastLED, FL_PRINT, FL_WARN, FL_WATCHDOG_AUTO, g_autoresearch_state, fl::json::object(), PIN_RX, PIN_TX, printStreamRaw(), fl::task::run(), fl::json::set(), and testRxChannel().

+ Here is the call graph for this function: