17#if FL_PLATFORM_HAS_LARGE_MEMORY
20#define DEBUG_PRINT(x) do {} while(0)
21#define DEBUG_PRINTLN(x) do {} while(0)
80void printRemoteResponseRaw(
const fl::json& response) {
90 Serial.write(
reinterpret_cast<const uint8_t*
>(data),
static_cast<size_t>(len));
105 output.
set(
"type", messageType);
109 auto keys = data.
keys();
110 for (fl::size i = 0; i < keys.size(); i++) {
111 output.
set(keys[i].c_str(), data[keys[i]]);
129enum class ReturnCode :
int {
136fl::json makeResponse(
bool success, ReturnCode returnCode,
const char* message,
139 r.
set(
"success", success);
140 r.
set(
"returnCode",
static_cast<int64_t
>(
static_cast<int>(returnCode)));
141 r.
set(
"message", message);
165 bool auto_apply =
true;
167 if (
args.is_array() &&
args.size() >= 1 &&
args[0].is_object()) {
168 fl::json config =
args[0];
169 if (config.
contains(
"startPin") && config[
"startPin"].is_int()) {
170 start_pin =
static_cast<int>(config[
"startPin"].
as_int().value());
172 if (config.
contains(
"endPin") && config[
"endPin"].is_int()) {
173 end_pin =
static_cast<int>(config[
"endPin"].
as_int().value());
175 if (config.
contains(
"autoApply") && config[
"autoApply"].is_bool()) {
176 auto_apply = config[
"autoApply"].
as_bool().value();
181 if (start_pin < 0 || start_pin > 48 || end_pin < 0 || end_pin > 48 || start_pin >= end_pin) {
182 response.set(
"error",
"InvalidRange");
183 response.set(
"message",
"Pin range must be 0-48 with startPin < endPin");
199 fl::u64 skipped_mask = 0;
200 auto recordSkip = [&](
int p,
const char* reason) {
202 if (skipped_mask & bit) {
207 entry.
set(
"pin",
static_cast<int64_t
>(p));
208 entry.
set(
"reason", reason);
212 FL_DBG(
"[PIN PROBE] Searching for connected pin pairs in range " << start_pin <<
"-" << end_pin);
215 auto testPinPair = [](
int tx,
int rx) ->
bool {
232 return (rx_when_tx_low == LOW) && (rx_when_tx_high == HIGH);
243 auto tryDirection = [&](
int tx,
int rx) ->
bool {
248 return testPinPair(tx, rx);
251 for (
int a = start_pin; a <= end_pin && found_tx < 0; a++) {
260 for (
int b = a + 1; b <= end_pin; b++) {
265 if (tryDirection(a, b)) {
268 FL_DBG(
"[PIN PROBE] Found connected pair: TX=" << found_tx <<
" -> RX=" << found_rx);
271 if (tryDirection(b, a)) {
274 FL_DBG(
"[PIN PROBE] Found connected pair (reversed): TX=" << found_tx <<
" -> RX=" << found_rx);
281 search_range.
push_back(
static_cast<int64_t
>(start_pin));
282 search_range.
push_back(
static_cast<int64_t
>(end_pin));
283 response.set(
"searchRange", search_range);
289 response.set(
"skippedPins", skipped_pins);
291 if (found_tx >= 0 && found_rx >= 0) {
294 response.set(
"txPin",
static_cast<int64_t
>(found_tx));
295 response.set(
"rxPin",
static_cast<int64_t
>(found_rx));
299 int old_tx =
mState->pin_tx;
300 int old_rx =
mState->pin_rx;
301 bool tx_changed = (found_tx != old_tx);
302 bool rx_changed = (found_rx != old_rx);
304 fl::shared_ptr<fl::RxChannel> replacement_rx;
307 replacement_rx =
mState->rx_factory(found_rx);
309 if (!replacement_rx) {
311 response.set(
"error",
"RxChannelCreationFailed");
312 response.set(
"message",
"Failed to recreate RX channel on discovered pin");
320 if (tx_changed || rx_changed) {
321 mState->invalidateLedRxValidation();
323 mState->pin_tx = found_tx;
324 mState->pin_rx = found_rx;
326 mState->rx_channel = replacement_rx;
329 FL_DBG(
"[PIN PROBE] Auto-applied pins: TX=" << found_tx <<
", RX=" << found_rx);
331 response.set(
"previousTxPin",
static_cast<int64_t
>(old_tx));
332 response.set(
"previousRxPin",
static_cast<int64_t
>(old_rx));
335 response.set(
"message",
"Use setPins to apply the found pins");
340 response.set(
"message",
"No connected pin pairs found. Please connect a jumper wire between two GPIO pins.");
349 printRemoteResponseRaw,
383 mRemote->update(current_millis);
395 mState->ble_server_active =
false;
410 response.set(
"timestamp",
static_cast<int64_t
>(now));
411 response.set(
"uptimeMs",
static_cast<int64_t
>(now));
419 status.set(
"ready",
true);
420 status.set(
"pinTx",
static_cast<int64_t
>(
mState->pin_tx));
421 status.set(
"pinRx",
static_cast<int64_t
>(
mState->pin_rx));
422 status.set(
"transport",
"ble");
431 response.set(
"message",
"BLE remote already active");
442 response.set(
"error",
"BLE not available on this platform");
455 mState->ble_server_active =
true;
AutoResearchBleState & getBleState()
Get current BLE autoresearch state.
#define AUTORESEARCH_BLE_DEVICE_NAME
Bus::FLEX_IO runtime-binding introspection RPC handler (FastLED#3515 Phase B).
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.
void printJsonRaw(const fl::json &json, const char *prefix="REMOTE: ")
Print JSON directly to Serial, bypassing fl::println and ScopedLogDisable This ensures RPC responses ...
Issue #2994 repro: compounded per-sequence timing drift vs 3.10.3.
Wave8 expansion micro-benchmark for #2526.
fl::unique_ptr< fl::Remote > remote
#define FL_BLE_CHAR_TX_UUID
#define FL_BLE_CHAR_RX_UUID
#define FL_BLE_SERVICE_UUID
fl::net::ble — BLE GATT transport layer for JSON-RPC
SPI encoder configuration for clocked LED chipsets.
void bindNetworkMethods(fl::Remote &remote)
void bindRpSpiMethods(fl::Remote &remote)
fl::json stopBleRemote()
Stop BLE remote (destroys BLE Remote + GATT server)
AutoResearchRemoteControl()
Constructor.
void tick(uint32_t current_millis)
Process RPC system (pull + tick + push)
fl::net::ble::TransportState * mBleState
void bindBenchmarkMethods(fl::Remote &remote)
fl::unique_ptr< fl::Remote > mBleRemote
void bindSystemMethods(fl::Remote &remote)
fl::shared_ptr< AutoResearchState > mState
fl::json findConnectedPinsImpl(const fl::json &args)
void bindDriverMethods(fl::Remote &remote)
void registerFunctions(fl::shared_ptr< AutoResearchState > state)
Register all RPC functions with shared autoresearch state.
~AutoResearchRemoteControl()
Destructor.
void bindPinMethods(fl::Remote &remote)
fl::json startBleRemote()
Start BLE remote (creates BLE GATT server + second Remote instance)
void bindAsyncMethods(fl::Remote &remote)
void registerAllMethods(fl::Remote *remote)
Register all RPC methods on a given Remote instance.
fl::unique_ptr< fl::Remote > mRemote
void bindMathMethods(fl::Remote &remote)
void flush() FL_NO_EXCEPT
void bind(const Config< Callable > &config) FL_NO_EXCEPT
Register method with config (name, function, optional metadata)
JSON-RPC server with scheduling support.
const char * c_str() const FL_NO_EXCEPT
bool is_object() const FL_NO_EXCEPT
fl::optional< i64 > as_int() const FL_NO_EXCEPT
void set(const fl::string &key, const json &value) FL_NO_EXCEPT
bool has_value() const FL_NO_EXCEPT
fl::vector< fl::string > keys() const FL_NO_EXCEPT
bool is_null() const FL_NO_EXCEPT
fl::optional< bool > as_bool() const FL_NO_EXCEPT
void push_back(const json &value) FL_NO_EXCEPT
bool contains(size_t idx) const FL_NO_EXCEPT
static json object() FL_NO_EXCEPT
static json array() FL_NO_EXCEPT
Task executor — runs registered task runners and manages the run loop.
Platform-abstracted heap memory query functions.
FastLED's Elegant JSON Library: fl::json
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NO_EXCEPT
void destroyTransport(TransportState *) FL_NO_EXCEPT
Deinitialize BLE stack and free heap state.
fl::pair< fl::function< fl::optional< fl::json >()>, fl::function< void(const fl::json &)> > getTransportCallbacks(TransportState *) FL_NO_EXCEPT
Get RequestSource and ResponseSink lambdas for fl::Remote.
TransportState * createTransport(const char *) FL_NO_EXCEPT
Create BLE GATT server, heap-allocate transport state.
Status status() FL_NO_EXCEPT
Current connection state.
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...
fl::u32 millis() FL_NO_EXCEPT
Universal millisecond timer - returns milliseconds since system startup.
constexpr u64 pinMaskBit(int pin) FL_NO_EXCEPT
Bit for pin in a 64-bit pin mask; 0 when pin is outside [0, 64).
fl::function< void(fl::JsonStreamWriter &)> JsonStreamCallback
const char * pinProbeDriveSkipReason(int pin) FL_NO_EXCEPT
Why a probe may read pin but must not drive it, or nullptr when it may drive it.
fl::function< fl::optional< fl::json >()> createSerialRequestSource(const char *prefix="") FL_NO_EXCEPT
fl::string formatJsonResponse(const fl::json &response, const char *prefix) FL_NO_EXCEPT
Serialize JSON response to a string.
@ SUCCESS
Operation completed successfully.
const char * pinProbeSkipReason(int pin) FL_NO_EXCEPT
Why a probe must not touch pin at all (no pinMode, read or write), or nullptr when it may.
void digitalWrite(int pin, PinValue val) FL_NO_EXCEPT
Write digital value to pin.
PinValue digitalRead(int pin) FL_NO_EXCEPT
Read digital value from pin.
void pinMode(int pin, PinMode mode) FL_NO_EXCEPT
Set pin mode (input, output, pull-up, pull-down)
Base definition for an LED controller.
Platform-neutral "may a pin probe touch this pin?" API.
Promise-based fluent API for FastLED - standalone async primitives.
Umbrella header for SIMD subsystem.