15#if !FL_PLATFORM_HAS_LARGE_MEMORY
150#define FASTLED_LOG_PARLIO_ASYNC_ENABLED
238#if defined(FL_IS_ESP32) && defined(SET_LOOP_TASK_STACK_SIZE)
239SET_LOOP_TASK_STACK_SIZE(16 * 1024);
261static constexpr uint32_t SERIAL_TIMEOUT_MS = 120000;
262#if defined(FL_IS_ESP_32S3) || defined(FL_IS_ESP_32C3) || \
263 defined(FL_IS_ESP_32C6) || defined(FL_IS_ESP_32H2) || \
264 defined(CONFIG_IDF_TARGET_ESP32P4) || defined(FL_IS_RP)
265static constexpr uint32_t AUTORESEARCH_SERIAL_WAIT_MS = 2000;
267static constexpr uint32_t AUTORESEARCH_SERIAL_WAIT_MS = SERIAL_TIMEOUT_MS;
275static constexpr uint32_t AUTORESEARCH_WATCHDOG_TIMEOUT_MS = 5000;
287static constexpr uint32_t AUTORESEARCH_SETUP_WATCHDOG_TIMEOUT_MS = 20000;
299#define PIN_TX g_autoresearch_state->pin_tx
300#define PIN_RX g_autoresearch_state->pin_rx
302#define CHIPSET WS2812B
303#define COLOR_ORDER RGB
308#if defined(FL_IS_TEENSY_4X)
312constexpr int RX_BUFFER_SIZE = 1000 * 32 + 100;
313#elif defined(FL_IS_ESP_32C6) || defined(FL_IS_ESP_32H2) || \
314 defined(FL_IS_ESP_32C5) || defined(FL_IS_RP)
315constexpr int RX_BUFFER_SIZE = 100 * 32 + 100;
316#elif defined(FL_IS_ESP_32DEV)
322constexpr int RX_BUFFER_SIZE = 1000 * 32 + 100;
324constexpr int RX_BUFFER_SIZE = 3000 * 32 + 100;
330constexpr int RX_BUFFER_SIZE_NO_PSRAM = 1000 * 32 + 100;
332static int rxBufferSize() {
334 if (RX_BUFFER_SIZE > RX_BUFFER_SIZE_NO_PSRAM && heap.
total() > 0 &&
336 return RX_BUFFER_SIZE_NO_PSRAM;
338 return RX_BUFFER_SIZE;
346 if (!channel || channel->getPin() != pin) {
363void init_serial_buffers() {
364#if defined(FL_IS_ESP32) && !defined(FL_IS_ESP_32S2)
367 Serial.setRxBufferSize(4096);
368 Serial.setTxBufferSize(4096);
396#ifndef AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS
397#define AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS 3
418 AUTORESEARCH_BOOTLOADER_ESCAPE_RESETS);
423 init_serial_buffers();
426#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
445#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
452 Serial.setTxTimeoutMs(100);
462#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
463 const fl::u16 watchdog_crash_count =
FastLED.watchdog().consecutiveCrashCount();
464 if (
FastLED.watchdog().isInSafeMode()) {
466 recovery.
set(
"reason",
"watchdog_reset_loop");
467 recovery.
set(
"crashCount",
static_cast<int64_t
>(watchdog_crash_count));
468 recovery.
set(
"safeModeThreshold",
static_cast<int64_t
>(
FastLED.watchdog().safeModeThreshold()));
489 g_rx_buffer_storage.
resize(rxBufferSize());
493 g_autoresearch_state->pin_tx = DEFAULT_PIN_TX;
494 g_autoresearch_state->pin_rx = DEFAULT_PIN_RX;
495 g_autoresearch_state->default_pin_tx = DEFAULT_PIN_TX;
496 g_autoresearch_state->default_pin_rx = DEFAULT_PIN_RX;
497 g_autoresearch_state->rx_buffer = g_rx_buffer_storage;
498 g_autoresearch_state->rx_factory = createRxDevice;
500 const char* loop_back_mode =
PIN_TX ==
PIN_RX ?
"INTERNAL" :
"JUMPER WIRE";
504 ss <<
"\nββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n";
505 ss <<
"β FastLED AutoResearch - Test Matrix Configuration β\n";
506 ss <<
"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n";
509 ss <<
"\n[PLATFORM]\n";
513 ss <<
"\n[HARDWARE]\n";
514 ss <<
" TX Pin: " <<
PIN_TX <<
"\n";
515 ss <<
" RX Pin: " <<
PIN_RX <<
"\n";
517 ss <<
" Loopback Mode: " << loop_back_mode <<
"\n";
518 ss <<
" Color Order: RGB\n";
519 ss <<
" RX Buffer Size: " << g_rx_buffer_storage.
size() <<
" bytes";
536 ss <<
"\n[REMOTE RPC] Registering JSON RPC functions for dynamic control";
537 RemoteControlSingleton::instance().registerFunctions(g_autoresearch_state);
543 g_autoresearch_state);
550 ss <<
"\n[RX SETUP] Creating RX channel for LED autoresearch\n";
551 ss <<
"[RX CREATE] Creating RX channel on PIN " <<
PIN_RX
552 <<
" (" << (40000000 / 1000000) <<
"MHz, " << g_rx_buffer_storage.
size() <<
" symbols)";
554 g_autoresearch_state->rx_channel = createRxDevice(
PIN_RX);
556 if (!g_autoresearch_state->rx_channel) {
558 errorData.
set(
"error",
"RxChannelCreationFailed");
559 errorData.
set(
"message",
"Failed to create RX channel during setup");
560 errorData.
set(
"pinRx",
static_cast<int64_t
>(
PIN_RX));
567 ss <<
"[RX CREATE] β RX channel created successfully (will be initialized with config in begin())\n";
568 ss <<
"[RX SETUP] β RX channel ready for LED autoresearch";
577 ss <<
"\n[GPIO BASELINE TEST] Testing GPIO " <<
PIN_TX <<
" β GPIO " <<
PIN_RX <<
" connectivity";
588 g_autoresearch_state->drivers_available =
FastLED.getDriverInfos();
590 ss <<
"\n[DRIVER DISCOVERY]\n";
591 ss <<
" Found " << g_autoresearch_state->drivers_available.size() <<
" driver(s) available:\n";
592 for (fl::size i = 0; i < g_autoresearch_state->drivers_available.size(); i++) {
593 ss <<
" " << (i+1) <<
". " << g_autoresearch_state->drivers_available[i].name.c_str()
594 <<
" (priority: " << g_autoresearch_state->drivers_available[i].priority
595 <<
", enabled: " << (g_autoresearch_state->drivers_available[i].enabled ?
"yes" :
"no") <<
")\n";
603 readyData.
set(
"ready",
true);
604 readyData.
set(
"setupTimeMs",
static_cast<int64_t
>(
millis()));
605 readyData.
set(
"drivers",
static_cast<int64_t
>(g_autoresearch_state->drivers_available.size()));
606 readyData.
set(
"pinTx",
static_cast<int64_t
>(
PIN_TX));
607 readyData.
set(
"pinRx",
static_cast<int64_t
>(
PIN_RX));
610 readyData.
set(
"loopbackMode", loop_back_mode);
611 readyData.
set(
"rxBufferSize",
static_cast<int64_t
>(g_rx_buffer_storage.
size()));
618 FastLED.watchdog().markBootHealthy();
645 for (
int i = 0; i < 100; i++) {
665 if (g_autoresearch_state->deliberate_hang_requested) {
667#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
677#if !defined(FL_IS_STUB) && !defined(FL_IS_WASM)
688 FastLED.watchdog().markCleanShutdown();
692 if (!g_autoresearch_state->gpio_baseline_test_done && g_autoresearch_state->rx_channel) {
695 g_autoresearch_state->gpio_baseline_test_done =
true;
700 const int pin_tx = g_autoresearch_state->pin_tx;
701 const int pin_rx = g_autoresearch_state->pin_rx;
703 g_autoresearch_state->rx_channel, pin_tx, pin_rx, 40000000, 100);
704 g_autoresearch_state->led_rx_available = gpio_ok;
706 gpioData.
set(
"success", gpio_ok);
707 gpioData.
set(
"pinTx",
static_cast<int64_t
>(pin_tx));
708 gpioData.
set(
"pinRx",
static_cast<int64_t
>(pin_rx));
709 gpioData.
set(
"hz",
static_cast<int64_t
>(40000000));
710 gpioData.
set(
"symbols",
static_cast<int64_t
>(100));
718 if (now - last_status_ms >= 5000) {
720 status.set(
"ready",
true);
721 status.set(
"uptimeMs",
static_cast<int64_t
>(now));
723 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
fl::size size() const FL_NO_EXCEPT
void resize(fl::size n) FL_NO_EXCEPT
Platform-abstracted heap memory query functions.
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
HeapInfo getFreeHeap() FL_NO_EXCEPT
Query available heap memory.
const char * toString(RxBackend backend) FL_NO_EXCEPT
fl::size total() const FL_NO_EXCEPT
Total free heap (SRAM + PSRAM)
bool has_psram() const FL_NO_EXCEPT
Check if PSRAM is available.
#define FL_WATCHDOG_AUTO(...)
Unified cross-platform Watchdog Timer API for FastLED.