FastLED 3.10.6
Loading...
Searching...
No Matches
sketch_macros.h
Go to the documentation of this file.
1#pragma once
2
3// Pull in platform detection BEFORE the tier classification fires. Without
4// this, FL_IS_ARM_LPC / FL_IS_TEENSY_LC / FL_IS_STM32_F1 etc. -- the gates
5// in the Low-tier branch below -- are undefined when sketch_macros.h is
6// transitively included via fl/system/engine_events.h before any other
7// platform-aware include. Result: LPC builds get FL_PLATFORM_HAS_LARGE_MEMORY=1
8// (wrong) and pull in FASTLED_HAS_ENGINE_EVENTS code that lacks symbol
9// definitions -- link fails. Pulling is_platform.h here makes the detection
10// canonical regardless of include order.
11#include "platforms/is_platform.h"
12
13// Four-tier platform-memory classification (FastLED #3000).
14//
15// Canonical names:
16// FL_PLATFORM_HAS_TINY_MEMORY — 1 on parts with <=1KB SRAM
17// (classic ATtiny <=512B, ATtiny1604 1KB,
18// select modern tinyAVR 0/1-series with
19// <=1KB SRAM — see FL_IS_AVR_ATTINY_TINY_MEMORY
20// in is_avr.h; 2-series parts with 2KB+ are
21// excluded; ATmega8/8A via
22// FL_IS_AVR_ATMEGA_TINY_MEMORY)
23// FL_PLATFORM_HAS_LARGE_MEMORY — 1 on the "high" tier (Apollo3, nRF52,
24// SAMD21, generic ARM)
25// FL_PLATFORM_HAS_HUGE_MEMORY — 1 on the "huge" tier (ESP32, Teensy
26// 3.5/3.6/4.x, RP2040/RP2350, SAMD51,
27// STM32F4+/H7, native/WASM)
28//
29// Tier truth table:
30// Tiny: TINY=1, LARGE=0, HUGE=0 (<=1KB SRAM parts)
31// Low: TINY=0, LARGE=0, HUGE=0 (AVR Uno/Nano/Leonardo, ATtiny 2-3KB,
32// ESP8266, Teensy LC/3.0/3.1/3.2, STM32F1,
33// Renesas UNO, LPC8xx)
34// High: TINY=0, LARGE=1, HUGE=0
35// Huge: TINY=0, LARGE=1, HUGE=1
36//
37// Invariants:
38// HUGE=1 implies LARGE=1. LARGE=0 implies HUGE=0.
39// TINY=1 implies LARGE=0 and HUGE=0.
40//
41// Backward compatibility (#3000):
42// The names `SKETCH_HAS_TINY_MEMORY`, `SKETCH_HAS_LARGE_MEMORY`,
43// `SKETCH_HAS_HUGE_MEMORY` (and `_OVERRIDDEN` variants, plus the older
44// `SKETCH_HAS_LOTS_OF_MEMORY` / `SKETCH_HAS_VERY_LARGE_MEMORY` aliases)
45// are preserved as deprecated aliases so external user sketches keep
46// compiling. Internal FastLED code is migrating to the
47// `FL_PLATFORM_HAS_*` names over a series of follow-up PRs; both names
48// work identically until that migration completes. Either name can be
49// used as a build-flag override (e.g. `-DSKETCH_HAS_LARGE_MEMORY=1` or
50// `-DFL_PLATFORM_HAS_LARGE_MEMORY=1`).
51//
52// Override mechanism: define the macro to 0 or 1 in build flags or
53// before including FastLED. The header detects the override and sets
54// the corresponding `_OVERRIDDEN` flag, which `platforms/*/compile_test.hpp`
55// uses to skip the platform-default sanity assertion.
56
57// =============================================================================
58// Tier 1: tiny (<=1KB SRAM)
59// =============================================================================
60//
61// Detect BEFORE computing LARGE/HUGE so the invariant TINY=1 → LARGE=0,
62// HUGE=0 holds for the platform-default paths.
63//
64// `FL_IS_AVR_ATTINY_TINY_MEMORY` is defined in `platforms/avr/is_avr.h`
65// (included via `platforms/is_platform.h` upstream in FastLED.h).
66#if defined(FL_PLATFORM_HAS_TINY_MEMORY) || defined(SKETCH_HAS_TINY_MEMORY)
67 // User-supplied override. Accept either spelling.
68 #ifndef FL_PLATFORM_HAS_TINY_MEMORY
69 #define FL_PLATFORM_HAS_TINY_MEMORY SKETCH_HAS_TINY_MEMORY
70 #endif
71 #define FL_PLATFORM_HAS_TINY_MEMORY_OVERRIDDEN 1
72#else
73 #if defined(FL_IS_AVR_ATTINY_TINY_MEMORY) || defined(FL_IS_AVR_ATMEGA_TINY_MEMORY)
74 #define FL_PLATFORM_HAS_TINY_MEMORY 1
75 #else
76 #define FL_PLATFORM_HAS_TINY_MEMORY 0
77 #endif
78#endif
79
80// =============================================================================
81// Tier 3: large / high (>= 256KB flash, "high" tier)
82// =============================================================================
83#if defined(FL_PLATFORM_HAS_LARGE_MEMORY) || defined(SKETCH_HAS_LARGE_MEMORY)
84 // User-supplied override. Accept either spelling.
85 #ifndef FL_PLATFORM_HAS_LARGE_MEMORY
86 #define FL_PLATFORM_HAS_LARGE_MEMORY SKETCH_HAS_LARGE_MEMORY
87 #endif
88 #define FL_PLATFORM_HAS_LARGE_MEMORY_OVERRIDDEN 1
89#else
90 #if defined(FL_IS_AVR) \
91 || defined(__AVR_ATtiny85__) \
92 || defined(__AVR_ATtiny88__) \
93 || defined(__AVR_ATmega32U4__) \
94 || defined(ARDUINO_attinyxy6) \
95 || defined(ARDUINO_attinyxy4) \
96 || defined(FL_IS_TEENSY_LC) \
97 || defined(FL_IS_TEENSY_30) \
98 || defined(FL_IS_TEENSY_31) \
99 || defined(FL_IS_TEENSY_32) \
100 || defined(FL_IS_STM32_F1) \
101 || defined(FL_IS_ESP8266) \
102 || defined(ARDUINO_ARCH_RENESAS_UNO) \
103 || defined(ARDUINO_BLUEPILL_F103C8) \
104 || defined(FL_IS_ARM_LPC)
105 #define FL_PLATFORM_HAS_LARGE_MEMORY 0
106 #else
107 #define FL_PLATFORM_HAS_LARGE_MEMORY 1
108 #endif
109#endif
110
111// =============================================================================
112// Tier 4: huge (>= 256KB RAM, "huge" tier)
113// =============================================================================
114//
115// ESP32 (all), Teensy 4.x/3.5/3.6, RP2040/RP2350, SAMD51, STM32F4+/H7,
116// native/WASM.
117#if defined(FL_PLATFORM_HAS_HUGE_MEMORY) || defined(SKETCH_HAS_HUGE_MEMORY)
118 // User-supplied override. Accept either spelling.
119 #ifndef FL_PLATFORM_HAS_HUGE_MEMORY
120 #define FL_PLATFORM_HAS_HUGE_MEMORY SKETCH_HAS_HUGE_MEMORY
121 #endif
122 #define FL_PLATFORM_HAS_HUGE_MEMORY_OVERRIDDEN 1
123#else
124 #if defined(FL_IS_ESP32) \
125 || defined(FL_IS_TEENSY_35) \
126 || defined(FL_IS_TEENSY_36) \
127 || defined(FL_IS_TEENSY_4X) \
128 || defined(ARDUINO_ARCH_RP2040) \
129 || defined(PICO_RP2040) \
130 || defined(PICO_RP2350) \
131 || defined(__SAMD51__) \
132 || defined(STM32F4xx) || defined(STM32H7xx) || defined(ARDUINO_GIGA) \
133 || defined(FASTLED_STUB_IMPL) \
134 || defined(__EMSCRIPTEN__)
135 #define FL_PLATFORM_HAS_HUGE_MEMORY 1
136 #else
137 #define FL_PLATFORM_HAS_HUGE_MEMORY 0
138 #endif
139#endif
140
141// =============================================================================
142// Invariant enforcement
143// =============================================================================
144#if FL_PLATFORM_HAS_HUGE_MEMORY && !FL_PLATFORM_HAS_LARGE_MEMORY
145 #error "FL_PLATFORM_HAS_HUGE_MEMORY=1 requires FL_PLATFORM_HAS_LARGE_MEMORY=1"
146#endif
147#if FL_PLATFORM_HAS_TINY_MEMORY && FL_PLATFORM_HAS_LARGE_MEMORY
148 #error "FL_PLATFORM_HAS_TINY_MEMORY=1 is incompatible with FL_PLATFORM_HAS_LARGE_MEMORY=1"
149#endif
150
151// =============================================================================
152// AutoResearch tier — `FL_AUTORESEARCH_LITE_RPC`
153// =============================================================================
154//
155// Auto-derived from the memory tier: on the "Low" and "Tiny" tiers where
156// FL_PLATFORM_HAS_LARGE_MEMORY == 0 (LPC8xx, AVR Uno-class, STM32F1, ESP8266,
157// Teensy LC/3.0-3.2, Renesas UNO, ATtiny 2-3 KB) the AutoResearch sketch
158// enters lite mode: it drops JSON-shaped RPC handlers (which pull `fl::json`
159// output builder + tokenizer into flash — ~4 KB) and any float-dependent RPC
160// bodies (which pull soft-float libgcc helpers — ~4 KB). What remains is the
161// CSV-string RPC path that platform driver validation actually needs:
162// `echo`, `pinToggleRx`, `ws2812SctTest`, `pwmDmaCl*`, `dmaSpi*`.
163//
164// Override with `-DFL_AUTORESEARCH_LITE_RPC=0` (force full-fat mode on a
165// low-memory platform — will likely overflow flash) or `=1` (force lite mode
166// on a large-memory platform — useful for measuring what lite-mode ships).
167//
168// Rationale: LPC845 has 64 KB flash. Vanilla AutoResearch on LPC845 already
169// sits at ~53 KB / 83%. Once `FASTLED_LPC_PWM_DMA=1` or `FASTLED_LPC_SPI_DMA=1`
170// pull in the DMA harness code, the sketch needs the lite path to survive
171// the flash budget. The lite gate keeps the same CSV RPC contract so the
172// Python-side test runners (`ci/autoresearch/test_lpc_*.py`) do not have to
173// branch by build mode.
174#if defined(FL_AUTORESEARCH_LITE_RPC)
175 #define FL_AUTORESEARCH_LITE_RPC_OVERRIDDEN 1
176#else
177 #if !FL_PLATFORM_HAS_LARGE_MEMORY
178 #define FL_AUTORESEARCH_LITE_RPC 1
179 #else
180 #define FL_AUTORESEARCH_LITE_RPC 0
181 #endif
182#endif
183
184// =============================================================================
185// Backward-compat aliases (FastLED #3000)
186// =============================================================================
187//
188// The legacy `SKETCH_HAS_*_MEMORY` names mirror the canonical
189// `FL_PLATFORM_HAS_*_MEMORY` defines verbatim. Both names will continue
190// to evaluate identically; new code should prefer the `FL_PLATFORM_HAS_*`
191// names. The `_OVERRIDDEN` variants are also mirrored for parity with
192// the platform `compile_test.hpp` files that key off them.
193//
194// `#ifndef` guards protect the case where the user already supplied
195// `SKETCH_HAS_*` (which we picked up above as an override) — preventing
196// a redefinition warning.
197#ifndef SKETCH_HAS_TINY_MEMORY
198 #define SKETCH_HAS_TINY_MEMORY FL_PLATFORM_HAS_TINY_MEMORY
199#endif
200#ifndef SKETCH_HAS_LARGE_MEMORY
201 #define SKETCH_HAS_LARGE_MEMORY FL_PLATFORM_HAS_LARGE_MEMORY
202#endif
203#ifndef SKETCH_HAS_HUGE_MEMORY
204 #define SKETCH_HAS_HUGE_MEMORY FL_PLATFORM_HAS_HUGE_MEMORY
205#endif
206
207#ifdef FL_PLATFORM_HAS_TINY_MEMORY_OVERRIDDEN
208 #ifndef SKETCH_HAS_TINY_MEMORY_OVERRIDDEN
209 #define SKETCH_HAS_TINY_MEMORY_OVERRIDDEN 1
210 #endif
211#endif
212#ifdef FL_PLATFORM_HAS_LARGE_MEMORY_OVERRIDDEN
213 #ifndef SKETCH_HAS_LARGE_MEMORY_OVERRIDDEN
214 #define SKETCH_HAS_LARGE_MEMORY_OVERRIDDEN 1
215 #endif
216#endif
217#ifdef FL_PLATFORM_HAS_HUGE_MEMORY_OVERRIDDEN
218 #ifndef SKETCH_HAS_HUGE_MEMORY_OVERRIDDEN
219 #define SKETCH_HAS_HUGE_MEMORY_OVERRIDDEN 1
220 #endif
221#endif
222
223// Older spellings still seen in some user sketches.
224#ifndef SKETCH_HAS_LOTS_OF_MEMORY
225 #define SKETCH_HAS_LOTS_OF_MEMORY FL_PLATFORM_HAS_LARGE_MEMORY
226#endif
227#ifndef SKETCH_HAS_VERY_LARGE_MEMORY
228 #define SKETCH_HAS_VERY_LARGE_MEMORY FL_PLATFORM_HAS_HUGE_MEMORY
229#endif
230
231// =============================================================================
232// Misc utilities (kept as-is)
233// =============================================================================
234#ifndef SKETCH_STRINGIFY
235#define SKETCH_STRINGIFY_HELPER(x) #x
236#define SKETCH_STRINGIFY(x) SKETCH_STRINGIFY_HELPER(x)
237#endif
238
239// SKETCH_HALT and SKETCH_HALT_OK macros have been removed.
240// They caused watchdog timer resets on ESP32-C6 due to the infinite while(1) loop
241// preventing loop() from returning.
242//
243// Replacement: Use a static flag to run tests once:
244//
245// Pattern:
246// static bool tests_run = false;
247//
248// void loop() {
249// if (tests_run) {
250// delay(1000);
251// return;
252// }
253// tests_run = true;
254//
255// // ... your test code here ...
256// FL_PRINT("Tests complete");
257// }
258//
259// This allows loop() to return normally, preventing watchdog timer resets.