FastLED 3.9.15
Loading...
Searching...
No Matches
bus.h
Go to the documentation of this file.
1#pragma once
2
14
15#include "fl/stl/noexcept.h"
17#include "fl/stl/stdint.h"
18#include "platforms/is_platform.h"
19
20// Platform CMSIS/Arduino headers (pulled in transitively above) define
21// peripheral pointer macros that collide with our `Bus` enumerator names.
22// Sam3X8E in particular does:
23// #define UART ((Uart *)0x400E0800U)
24// #define SPI ((Spi *)0x40008000U)
25// Without these undefs, the preprocessor expands those names inside
26// `enum class Bus { ..., SPI, UART, ... }`, producing a syntax error
27// (see FastLED sam3x8e_due CI failure). Push the originals so any
28// downstream TU that needs the register macros keeps working.
29#pragma push_macro("UART")
30#pragma push_macro("SPI")
31#pragma push_macro("I2S")
32#undef UART
33#undef SPI
34#undef I2S
35
36// Post-#2428 architecture: drivers do NOT auto-register with `ChannelManager`.
37// Only the platform-default driver TU (named by the legacy clockless controller's
38// Phase 5b pre-bind via `BusTraits<DefaultBus<Chipset>>::instancePtr()`) links
39// into the binary. Users who need additional drivers at runtime call:
40// - `fl::enableDrivers<fl::Bus::X, ...>()` for selective opt-in,
41// - `FastLED.enableAllDrivers()` for 3.10.3-style universal enrollment,
42// - `FastLED.setExclusiveDriver<fl::Bus::X>()` to register a non-default driver
43// at high priority (must be called before `addLeds<>` to override the pre-bind).
44//
45// The historical `FASTLED_DISABLE_LEGACY_DRIVER_REGISTRY` opt-in macro has been
46// removed; the previously opt-in behaviour is now the only behaviour.
47
48namespace fl {
49
50// Forward declarations. The chipset family types live in fl/channels/config.h,
51// but DefaultBus<Chipset> only needs the type identity, not the layout.
52struct ClocklessChipset;
53struct SpiChipsetConfig;
54
77
88template<typename Chipset> struct DefaultBus;
89
90// ---------------------------------------------------------------------------
91// Per-platform DefaultBus<Chipset> specializations
92// ---------------------------------------------------------------------------
93//
94// Each specialization sets `value` to the Bus identifier whose driver TU should
95// be linked when the user does not name a bus explicitly.
96
97#if defined(FL_IS_STUB) || defined(FL_IS_WASM)
98
99template<> struct DefaultBus<ClocklessChipset> {
100 static constexpr Bus value = Bus::STUB;
101};
102
103template<> struct DefaultBus<SpiChipsetConfig> {
104 static constexpr Bus value = Bus::STUB;
105};
106
107#elif defined(FL_IS_ESP32)
108
109// ESP32-P4 / C6 / H2 / C5 -- PARLIO is the highest-priority clockless driver.
110// ESP32-dev / S2 / S3 -- RMT is the recommended clockless default.
111// Mirrors the priority order used by channel_manager_esp32.cpp.hpp.
112#if defined(FL_IS_ESP_32P4) || defined(FL_IS_ESP_32C6) || \
113 defined(FL_IS_ESP_32H2) || defined(FL_IS_ESP_32C5)
114template<> struct DefaultBus<ClocklessChipset> {
115 static constexpr Bus value = Bus::PARLIO;
116};
117#else
118template<> struct DefaultBus<ClocklessChipset> {
119 static constexpr Bus value = Bus::RMT;
120};
121#endif
122
123// True SPI chipsets (APA102, SK9822, HD108): pick the platform-native parallel
124// SPI driver. ESP32-S3 uses LCD_SPI; original ESP32 uses I2S_SPI; other variants
125// are intentionally undefined so users get a clear "specify Bus::X explicitly"
126// error rather than a silent wrong default.
127#if defined(FL_IS_ESP_32S3)
128template<> struct DefaultBus<SpiChipsetConfig> {
129 static constexpr Bus value = Bus::LCD_SPI;
130};
131#elif defined(FL_IS_ESP_32DEV)
132template<> struct DefaultBus<SpiChipsetConfig> {
133 static constexpr Bus value = Bus::I2S_SPI;
134};
135#endif
136
137#elif defined(FL_IS_TEENSY_4X)
138
139template<> struct DefaultBus<ClocklessChipset> {
140 static constexpr Bus value = Bus::OBJECT_FLED;
141};
142// SpiChipsetConfig default for Teensy 4.x is intentionally unspecified -- users
143// pick explicitly between Bus::BIT_BANG and any future hardware-SPI bus.
144
145#endif
146
167inline const char* busName(Bus b) FL_NOEXCEPT {
168 switch (b) {
169 case Bus::AUTO: return "AUTO";
170 case Bus::RMT: return "RMT";
171 case Bus::PARLIO: return "PARLIO";
172 case Bus::SPI: return "SPI";
173 case Bus::I2S: return "I2S";
174 case Bus::I2S_SPI: return "I2S_SPI";
175 case Bus::LCD_RGB: return "LCD_RGB";
176 case Bus::LCD_SPI: return "LCD_SPI";
177 case Bus::LCD_CLOCKLESS: return "LCD_CLOCKLESS";
178 case Bus::UART: return "UART";
179 case Bus::FLEX_IO: return "FLEX_IO";
180 case Bus::OBJECT_FLED: return "OBJECT_FLED";
181 case Bus::LPUART: return "LPUART";
182 case Bus::BIT_BANG: return "BIT_BANG";
183 case Bus::STUB: return "STUB";
184 }
185 return ""; // unreachable — silences -Wreturn-type on toolchains that miss the exhaustive switch
186}
187
188// Drift-prevention: if a new `Bus` enumerator is added, the switch above must
189// gain a case. Update this assertion to the new last enumerator after you
190// wire the case in — its failure is the prompt to revisit `busName()`.
192 "Bus changed: add the new value to busName() in this file"); // ok plain enum
193
194} // namespace fl
195
196// Restore the original platform macros for any downstream code that needs
197// the CMSIS / Arduino register pointers.
198#pragma pop_macro("I2S")
199#pragma pop_macro("SPI")
200#pragma pop_macro("UART")
unsigned char u8
Definition s16x16x4.h:132
constexpr int type_rank< T >::value
const char * busName(Bus b) FL_NOEXCEPT
Canonical driver-name string for a Bus value.
Definition bus.h:167
Bus
Driver identifier for compile-time bus selection.
Definition bus.h:60
@ LPUART
Teensy 4.x iMXRT1062 LPUART (inverted-TX + eDMA) clockless driver.
Definition bus.h:73
@ FLEX_IO
Teensy 4.x FlexIO2 driver.
Definition bus.h:71
@ I2S_SPI
Original ESP32 native I2S parallel SPI (true SPI chipsets).
Definition bus.h:66
@ SPI
Generic SPI clockless driver.
Definition bus.h:64
@ PARLIO
ESP32-P4/C6/H2/C5 parallel I/O peripheral.
Definition bus.h:63
@ OBJECT_FLED
Teensy 4.x ObjectFLED driver.
Definition bus.h:72
@ LCD_RGB
ESP32-P4 LCD RGB peripheral (parallel clockless).
Definition bus.h:67
@ LCD_CLOCKLESS
ESP32-S3 LCD_CAM clockless driver (replaces misnamed I2S).
Definition bus.h:69
@ I2S
ESP32-S3 LCD_CAM via legacy I80 bus (clockless).
Definition bus.h:65
@ BIT_BANG
Portable bit-bang fallback driver.
Definition bus.h:74
@ LCD_SPI
ESP32-S3 LCD_CAM SPI driver (true SPI chipsets).
Definition bus.h:68
@ RMT
ESP32 RMT peripheral (all ESP32 variants).
Definition bus.h:62
@ UART
ESP32 UART driver via wave8 framing.
Definition bus.h:70
@ AUTO
Sentinel: defer to DefaultBus<Chipset>::value.
Definition bus.h:61
@ STUB
Native/host/test stub driver.
Definition bus.h:75
Base definition for an LED controller.
Definition crgb.hpp:179
Per-platform default bus for a given chipset family.
Definition bus.h:88
#define FL_STATIC_ASSERT(...)
#define FL_NOEXCEPT
Portable compile-time assertion wrapper.
Clockless chipset configuration (single data pin)
Definition config.h:32
SPI chipset configuration (data + clock pins)
Definition config.h:102