FastLED 3.10.9
Loading...
Searching...
No Matches

◆ legacyAsyncProbe()

fl::json autoresearch::legacyAsyncProbe ( const fl::json & args)
inline

Call after the regular driver test has registered the selected backend.

Poll only at the two observation points; application work between them deliberately performs no delay, yield, wait, or driver servicing.

Definition at line 426 of file AutoResearchLegacyAsync.h.

426 {
427 int pin = 4;
428 int count = 2000;
429 if (args.is_object()) {
430 if (args["pin"].is_int()) { pin = static_cast<int>(args["pin"].as_int().value()); }
431 if (args["numLeds"].is_int()) { count = static_cast<int>(args["numLeds"].as_int().value()); }
432 }
433 fl::json result = fl::json::object();
434 if (count < 100 || count > 4096) {
435 result.set("success", false);
436 result.set("error", "numLeds must be in [100,4096]");
437 return result;
438 }
439 const char* name = legacyClocklessBoundDriverName();
440 auto driver = name ? fl::channelManager().findDriverByName(name) : nullptr;
441 if (!driver) {
442 result.set("success", false);
443 result.set("error", "Run the regular driver test first to register the backend");
444 return result;
445 }
448 const fl::string scenario = args.is_object()
449 ? args["scenario"].as_string().value_or("") : fl::string();
450 const bool legacyOnly = scenario == "replacement" ||
451 (args.is_object() && args["legacyOnly"].as_bool().value_or(false));
452 if (scenario == "mixed" && legacyOnly) {
453 result.set("success", false);
454 result.set("error", "Mixed Channel API coverage requires the manager listener");
455 return result;
456 }
457 LegacyAsyncManagerScope managerScope(legacyOnly);
458#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES // ok platform specific - this fixture requires RMT4-only worker diagnostics or fault-test configuration, with no neutral equivalent.
459 if (scenario == "standalone" || scenario == "enable" || scenario == "backpressure") {
460 if (count < 1000) { count = 1000; }
461 result = legacyAsyncControllerProbe(scenario, pin, count, driver);
462 result.set("legacyOnly", legacyOnly);
463 return result;
464 }
465 if (scenario == "replacement") {
466 if (count < 1000) { count = 1000; }
467 result = legacyAsyncReplacementProbe(pin, count, driver);
468 result.set("legacyOnly", legacyOnly);
469 return result;
470 }
471 if (scenario == "mixed") {
472 if (count < 1000) { count = 1000; }
473 return legacyAsyncMixedProbe(pin, count, driver);
474 }
475 if (args.is_object() && args["overflow"].is_bool() &&
476 args["overflow"].as_bool().value()) {
477 if (count < 1000) { count = 1000; }
478 return legacyAsyncOverflowProbe(count, driver);
479 }
480#endif
481 fl::vector<CRGB> leds;
482 leds.resize(static_cast<size_t>(count));
483 if (leds.size() != static_cast<size_t>(count)) { return legacyPixelAllocationFailure(); }
484 fill_solid(leds.data(), count, CRGB::White);
485 LegacyClocklessProxy proxy(pin, leds.data(), count);
486 if (!proxy.valid()) {
487 result.set("success", false);
488 result.set("error", "Unsupported legacy pin");
489 return result;
490 }
492 const fl::u32 showStarted = fl::micros();
493 FastLED.show();
494 const fl::u32 showDurationUs = fl::micros() - showStarted;
495 auto stateAtReturn = driver->poll().state;
496 const bool returnedActive = stateAtReturn == fl::IChannelDriver::DriverState::BUSY ||
498 size_t encodedBytes = 0;
499 int firstEncodedByte = -1;
500#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES // ok platform specific - this fixture requires RMT4-only worker diagnostics or fault-test configuration, with no neutral equivalent.
501 {
502 auto frame = proxy.frameData().lock();
503 if (frame) {
504 encodedBytes = frame->getSize();
505 if (encodedBytes) { firstEncodedByte = frame->getData()[0]; }
506 }
507 }
508#endif
509 // Mutating the caller's pixels must not mutate the encoded frame in flight.
510 fill_solid(leds.data(), count, CRGB::Blue);
511 unsigned highSamples = 0;
512 const fl::u32 start = fl::micros();
513 int firstHighDelayUs = -1;
514 // Startup may be queued when show returns. Sample through the full drain
515 // window without calling any driver service, wait, yield, or delay.
516 while (fl::micros() - start < 200000) {
517 const fl::u32 elapsed = fl::micros() - start;
518 if (digitalRead(pin)) {
519 ++highSamples;
520 if (firstHighDelayUs < 0) { firstHighDelayUs = static_cast<int>(elapsed); }
521 }
522 }
523 const auto stateAfterIdle = driver->poll().state;
524 const bool completedIndependently = stateAfterIdle == fl::IChannelDriver::DriverState::READY;
525 const bool drained = FastLED.wait(1000);
526 result.set("returnedActive", returnedActive);
527 result.set("stateAtReturn", static_cast<int>(stateAtReturn));
528 result.set("showDurationUs", static_cast<int>(showDurationUs));
529 result.set("encodedBytes", static_cast<int>(encodedBytes));
530 result.set("firstEncodedByte", firstEncodedByte);
531 result.set("firstHighDelayUs", firstHighDelayUs);
532 result.set("padHighSamplesAfterReturn", static_cast<int>(highSamples));
533 result.set("completedWithoutApplicationPolling", completedIndependently);
534 result.set("waitSucceeded", drained);
535#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES // ok platform specific - this fixture requires RMT4-only worker diagnostics or fault-test configuration, with no neutral equivalent.
536 addLegacyTxDiagnostics(result);
537#endif
538#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES && FL_RMT4_ASYNC // ok platform specific - measure the RMT4 worker's stack without adding a cross-platform virtual API.
539 auto& selected = static_cast<fl::Rmt4AsyncDriver&>(fl::BusTraits<fl::Bus::RMT>::instance()); // ok platform specific - observe the selected RMT4 worker internals without adding a generic driver diagnostic API.
540 result.set("workerStackUnusedBytes", static_cast<int>(selected.workerStackHighWaterBytes())); // ok platform specific - observe the selected RMT4 worker internals without adding a generic driver diagnostic API.
541#endif
542 result.set("success", returnedActive && highSamples > 0 && completedIndependently && drained);
543 return result;
544}
CRGB leds[1]
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
@ CHANNELS
Remove all channels from controller list.
Definition FastLED.h:663
const char * legacyClocklessBoundDriverName()
Name of the driver to which public legacy templates are bound.
void clear(bool writeData=false) FL_NO_EXCEPT
Clear the leds, wiping the local array of data.
void show(fl::u8 scale) FL_NO_EXCEPT
Update all our controllers with the current led colors, using the passed in brightness.
void setBrightness(fl::u8 scale) FL_NO_EXCEPT
Set the global brightness scaling.
Definition FastLED.h:1602
void wait() FL_NO_EXCEPT
Wait for all channel bus transmissions to complete.
fl::shared_ptr< IChannelDriver > findDriverByName(const fl::string &name) const FL_NO_EXCEPT
Silent counterpart to getDriverByName().
static json object() FL_NO_EXCEPT
Definition json.h:864
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NO_EXCEPT
Fill a range of LEDs with a solid color.
Definition fill.cpp.hpp:10
fl::json legacyPixelAllocationFailure()
ChannelManager & channelManager() FL_NO_EXCEPT
Get the global ChannelManager singleton instance.
fl::u32 micros() FL_NO_EXCEPT
Universal microsecond timer - returns microseconds since system startup.
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
PinValue digitalRead(int pin) FL_NO_EXCEPT
Read digital value from pin.
Definition pin.cpp.hpp:55
corkscrew_args args
Definition old.h:149
AutoResearch registers a ChannelManager for its selectable driver tests.
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
Definition crgb.h:519
@ White
<div style='background:#FFFFFF;width:4em;height:4em;'></div>
Definition crgb.h:653
@ READY
Hardware idle; ready to accept new transmissions.
Definition driver.h:170
@ DRAINING
All channels submitted; still transmitting.
Definition driver.h:172
@ BUSY
Active: channels transmitting or queued.
Definition driver.h:171

References args, fl::CRGB::Blue, fl::IChannelDriver::DriverState::BUSY, fl::channelManager(), CHANNELS, fl::IChannelDriver::DriverState::DRAINING, FastLED, fill_solid(), fl::ChannelManager::findDriverByName(), leds, legacyClocklessBoundDriverName(), legacyPixelAllocationFailure(), fl::micros(), fl::json::object(), fl::IChannelDriver::DriverState::READY, LegacyClocklessProxy::valid(), and fl::CRGB::White.

+ Here is the call graph for this function: