Run the PARLIO streaming functional test.
109 {
112 r.completed = false;
113 r.explicit_tx_pins = tx_pins != nullptr;
114 r.base_tx_pin = base_tx_pin;
115 r.lanes = num_lanes;
116 r.leds_per_lane = num_leds;
117 r.iterations = iterations;
118 r.timeout_ms = timeout_ms;
119 r.failed_iter = -1;
120 for (
int lane = 0; lane <
kMaxLanes; ++lane) {
121 r.tx_pins[lane] = -1;
122 }
123
124 if (iterations < 1) iterations = 1;
126 r.iterations = iterations;
127 if (!tx_pins && base_tx_pin < 0) return r;
128 if (num_lanes < 1 || num_lanes > 16) return r;
129 if (num_leds < 1) return r;
130 if (tx_pins) {
131 base_tx_pin = tx_pins[0];
132 r.base_tx_pin = base_tx_pin;
133 for (int lane = 0; lane < num_lanes; ++lane) {
134 if (tx_pins[lane] < 0) return r;
135 }
136 }
137
138#if defined(ARDUINO_ARCH_ESP32) || defined(ESP_PLATFORM)
139
140
141
144 for (int lane = 0; lane < num_lanes; ++lane) {
145 for (int i = 0; i < num_leds; ++i) {
146 leds[lane][i] =
CRGB(0xF0, 0x0F, 0xAA);
147 }
148 }
149
150 fl::ChipsetTimingConfig timing =
152
153 fl::ChannelOptions parlio_opts;
156
158
159 fl::vector<fl::shared_ptr<fl::Channel>> channels;
160 for (int lane = 0; lane < num_lanes; ++lane) {
161 const int tx_pin = tx_pins ? tx_pins[lane] : (base_tx_pin + lane);
162 r.tx_pins[lane] = tx_pin;
165 return r;
166 }
167 fl::ChannelConfig cfg(
168 tx_pin,
169 timing,
170 fl::span<CRGB>(
leds[lane], num_leds),
172 parlio_opts);
174 if (!ch) {
176 return r;
177 }
179 }
180 r.channels_ok = true;
181
182 bool ok = true;
186 for (int iter = 0; iter < iterations; ++iter) {
192 const uint32_t show_us = t_show - t0;
193 const uint32_t wait_us = t1 - t_show;
195 r.per_iter_us[iter] = dt;
196 r.per_iter_show_us[iter] = show_us;
197 r.per_iter_wait_us[iter] = wait_us;
198 if (dt > timeout_ms * 1000u) {
199 r.failed_iter = iter;
200 ok = false;
201 break;
202 }
203 if (iter > 0) {
204 steady_total += dt;
205 steady_show_total += show_us;
206 steady_wait_total += wait_us;
207 }
208 }
209
211
212#if defined(ESP32) && FASTLED_ESP32_HAS_PARLIO
213 {
214 auto metrics = fl::detail::ParlioEngine::getInstance().getDebugMetrics();
215 r.tx_done_count = metrics.mTxDoneCount;
216 r.worker_isr_count = metrics.mWorkerIsrCount;
217 r.underrun_count = metrics.mUnderrunCount;
218 r.ring_count = metrics.mRingCount;
219 r.bytes_total = metrics.mBytesTotal;
220 r.bytes_transmitted = metrics.mBytesTransmitted;
221 r.ring_error = metrics.mRingError;
222 r.hardware_idle = metrics.mHardwareIdle;
223 }
224#endif
225
226 r.completed = ok;
227 if (ok && iterations > 1) {
228 r.steady_avg_us = steady_total / (iterations - 1);
229 r.steady_avg_show_us = steady_show_total / (iterations - 1);
230 r.steady_avg_wait_us = steady_wait_total / (iterations - 1);
231 } else if (ok) {
232 r.steady_avg_us = r.per_iter_us[0];
233 r.steady_avg_show_us = r.per_iter_show_us[0];
234 r.steady_avg_wait_us = r.per_iter_wait_us[0];
235 }
236#else
237 (void)base_tx_pin;
238 (void)timeout_ms;
239#endif
240 return r;
241}
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
void clear(bool writeData=false) FL_NO_EXCEPT
Clear the leds, wiping the local array of data.
static void add(fl::ChannelPtr channel) FL_NO_EXCEPT
Add a Channel-based LED controller (from ChannelPtr)
void show(fl::u8 scale) FL_NO_EXCEPT
Update all our controllers with the current led colors, using the passed in brightness.
void wait() FL_NO_EXCEPT
Wait for all channel bus transmissions to complete.
void push_back(const T &value) FL_NO_EXCEPT
@ CHANNELS
Remove all channels from controller list.
ParlioLedState & parlioLedState()
constexpr int kMaxIterations
bool isFastLedOutputPinValid(int pin)
CRGB leds[kMaxLanes][kMaxLeds]
constexpr ChipsetTimingConfig makeTimingConfig() FL_NO_EXCEPT
Convert compile-time CHIPSET type to runtime timing config.
fl::u32 micros() FL_NO_EXCEPT
Universal microsecond timer - returns microseconds since system startup.