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

◆ autoResearchLowMemorySetup()

void autoResearchLowMemorySetup ( )
inline

Definition at line 120 of file AutoResearchLowMemory.h.

120 {
121 fl::serial_begin(115200);
122
123 // Arm the watchdog so a hung sketch unbricks itself on crash.
125
126 // Emit a literal-only warning so the autoresearch harness can verify
127 // the FL_WARN log pipeline reaches the host.
128 FL_WARN_LIT("FL_WARN: low-memory bring-up OK");
129
130 // The C++ inline-ODR rule guarantees a single shared instance across
131 // every translation unit that calls this inline function, which is
132 // exactly what we want (one Remote bound to the singleton Serial
133 // transport). The included-once-per-sketch model of `.ino` builds
134 // also reduces to a single TU in practice.
135 static fl::Remote remote( // okay static in header
137 fl::createSerialResponseSink("REMOTE: "));
139 remote.bind("echo", [](int v) -> int {
140 FL_WARN_LIT("FL_WARN: echo invoked");
141 return v;
142 });
143
144#if defined(FL_IS_ARM_LPC)
145 // pinToggleRx (FastLED #3021 Phase 1) — bit-bang square wave on tx_pin
146 // and capture SCT edges on rx_pin. CSV stats out.
147 remote.bind("pinToggleRx",
148 [](int tx_pin, int rx_pin, int freq_hz, int duration_ms) -> fl::string {
149 if (tx_pin < 0 || rx_pin < 0 || freq_hz <= 0 || duration_ms <= 0) {
150 return fl::string("0,0,0,0,0,0,0");
151 }
152 const fl::u32 expected_edges =
153 2u * static_cast<fl::u32>(freq_hz) *
154 static_cast<fl::u32>(duration_ms) / 1000u;
155 fl::u32 cap = expected_edges + (expected_edges / 2u);
156 if (cap < 256u) cap = 256u;
157 if (cap > 2048u) cap = 2048u;
158
159 auto rx = fl::LpcSctRxChannel::create(rx_pin);
160 if (!rx) return fl::string("0,0,0,0,0,0,0");
161
162 fl::RxConfig cfg;
163 cfg.buffer_size = cap;
164 cfg.start_low = true;
165 if (!rx->begin(cfg)) return fl::string("0,0,0,0,0,0,0");
166
167 pinMode(tx_pin, OUTPUT);
168 digitalWrite(tx_pin, LOW);
169
170 const fl::u32 half_us = 500000u / static_cast<fl::u32>(freq_hz);
171 const fl::u32 cycles = static_cast<fl::u32>(freq_hz) *
172 static_cast<fl::u32>(duration_ms) / 1000u;
173
174 for (fl::u32 i = 0; i < cycles; ++i) {
175 digitalWrite(tx_pin, HIGH);
176 delayMicroseconds(half_us);
177 rx->pollOnce();
178 digitalWrite(tx_pin, LOW);
179 delayMicroseconds(half_us);
180 rx->pollOnce();
181 if ((i & 0x7Fu) == 0u) {
183 }
184 }
185 rx->wait(1);
186
187 fl::EdgeTime edges_buf[2048];
188 const fl::size n_read = rx->getRawEdgeTimes(
189 fl::span<fl::EdgeTime>(edges_buf, sizeof(edges_buf) / sizeof(edges_buf[0])));
190
191 LowMemPinTogglePeriodStats stats = computeLowMemPeriodStats(edges_buf, n_read);
192
193 fl::sstream s;
194 const bool success = (stats.periods > 0);
195 s << (success ? 1 : 0) << ',' << static_cast<fl::u32>(n_read) << ','
196 << stats.periods << ',' << stats.mean_ns << ',' << stats.sigma_ns << ','
197 << stats.min_ns << ',' << stats.max_ns;
198 return s.str();
199 });
200
201#if defined(FASTLED_LPC_RX_SCT_WS2812)
202 // ws2812SctTest (FastLED #3021 Phase 2) -- WS2812 byte-match loopback.
203 remote.bind("ws2812SctTest",
204 [](int test_case, int tx_pin, int rx_pin, int capture_ms) -> fl::string {
205 if (test_case < 0 || test_case > 4 ||
206 tx_pin < 0 || rx_pin < 0 || capture_ms <= 0) {
207 return fl::string("0,0,0,0,0,0,0,0");
208 }
209 int num_leds = 1;
210 switch (test_case) {
211 case 1: num_leds = 3; break;
212 case 4: num_leds = 100; break;
213 default: num_leds = 1; break;
214 }
215 static CRGB leds_buf[100];
216 for (int i = 0; i < num_leds; ++i) {
217 switch (test_case) {
218 case 0: leds_buf[i] = CRGB(0xFF, 0x00, 0x00); break;
219 case 1: {
220 if (i == 0) leds_buf[i] = CRGB(0xFF, 0x00, 0x00);
221 else if (i == 1) leds_buf[i] = CRGB(0x00, 0xFF, 0x00);
222 else leds_buf[i] = CRGB(0x00, 0x00, 0xFF);
223 break;
224 }
225 case 2: leds_buf[i] = CRGB(0x00, 0x00, 0x00); break;
226 case 3: leds_buf[i] = CRGB(0xFF, 0xFF, 0xFF); break;
227 case 4: {
228 const uint8_t r = (i % 3 == 0) ? 0xFFu : 0u;
229 const uint8_t g = (i % 3 == 1) ? 0xFFu : 0u;
230 const uint8_t b = (i % 3 == 2) ? 0xFFu : 0u;
231 leds_buf[i] = CRGB(r, g, b);
232 break;
233 }
234 }
235 }
236 const int expected_bytes = num_leds * 3;
237 static uint8_t expected_buf[300];
238 for (int i = 0; i < num_leds; ++i) {
239 expected_buf[i * 3 + 0] = leds_buf[i].g;
240 expected_buf[i * 3 + 1] = leds_buf[i].r;
241 expected_buf[i * 3 + 2] = leds_buf[i].b;
242 }
243 auto rx = fl::LpcSctRxChannel::create(rx_pin);
244 if (!rx) return fl::string("0,0,0,0,0,0,0,0");
245 fl::RxConfig cfg;
246 const fl::u32 expected_edges = (fl::u32)num_leds * 24u * 2u;
247 fl::u32 cap = expected_edges + (expected_edges / 2u);
248 if (cap < 256u) cap = 256u;
249 if (cap > 2048u) cap = 2048u;
250 cfg.buffer_size = cap;
251 cfg.start_low = true;
252 if (!rx->begin(cfg)) return fl::string("0,0,0,0,0,0,0,0");
253
254 constexpr int kFixedTxPin = 10; // P0_10
255 if (tx_pin != kFixedTxPin) {
256 return fl::string("0,0,0,0,0,0,0,0");
257 }
258 static bool fastled_inited = false;
259 if (!fastled_inited) {
260 FastLED.addLeds<WS2812, kFixedTxPin, GRB>(leds_buf, 100);
261 fastled_inited = true;
262 }
263 FastLED.show();
264 rx->wait(capture_ms);
265
266 static uint8_t decoded_buf[300];
267 for (int i = 0; i < expected_bytes; ++i) decoded_buf[i] = 0;
268
272 /*reset_us=*/0u);
273
274 auto dec = rx->decode(timing, fl::span<u8>(decoded_buf, expected_bytes));
275 const fl::u32 decoded_bytes = dec.ok() ? dec.value() : 0u;
276
277 fl::u32 matched = 0;
278 fl::u32 mismatched = 0;
279 for (fl::u32 i = 0; i < decoded_bytes && i < (fl::u32)expected_bytes; ++i) {
280 if (decoded_buf[i] == expected_buf[i]) ++matched;
281 else ++mismatched;
282 }
283 const fl::u32 missing = (fl::u32)expected_bytes - decoded_bytes;
284 mismatched += missing;
285
286 fl::EdgeTime probe[1024];
287 const fl::size edges_captured = rx->getRawEdgeTimes(
288 fl::span<fl::EdgeTime>(probe, 1024));
289
290 const bool success = (mismatched == 0 && decoded_bytes == (fl::u32)expected_bytes);
291
292 fl::sstream s;
293 s << (success ? 1 : 0) << ',' << test_case << ',' << num_leds << ','
294 << expected_bytes << ',' << decoded_bytes << ','
295 << matched << ',' << mismatched << ','
296 << static_cast<fl::u32>(edges_captured);
297 return s.str();
298 });
299#endif // FASTLED_LPC_RX_SCT_WS2812
300#endif // FL_IS_ARM_LPC
301}
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
fl::unique_ptr< fl::Remote > remote
Definition RpcClient.ino:43
JSON-RPC server with scheduling support.
Definition remote.h:40
static Watchdog & instance() FL_NOEXCEPT
void begin(fl::u32 timeout_ms) FL_NOEXCEPT
void feed() FL_NOEXCEPT
string str() const FL_NOEXCEPT
Definition strstream.h:43
constexpr EOrder GRB
Definition eorder.h:19
fl::CRGB CRGB
Definition crgb.h:25
#define FL_WARN_LIT(LITERAL)
Definition log.h:294
const dec_t dec
Definition ios.cpp.hpp:7
constexpr ChipsetTiming to_runtime_timing() FL_NOEXCEPT
Convert enum-based timing type to runtime ChipsetTiming struct.
Definition led_timing.h:521
void serial_begin(u32 baudRate)
fl::function< fl::optional< fl::json >()> createSerialRequestSource(const char *prefix="")
Create a JSON-RPC RequestSource that reads from fl:: serial input.
Definition serial.h:109
ChipsetTiming4Phase make4PhaseTiming(const ChipsetTiming &timing_3phase, u32 tolerance_ns) FL_NOEXCEPT
Create 4-phase RX timing from 3-phase chipset timing with tolerance.
Definition rx.cpp.hpp:51
void pinMode(int pin, PinMode mode)
Set pin mode (input, output, pull-up, pull-down)
Definition pin.cpp.hpp:378
fl::function< void(const fl::json &)> createSerialResponseSink(const char *prefix="REMOTE: ")
Create a JSON-RPC ResponseSink that writes to fl:: serial output.
Definition serial.h:162
void digitalWrite(int pin, PinValue val)
Write digital value to pin.
Definition pin.cpp.hpp:51
void delayMicroseconds(u32 us)
Delay for a given number of microseconds.
unsigned char uint8_t
Definition s16x16x4.h:209
4-phase RX timing thresholds for chipset detection
Definition rx.h:87
Universal edge timing representation (platform-agnostic)
Definition rx.h:34
size_t buffer_size
Buffer size in symbols/edges (default: 512)
Definition rx.h:218
bool start_low
Pin idle state: true=LOW (WS2812B), false=HIGH (inverted)
Definition rx.h:225
Configuration for RX device initialization.
Definition rx.h:216

References fl::Watchdog::begin(), fl::RxConfig::buffer_size, fl::createSerialRequestSource(), fl::createSerialResponseSink(), FastLED, fl::Watchdog::feed(), FL_WARN_LIT, anonymous_namespace{AutoResearchLowMemory.h}::g_low_memory_remote, GRB, fl::Watchdog::instance(), fl::make4PhaseTiming(), remote, fl::serial_begin(), fl::RxConfig::start_low, fl::sstream::str(), and fl::to_runtime_timing().

+ Here is the call graph for this function: