14#if !FL_PLATFORM_HAS_LARGE_MEMORY
149#define FASTLED_LOG_PARLIO_ASYNC_ENABLED
237#if defined(FL_IS_ESP32) && defined(SET_LOOP_TASK_STACK_SIZE)
238SET_LOOP_TASK_STACK_SIZE(16 * 1024);
260static constexpr uint32_t SERIAL_TIMEOUT_MS = 120000;
261#if defined(FL_IS_ESP_32S3) || defined(FL_IS_ESP_32C3) || \
262 defined(FL_IS_ESP_32C6) || defined(FL_IS_ESP_32H2) || \
263 defined(CONFIG_IDF_TARGET_ESP32P4) || defined(FL_IS_RP)
264static constexpr uint32_t AUTORESEARCH_SERIAL_WAIT_MS = 2000;
266static constexpr uint32_t AUTORESEARCH_SERIAL_WAIT_MS = SERIAL_TIMEOUT_MS;
274static constexpr uint32_t AUTORESEARCH_WATCHDOG_TIMEOUT_MS = 5000;
286static constexpr uint32_t AUTORESEARCH_SETUP_WATCHDOG_TIMEOUT_MS = 20000;
298#define PIN_TX g_autoresearch_state->pin_tx
299#define PIN_RX g_autoresearch_state->pin_rx
301#define CHIPSET WS2812B
302#define COLOR_ORDER RGB
307#if defined(FL_IS_TEENSY_4X)
311constexpr int RX_BUFFER_SIZE = 1000 * 32 + 100;
312#elif defined(FL_IS_ESP_32C6) || defined(FL_IS_ESP_32H2) || \
313 defined(FL_IS_ESP_32C5) || defined(FL_IS_RP)
314constexpr int RX_BUFFER_SIZE = 100 * 32 + 100;
315#elif defined(FL_IS_ESP_32DEV)
321constexpr int RX_BUFFER_SIZE = 1000 * 32 + 100;
323constexpr int RX_BUFFER_SIZE = 3000 * 32 + 100;
331 if (!channel || channel->getPin() != pin) {
348void init_serial_buffers() {
349#if defined(FL_IS_ESP32) && !defined(FL_IS_ESP_32S2)
352 Serial.setRxBufferSize(4096);
353 Serial.setTxBufferSize(4096);
381#ifndef AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS
382#define AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS 3
403 AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS);
408 init_serial_buffers();
411#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
430#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
437 Serial.setTxTimeoutMs(100);
447#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
448 const fl::u16 watchdog_crash_count =
FastLED.watchdog().consecutiveCrashCount();
449 if (
FastLED.watchdog().isInSafeMode()) {
451 recovery.
set(
"reason",
"watchdog_reset_loop");
452 recovery.
set(
"crashCount",
static_cast<int64_t
>(watchdog_crash_count));
453 recovery.
set(
"safeModeThreshold",
static_cast<int64_t
>(
FastLED.watchdog().safeModeThreshold()));
474 g_rx_buffer_storage.
resize(RX_BUFFER_SIZE);
478 g_autoresearch_state->pin_tx = DEFAULT_PIN_TX;
479 g_autoresearch_state->pin_rx = DEFAULT_PIN_RX;
480 g_autoresearch_state->default_pin_tx = DEFAULT_PIN_TX;
481 g_autoresearch_state->default_pin_rx = DEFAULT_PIN_RX;
482 g_autoresearch_state->rx_buffer = g_rx_buffer_storage;
483 g_autoresearch_state->rx_factory = createRxDevice;
485 const char* loop_back_mode =
PIN_TX ==
PIN_RX ?
"INTERNAL" :
"JUMPER WIRE";
489 ss <<
"\nββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n";
490 ss <<
"β FastLED AutoResearch - Test Matrix Configuration β\n";
491 ss <<
"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n";
494 ss <<
"\n[PLATFORM]\n";
498 ss <<
"\n[HARDWARE]\n";
499 ss <<
" TX Pin: " <<
PIN_TX <<
"\n";
500 ss <<
" RX Pin: " <<
PIN_RX <<
"\n";
502 ss <<
" Loopback Mode: " << loop_back_mode <<
"\n";
503 ss <<
" Color Order: RGB\n";
504 ss <<
" RX Buffer Size: " << RX_BUFFER_SIZE <<
" bytes";
521 ss <<
"\n[REMOTE RPC] Registering JSON RPC functions for dynamic control";
522 RemoteControlSingleton::instance().registerFunctions(g_autoresearch_state);
528 g_autoresearch_state);
535 ss <<
"\n[RX SETUP] Creating RX channel for LED autoresearch\n";
536 ss <<
"[RX CREATE] Creating RX channel on PIN " <<
PIN_RX
537 <<
" (" << (40000000 / 1000000) <<
"MHz, " << RX_BUFFER_SIZE <<
" symbols)";
539 g_autoresearch_state->rx_channel = createRxDevice(
PIN_RX);
541 if (!g_autoresearch_state->rx_channel) {
543 errorData.
set(
"error",
"RxChannelCreationFailed");
544 errorData.
set(
"message",
"Failed to create RX channel during setup");
545 errorData.
set(
"pinRx",
static_cast<int64_t
>(
PIN_RX));
552 ss <<
"[RX CREATE] β RX channel created successfully (will be initialized with config in begin())\n";
553 ss <<
"[RX SETUP] β RX channel ready for LED autoresearch";
562 ss <<
"\n[GPIO BASELINE TEST] Testing GPIO " <<
PIN_TX <<
" β GPIO " <<
PIN_RX <<
" connectivity";
573 g_autoresearch_state->drivers_available =
FastLED.getDriverInfos();
575 ss <<
"\n[DRIVER DISCOVERY]\n";
576 ss <<
" Found " << g_autoresearch_state->drivers_available.size() <<
" driver(s) available:\n";
577 for (fl::size i = 0; i < g_autoresearch_state->drivers_available.size(); i++) {
578 ss <<
" " << (i+1) <<
". " << g_autoresearch_state->drivers_available[i].name.c_str()
579 <<
" (priority: " << g_autoresearch_state->drivers_available[i].priority
580 <<
", enabled: " << (g_autoresearch_state->drivers_available[i].enabled ?
"yes" :
"no") <<
")\n";
588 readyData.
set(
"ready",
true);
589 readyData.
set(
"setupTimeMs",
static_cast<int64_t
>(
millis()));
590 readyData.
set(
"drivers",
static_cast<int64_t
>(g_autoresearch_state->drivers_available.size()));
591 readyData.
set(
"pinTx",
static_cast<int64_t
>(
PIN_TX));
592 readyData.
set(
"pinRx",
static_cast<int64_t
>(
PIN_RX));
595 readyData.
set(
"loopbackMode", loop_back_mode);
596 readyData.
set(
"rxBufferSize",
static_cast<int64_t
>(RX_BUFFER_SIZE));
603 FastLED.watchdog().markBootHealthy();
630 for (
int i = 0; i < 100; i++) {
650 if (g_autoresearch_state->deliberate_hang_requested) {
652#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
662#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
673 FastLED.watchdog().markCleanShutdown();
677 if (!g_autoresearch_state->gpio_baseline_test_done && g_autoresearch_state->rx_channel) {
680 g_autoresearch_state->gpio_baseline_test_done =
true;
685 const int pin_tx = g_autoresearch_state->pin_tx;
686 const int pin_rx = g_autoresearch_state->pin_rx;
688 g_autoresearch_state->rx_channel, pin_tx, pin_rx, 40000000, 100);
689 g_autoresearch_state->led_rx_available = gpio_ok;
691 gpioData.
set(
"success", gpio_ok);
692 gpioData.
set(
"pinTx",
static_cast<int64_t
>(pin_tx));
693 gpioData.
set(
"pinRx",
static_cast<int64_t
>(pin_rx));
694 gpioData.
set(
"hz",
static_cast<int64_t
>(40000000));
695 gpioData.
set(
"symbols",
static_cast<int64_t
>(100));
703 if (now - last_status_ms >= 5000) {
705 status.set(
"ready",
true);
706 status.set(
"uptimeMs",
static_cast<int64_t
>(now));
708 last_status_ms = now;
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 autoResearchExpectedEngines()
AutoResearch that expected engines are available for this platform Prints ERROR if any expected engin...
void autoResearchLowMemoryLoop()
void autoResearchLowMemorySetup()
void pollNetServer()
Service pending peer HTTP requests from the sketch loop.
void pollOtaArtifactUpdate(uint32_t watchdog_restore_ms)
Execute a queued RP2350W update from the sketch loop.
Full PARLIO encode bench for ESP32-P4 (post-byte-LUT, #2526 landed).
PARLIO ISR-streaming functional validation (#2548 deep-dive follow-up).
void printStreamRaw(const char *messageType, const fl::json &data)
Print JSONL stream message directly to Serial, bypassing fl::println.
Issue #2994 repro: compounded per-sequence timing drift vs 3.10.3.
Wave8 expansion micro-benchmark for #2526.
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
constexpr fl::RxBackend RX_BACKEND
Declaration of fl::enableAllDrivers() β enrolls every channel driver available on the current platfor...
static Watchdog & instance() FL_NO_EXCEPT
void begin(fl::u32 timeout_ms) FL_NO_EXCEPT
void setBootloaderEscapeThreshold(fl::u16 threshold) FL_NO_EXCEPT
Set the consecutive-watchdog-reset count that triggers the escape.
bool escapeToBootloaderIfLooping() FL_NO_EXCEPT
Reboot into the bootloader if this looks like a boot loop.
void set(const fl::string &key, const json &value) FL_NO_EXCEPT
static json object() FL_NO_EXCEPT
void clear() FL_NO_EXCEPT
void resize(fl::size n) FL_NO_EXCEPT
fl::task::Handle setupRpcAsyncTask(AutoResearchRemoteControl &remote_control, int interval_ms=10)
Setup async task for JSON-RPC processing.
constexpr int defaultTxPin()
void maybeRegisterStubAutorun(AutoResearchRemoteControl &, fl::shared_ptr< AutoResearchState > state)
On FL_IS_STUB: register a one-shot async task that drives autoresearch.
constexpr int defaultRxPin()
constexpr const char * chipName()
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Status status() FL_NO_EXCEPT
Current connection state.
void run(fl::u32 microseconds, ExecFlags flags) FL_NO_EXCEPT
Run selected task subsystems.
void delay(u32 ms, bool run_async=true) FL_NO_EXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
bool serial_ready() FL_NO_EXCEPT
void setLogLevel(u8 level) FL_NO_EXCEPT
Set the global log level.
fl::u32 millis() FL_NO_EXCEPT
Universal millisecond timer - returns milliseconds since system startup.
void serial_begin(u32 baudRate) FL_NO_EXCEPT
@ PLATFORM_DEFAULT
Use the recommended backend for the active platform (RMT on ESP32; FlexPWM on Teensy 4....
@ FL_LOG_LEVEL_NONE
No logging (completely silent)
bool flush(u32 timeoutMs) FL_NO_EXCEPT
const char * toString(RxDeviceType type) FL_NO_EXCEPT
Convert RxDeviceType to human-readable string.
#define FL_WATCHDOG_AUTO(...)
Unified cross-platform Watchdog Timer API for FastLED.