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

◆ measureTightTiming()

fl::json anonymous_namespace{AutoResearchRemote.cpp}::measureTightTiming ( const fl::string & driver_name,
const fl::ChipsetTimingConfig & timing,
const fl::vector< fl::ChannelConfig > & tx_configs,
int iterations,
uint32_t max_allowed_overhead_us,
bool & out_passed )

Definition at line 147 of file AutoResearchRemote.cpp.

152 {
153 fl::json metric = fl::json::object();
154 out_passed = false;
155
156 metric.set("requested", true);
157 metric.set("supported", false);
158 metric.set("driver", driver_name.c_str());
159
160 if (iterations < 1) {
161 metric.set("message", "iterations must be >= 1");
162 return metric;
163 }
164 if (tx_configs.empty()) {
165 metric.set("message", "no channel configs");
166 return metric;
167 }
168 for (fl::size i = 0; i < tx_configs.size(); i++) {
169 if (tx_configs[i].isSpi()) {
170 metric.set("message", "clocked SPI timing metric is not supported");
171 return metric;
172 }
173 }
174
175 fl::vector<fl::ChannelConfig> sample_configs = tx_configs;
176 fl::vector<fl::shared_ptr<fl::Channel>> channels;
177 for (fl::size i = 0; i < sample_configs.size(); i++) {
178 fl::ChannelConfig channel_config(
179 sample_configs[i].getDataPin(),
180 timing,
181 sample_configs[i].mLeds,
182 sample_configs[i].rgb_order);
183 fl::shared_ptr<fl::Channel> channel = FastLED.add(channel_config);
184 if (!channel) {
186 metric.set("message", "failed to create channel");
187 return metric;
188 }
189 channels.push_back(channel);
190 }
191
192 ScopedFastLedBrightness scoped_brightness(255);
193 for (fl::size lane = 0; lane < sample_configs.size(); lane++) {
194 fill_solid(sample_configs[lane].mLeds.data(),
195 sample_configs[lane].mLeds.size(),
197 }
198 FastLED.show();
199 if (!FastLED.wait(1000)) {
201 metric.set("message", "warmup wait timeout");
202 return metric;
203 }
204 delay(2);
205
206 const uint32_t expected_wire_us =
207 expectedClocklessWireUs(timing, maxLaneLeds(sample_configs));
208 uint32_t min_show_us = 0xFFFFFFFFu;
209 uint32_t max_show_us = 0;
210 uint32_t min_wait_us = 0xFFFFFFFFu;
211 uint32_t max_wait_us = 0;
212 uint32_t min_total_us = 0xFFFFFFFFu;
213 uint32_t max_total_us = 0;
214 uint32_t min_overhead_us = 0xFFFFFFFFu;
215 uint32_t max_overhead_us = 0;
216 uint64_t sum_show_us = 0;
217 uint64_t sum_wait_us = 0;
218 uint64_t sum_total_us = 0;
219 uint64_t sum_overhead_us = 0;
220 int samples = 0;
221 bool timed_out = false;
222
223 for (int sample = 0; sample < iterations; sample++) {
224 for (fl::size lane = 0; lane < sample_configs.size(); lane++) {
225 const uint8_t r = static_cast<uint8_t>(31 + sample * 17 + lane * 11);
226 const uint8_t g = static_cast<uint8_t>(67 + sample * 23 + lane * 7);
227 const uint8_t b = static_cast<uint8_t>(103 + sample * 29 + lane * 5);
228 fill_solid(sample_configs[lane].mLeds.data(),
229 sample_configs[lane].mLeds.size(),
230 CRGB(r, g, b));
231 }
232
233 const uint32_t t0 = micros();
234 FastLED.show();
235 const uint32_t t1 = micros();
236 const bool ok = FastLED.wait(1000);
237 const uint32_t t2 = micros();
238 if (!ok) {
239 timed_out = true;
240 break;
241 }
242
243 const uint32_t show_us = t1 - t0;
244 const uint32_t wait_us = t2 - t1;
245 const uint32_t total_us = t2 - t0;
246 const uint32_t overhead_us =
247 total_us > expected_wire_us ? total_us - expected_wire_us : 0;
248
249 if (show_us < min_show_us) min_show_us = show_us;
250 if (show_us > max_show_us) max_show_us = show_us;
251 if (wait_us < min_wait_us) min_wait_us = wait_us;
252 if (wait_us > max_wait_us) max_wait_us = wait_us;
253 if (total_us < min_total_us) min_total_us = total_us;
254 if (total_us > max_total_us) max_total_us = total_us;
255 if (overhead_us < min_overhead_us) min_overhead_us = overhead_us;
256 if (overhead_us > max_overhead_us) max_overhead_us = overhead_us;
257
258 sum_show_us += show_us;
259 sum_wait_us += wait_us;
260 sum_total_us += total_us;
261 sum_overhead_us += overhead_us;
262 samples++;
263 }
264
266
267 metric.set("supported", true);
268 metric.set("samples", static_cast<int64_t>(samples));
269 metric.set("iterations", static_cast<int64_t>(iterations));
270 metric.set("expected_wire_us", static_cast<int64_t>(expected_wire_us));
271 metric.set("max_allowed_overhead_us",
272 static_cast<int64_t>(max_allowed_overhead_us));
273
274 if (samples == 0) {
275 metric.set("passed", false);
276 metric.set("message", timed_out ? "timing wait timeout" : "no samples");
277 return metric;
278 }
279
280 metric.set("min_show_us", static_cast<int64_t>(min_show_us));
281 metric.set("max_show_us", static_cast<int64_t>(max_show_us));
282 metric.set("avg_show_us",
283 static_cast<int64_t>(sum_show_us / static_cast<uint64_t>(samples)));
284 metric.set("min_wait_us", static_cast<int64_t>(min_wait_us));
285 metric.set("max_wait_us", static_cast<int64_t>(max_wait_us));
286 metric.set("avg_wait_us",
287 static_cast<int64_t>(sum_wait_us / static_cast<uint64_t>(samples)));
288 metric.set("min_total_us", static_cast<int64_t>(min_total_us));
289 metric.set("max_total_us", static_cast<int64_t>(max_total_us));
290 metric.set("avg_total_us",
291 static_cast<int64_t>(sum_total_us / static_cast<uint64_t>(samples)));
292 metric.set("min_overhead_us", static_cast<int64_t>(min_overhead_us));
293 metric.set("max_overhead_us", static_cast<int64_t>(max_overhead_us));
294 metric.set("avg_overhead_us",
295 static_cast<int64_t>(sum_overhead_us / static_cast<uint64_t>(samples)));
296
297 out_passed = !timed_out && max_overhead_us <= max_allowed_overhead_us;
298 metric.set("passed", out_passed);
299 if (timed_out) {
300 metric.set("message", "timing wait timeout");
301 } else {
302 metric.set("message", out_passed ? "tight timing within budget"
303 : "tight timing exceeded budget");
304 }
305 return metric;
306}
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
void show(fl::u8 scale)
Update all our controllers with the current led colors, using the passed in brightness.
static void add(fl::ChannelPtr channel)
Add a Channel-based LED controller (from ChannelPtr)
void wait()
Wait for all channel bus transmissions to complete.
void clear(bool writeData=false)
Clear the leds, wiping the local array of data.
const char * c_str() const FL_NOEXCEPT
void set(const fl::string &key, const json &value) FL_NOEXCEPT
Definition json.h:701
static json object() FL_NOEXCEPT
Definition json.h:692
fl::size size() const FL_NOEXCEPT
bool empty() const FL_NOEXCEPT
void push_back(const T &value) FL_NOEXCEPT
Definition vector.h:624
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
fl::CRGB CRGB
Definition crgb.h:25
uint32_t maxLaneLeds(const fl::vector< fl::ChannelConfig > &tx_configs)
uint32_t expectedClocklessWireUs(const fl::ChipsetTimingConfig &timing, uint32_t max_leds)
fl::u32 uint32_t
Definition s16x16x4.h:219
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
CRGB sample(const CRGB *grid, const XYMap &xyMap, float x, float y, SampleMode mode)
Sample a pixel from a 2D CRGB grid at floating-point coordinates.
Definition sample.cpp.hpp:9
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
unsigned char uint8_t
Definition s16x16x4.h:209
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Definition crgb.h:510

References fl::CRGB::Black, fl::basic_string::c_str(), CHANNELS, fl::vector< T >::data(), fl::vector_basic::empty(), expectedClocklessWireUs(), FastLED, fill_solid(), maxLaneLeds(), fl::json::object(), fl::vector< T >::push_back(), fl::json::set(), and fl::vector_basic::size().

+ Here is the call graph for this function: