99 const int* tx_pins =
nullptr) {
103 r.explicit_tx_pins = tx_pins !=
nullptr;
104 r.base_tx_pin = base_tx_pin;
106 r.leds_per_lane = num_leds;
107 r.iterations = iterations;
108 r.timeout_ms = timeout_ms;
110 for (
int lane = 0; lane <
kMaxLanes; ++lane) {
111 r.tx_pins[lane] = -1;
114 if (iterations < 1) iterations = 1;
116 r.iterations = iterations;
117 if (!tx_pins && base_tx_pin < 0)
return r;
118 if (num_lanes < 1 || num_lanes > 16)
return r;
119 if (num_leds < 1)
return r;
121 base_tx_pin = tx_pins[0];
122 r.base_tx_pin = base_tx_pin;
123 for (
int lane = 0; lane < num_lanes; ++lane) {
124 if (tx_pins[lane] < 0)
return r;
128#if defined(ARDUINO_ARCH_ESP32) || defined(ESP_PLATFORM)
132 constexpr int kMaxLEDs = 256;
133 if (num_leds > kMaxLEDs)
return r;
135 for (
int lane = 0; lane < num_lanes; ++lane) {
136 for (
int i = 0; i < num_leds; ++i) {
137 leds[lane][i] =
CRGB(0xF0, 0x0F, 0xAA);
150 for (
int lane = 0; lane < num_lanes; ++lane) {
151 const int tx_pin = tx_pins ? tx_pins[lane] : (base_tx_pin + lane);
152 r.tx_pins[lane] = tx_pin;
170 r.channels_ok =
true;
173 uint32_t steady_total = 0;
174 uint32_t steady_show_total = 0;
175 uint32_t steady_wait_total = 0;
176 for (
int iter = 0; iter < iterations; ++iter) {
177 const uint32_t t0 = micros();
179 const uint32_t t_show = micros();
181 const uint32_t t1 = micros();
182 const uint32_t show_us = t_show - t0;
183 const uint32_t wait_us = t1 - t_show;
184 const uint32_t dt = t1 - t0;
185 r.per_iter_us[iter] = dt;
186 r.per_iter_show_us[iter] = show_us;
187 r.per_iter_wait_us[iter] = wait_us;
188 if (dt > timeout_ms * 1000u) {
189 r.failed_iter = iter;
195 steady_show_total += show_us;
196 steady_wait_total += wait_us;
202#if defined(ESP32) && FASTLED_ESP32_HAS_PARLIO
204 auto metrics = fl::detail::ParlioEngine::getInstance().getDebugMetrics();
205 r.tx_done_count = metrics.mTxDoneCount;
206 r.worker_isr_count = metrics.mWorkerIsrCount;
207 r.underrun_count = metrics.mUnderrunCount;
208 r.ring_count = metrics.mRingCount;
209 r.bytes_total = metrics.mBytesTotal;
210 r.bytes_transmitted = metrics.mBytesTransmitted;
211 r.ring_error = metrics.mRingError;
212 r.hardware_idle = metrics.mHardwareIdle;
217 if (ok && iterations > 1) {
218 r.steady_avg_us = steady_total / (iterations - 1);
219 r.steady_avg_show_us = steady_show_total / (iterations - 1);
220 r.steady_avg_wait_us = steady_wait_total / (iterations - 1);
222 r.steady_avg_us = r.per_iter_us[0];
223 r.steady_avg_show_us = r.per_iter_show_us[0];
224 r.steady_avg_wait_us = r.per_iter_wait_us[0];