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.
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 }
434 if (count < 100 || count > 4096) {
435 result.set(
"success",
false);
436 result.set(
"error",
"numLeds must be in [100,4096]");
438 }
441 if (!driver) {
442 result.set(
"success",
false);
443 result.set(
"error",
"Run the regular driver test first to register the backend");
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");
456 }
458#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES
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);
464 }
465 if (scenario == "replacement") {
466 if (count < 1000) { count = 1000; }
467 result = legacyAsyncReplacementProbe(pin, count, driver);
468 result.set(
"legacyOnly", legacyOnly);
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));
485 LegacyClocklessProxy proxy(pin,
leds.data(), count);
486 if (!proxy.valid()) {
487 result.set(
"success",
false);
488 result.set(
"error",
"Unsupported legacy pin");
490 }
494 const fl::u32 showDurationUs =
fl::micros() - showStarted;
495 auto stateAtReturn = driver->poll().state;
498 size_t encodedBytes = 0;
499 int firstEncodedByte = -1;
500#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES
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
511 unsigned highSamples = 0;
513 int firstHighDelayUs = -1;
514
515
519 ++highSamples;
520 if (firstHighDelayUs < 0) { firstHighDelayUs = static_cast<int>(elapsed); }
521 }
522 }
523 const auto stateAfterIdle = driver->poll().state;
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
536 addLegacyTxDiagnostics(result);
537#endif
538#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES && FL_RMT4_ASYNC
539 auto& selected = static_cast<fl::Rmt4AsyncDriver&>(fl::BusTraits<fl::Bus::RMT>::instance());
540 result.set(
"workerStackUnusedBytes",
static_cast<int>(selected.workerStackHighWaterBytes()));
541#endif
542 result.set(
"success", returnedActive && highSamples > 0 && completedIndependently && drained);
544}
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
@ CHANNELS
Remove all channels from controller list.
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.
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
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NO_EXCEPT
Fill a range of LEDs with a solid color.
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)
PinValue digitalRead(int pin) FL_NO_EXCEPT
Read digital value from pin.
AutoResearch registers a ChannelManager for its selectable driver tests.
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
@ White
<div style='background:#FFFFFF;width:4em;height:4em;'></div>
@ READY
Hardware idle; ready to accept new transmissions.
@ DRAINING
All channels submitted; still transmitting.
@ BUSY
Active: channels transmitting or queued.