FastLED 3.9.15
Loading...
Searching...
No Matches

◆ autoResearchChipsetTiming()

void autoResearchChipsetTiming ( fl::AutoResearchConfig & config,
int & total,
int & passed,
uint32_t & out_show_duration_ms,
fl::vector< fl::RunResult > * out_results = nullptr,
int num_runs_per_pattern = 1 )

Definition at line 1011 of file AutoResearchTest.cpp.

1015 {
1016 fl::sstream ss;
1017 ss << "\n========================================\n";
1018 ss << "Testing: " << config.timing_name << "\n";
1019 bool has_spi_config = config.tx_configs.size() > 0 && config.tx_configs[0].isSpi();
1020 if (has_spi_config) {
1021 const auto* spi_cfg = config.tx_configs[0].getSpiChipset();
1022 ss << " Protocol: SPI (APA102)\n";
1023 ss << " Clock: " << (spi_cfg ? spi_cfg->timing.clock_hz : 0) << " Hz\n";
1024 } else {
1025 ss << " T0H: " << config.timing.t1_ns << "ns\n";
1026 ss << " T1H: " << (config.timing.t1_ns + config.timing.t2_ns) << "ns\n";
1027 ss << " T0L: " << config.timing.t3_ns << "ns\n";
1028 ss << " RESET: " << config.timing.reset_us << "us\n";
1029 }
1030 ss << " Channels: " << config.tx_configs.size() << "\n";
1031 ss << "========================================";
1032 FL_WARN(ss.str());
1033
1034 // Create ALL channels from tx_configs (multi-channel support)
1036 for (size_t i = 0; i < config.tx_configs.size(); i++) {
1038 if (config.tx_configs[i].isSpi()) {
1039 // SPI chipset: pass through the SPI config directly
1040 channel = FastLED.add(config.tx_configs[i]);
1041 } else {
1042 // Clockless chipset: re-create with runtime timing
1043 fl::ChannelConfig channel_config(config.tx_configs[i].getDataPin(), config.timing, config.tx_configs[i].mLeds, config.tx_configs[i].rgb_order);
1044 channel = FastLED.add(channel_config);
1045 }
1046 if (!channel) {
1047 FL_ERROR("Failed to create channel " << i << " (pin " << config.tx_configs[i].getDataPin() << ") - platform not supported");
1048 // Clean up previously created channels
1049 for (auto& ch : channels) {
1050 ch.reset();
1051 }
1052 return;
1053 }
1054 channels.push_back(channel);
1055 }
1056
1057 FastLED.setBrightness(255);
1058
1059 // Pre-initialize the TX engine to avoid first-call setup delays
1060 for (size_t i = 0; i < config.tx_configs.size(); i++) {
1061 fill_solid(config.tx_configs[i].mLeds.data(), config.tx_configs[i].mLeds.size(), CRGB::Black);
1062 }
1063 FastLED.show();
1064 if (!FastLED.wait(1000)) { // 1s timeout - driver stall guard
1065 FL_ERROR("[PREINIT] TX wait timeout - driver may be stalled on this platform");
1067 return;
1068 }
1069 // TX engine pre-init logging silenced for speed
1070
1071 // CRITICAL: Wait for PARLIO streaming transmission to complete before starting tests
1072 // Without this delay, the RX will capture the pre-initialization BLACK frame instead of the test pattern
1073 // PARLIO is a streaming engine with ring buffers - need time to drain the initial frame
1074 delay(5); // Reduced from 100ms - just enough for buffer drain
1075
1076 // Run test patterns (mixed bit patterns to test MSB vs LSB handling)
1077 int total = 0;
1078 int passed = 0;
1079
1080 // Multi-run configuration - optimized for speed
1081 fl::MultiRunConfig multi_config;
1082 // num_runs=1: Python orchestrates retries (default).
1083 // num_runs>=2: Back-to-back captures of the same buffer to expose second-frame
1084 // degradation (e.g., SPI driver zeroing its DMA buffer after the first show()).
1085 multi_config.num_runs = (num_runs_per_pattern > 0) ? num_runs_per_pattern : 1;
1086 multi_config.print_all_runs = (multi_config.num_runs > 1);
1087 multi_config.print_per_led_errors = false; // Errors reported via JSON-RPC
1088 multi_config.max_errors_per_run = 10; // Store first 10 errors for JSON response
1089
1090 // Measure show-only duration (excludes setup/teardown overhead)
1091 uint32_t show_start_ms = millis();
1092
1093 // Test all 4 bit patterns (0-3)
1094 for (int pattern_id = 0; pattern_id < 4; pattern_id++) {
1095 // Apply pattern to all lanes
1096 for (size_t i = 0; i < config.tx_configs.size(); i++) {
1098 config.tx_configs[i].mLeds.data(),
1099 config.tx_configs[i].mLeds.size(),
1100 pattern_id
1101 );
1102 }
1103 runMultiTest(getBitPatternName(pattern_id), config, multi_config, total, passed, out_results);
1104 }
1105
1106 out_show_duration_ms += millis() - show_start_ms;
1107
1108 // Results reported via JSON-RPC (verbose logging silenced for speed)
1109
1110 // Accumulate results for driver-level tracking
1111 driver_total += total;
1112 driver_passed += passed;
1113
1114 // Destroy ALL channels before testing next timing configuration
1115 // CRITICAL: Clear FastLED's global channel registry to prevent accumulation
1116 // If we only destroy local shared_ptrs, FastLED still holds references
1118 // Channel destruction is synchronous - no delay needed
1119}
const char * getBitPatternName(int pattern_id)
void runMultiTest(const char *test_name, fl::AutoResearchConfig &config, const fl::MultiRunConfig &multi_config, int &total, int &passed, fl::vector< fl::RunResult > *out_results)
void setMixedBitPattern(CRGB *leds, size_t count, int pattern_id)
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:580
const T * data() const FL_NOEXCEPT
Definition span.h:461
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
string str() const FL_NOEXCEPT
Definition strstream.h:43
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NOEXCEPT
Fill a range of LEDs with a solid color.
Definition fill.cpp.hpp:9
#define FL_WARN(X)
Definition log.h:276
#define FL_ERROR(X)
Definition log.h:219
fl::u32 uint32_t
Definition s16x16x4.h:219
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
void delay(u32 ms, bool run_async=true) FL_NOEXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
Definition delay.h:98
const fl::ChipsetTimingConfig & timing
Chipset timing configuration to test.
const char * timing_name
Timing name for logging (e.g., "WS2812B-V5")
fl::span< fl::ChannelConfig > tx_configs
TX channel configurations to test (mutable for LED manipulation)
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Definition crgb.h:510
Configuration for a single LED channel.
Definition config.h:163
u32 t1_ns
T0H: High time for bit 0 (nanoseconds)
u32 t2_ns
T1H-T0H: Additional high time for bit 1 (nanoseconds)
u32 reset_us
Reset/latch time (microseconds)
u32 t3_ns
T0L: Low tail duration (nanoseconds)
bool print_per_led_errors
Print every LED error (default: false)
int max_errors_per_run
Max errors to store per run (default: 5)
bool print_all_runs
Print all run results (default: only errors)
int num_runs
Number of runs to execute.
Multi-run test configuration.

References fl::CRGB::Black, CHANNELS, fl::span< T, Extent >::data(), FastLED, fill_solid(), FL_ERROR, FL_WARN, getBitPatternName(), fl::MultiRunConfig::max_errors_per_run, fl::MultiRunConfig::num_runs, fl::MultiRunConfig::print_all_runs, fl::MultiRunConfig::print_per_led_errors, fl::vector< T >::push_back(), fl::ChipsetTimingConfig::reset_us, runMultiTest(), setMixedBitPattern(), fl::span< T, Extent >::size(), fl::sstream::str(), fl::ChipsetTimingConfig::t1_ns, fl::ChipsetTimingConfig::t2_ns, fl::ChipsetTimingConfig::t3_ns, fl::AutoResearchConfig::timing, fl::AutoResearchConfig::timing_name, and fl::AutoResearchConfig::tx_configs.

Referenced by autoresearch::maybeRegisterStubAutorun(), AutoResearchRemoteControl::runParallelTestImpl(), AutoResearchRemoteControl::runSingleTestImpl(), and testDriver().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: