FastLED 3.10.6
Loading...
Searching...
No Matches
bus_info.h
Go to the documentation of this file.
1#pragma once
2
5
6#include "fl/channels/bus.h"
7#include "fl/stl/noexcept.h"
8#include "fl/stl/stdint.h"
9
10namespace fl {
11
13 bool available = false;
14 bool initialized = false;
15 bool ready = false;
16 bool busy = false;
17 const char* error = "";
18
20
21 DeviceRuntime(bool availableValue, bool initializedValue,
22 bool readyValue, bool busyValue,
23 const char* errorValue) FL_NO_EXCEPT
24 : available(availableValue),
25 initialized(initializedValue),
26 ready(readyValue),
27 busy(busyValue),
28 error(errorValue) {}
29};
30
31struct DeviceInfo {
34 const char* bus_name = "AUTO";
35 const char* vendor_name = "NOOP";
36 const char* device_name = "no-op";
37 const char* notes = "";
38 bool is_noop = true;
40
42
43 DeviceInfo(Bus busValue, fl::u8 whichValue, const char* busNameValue,
44 const char* vendorNameValue, const char* deviceNameValue,
45 const char* notesValue, bool isNoopValue,
46 const DeviceRuntime& runtimeValue) FL_NO_EXCEPT
47 : bus(busValue),
48 which(whichValue),
49 bus_name(busNameValue),
50 vendor_name(vendorNameValue),
51 device_name(deviceNameValue),
52 notes(notesValue),
53 is_noop(isNoopValue),
54 runtime(runtimeValue) {}
55};
56
57namespace detail {
58
60 return DeviceRuntime{true, false, true, false, ""};
61}
62
64 return DeviceRuntime{false, false, false, false, "unavailable"};
65}
66
67inline DeviceInfo makeInfo(Bus bus, fl::u8 which, const char* vendor,
68 const char* device, const char* notes = "") FL_NO_EXCEPT {
69 return DeviceInfo{bus, which, busName(bus, which), vendor, device, notes,
70 false, availableRuntime()};
71}
72
73inline DeviceInfo makeNoop(Bus bus, fl::u8 which, const char* notes = "") FL_NO_EXCEPT {
74 return DeviceInfo{bus, which, busName(bus, which), "NOOP", "no-op", notes,
75 true, unavailableRuntime()};
76}
77
78template<Bus B, fl::u8 Which>
80 static inline DeviceInfo get() FL_NO_EXCEPT {
81 return makeNoop(B, Which);
82 }
83};
84
85template<fl::u8 Which>
86struct DeviceInfoResolver<Bus::AUTO, Which> {
87 static inline DeviceInfo get() FL_NO_EXCEPT {
88 return DeviceInfo{Bus::AUTO, Which, "AUTO", "AUTO",
89 "(auto -- resolves per chipset)", "",
90 false, availableRuntime()};
91 }
92};
93
94template<fl::u8 Which>
96 static inline DeviceInfo get() FL_NO_EXCEPT {
97 return Which == 0
98 ? makeInfo(Bus::BIT_BANG, Which, "BIT_BANG", "portable bit-bang")
99 : makeNoop(Bus::BIT_BANG, Which, "out of range");
100 }
101};
102
103#if defined(FL_IS_TEENSY_4X)
104
105template<> struct DeviceInfoResolver<Bus::FLEX_IO, 0> {
106 static inline DeviceInfo get() FL_NO_EXCEPT {
107 return makeInfo(Bus::FLEX_IO, 0, "OBJECT_FLED", "ObjectFLED");
108 }
109};
110
111template<> struct DeviceInfoResolver<Bus::FLEX_IO, 1> {
112 static inline DeviceInfo get() FL_NO_EXCEPT {
113 return makeInfo(Bus::FLEX_IO, 1, "FLEXIO", "FlexIO2");
114 }
115};
116
117template<> struct DeviceInfoResolver<Bus::SPI, 0> {
118 static inline DeviceInfo get() FL_NO_EXCEPT {
119 return makeInfo(Bus::SPI, 0, "LPSPI", "LPSPI4");
120 }
121};
122
123template<> struct DeviceInfoResolver<Bus::SPI, 1> {
124 static inline DeviceInfo get() FL_NO_EXCEPT {
125 return makeInfo(Bus::SPI, 1, "LPSPI", "LPSPI1");
126 }
127};
128
129template<> struct DeviceInfoResolver<Bus::SPI, 2> {
130 static inline DeviceInfo get() FL_NO_EXCEPT {
131 return makeInfo(Bus::SPI, 2, "LPSPI", "LPSPI2");
132 }
133};
134
135template<> struct DeviceInfoResolver<Bus::SPI, 3> {
136 static inline DeviceInfo get() FL_NO_EXCEPT {
137 return makeInfo(Bus::SPI, 3, "LPSPI", "LPSPI3");
138 }
139};
140
141template<> struct DeviceInfoResolver<Bus::UART, 0> {
142 static inline DeviceInfo get() FL_NO_EXCEPT {
143 return makeInfo(Bus::UART, 0, "LPUART", "LPUART parallel");
144 }
145};
146
147#elif defined(FL_IS_ARM_LPC_845)
148
149template<> struct DeviceInfoResolver<Bus::UART, 0> {
150 static inline DeviceInfo get() FL_NO_EXCEPT {
151#if FASTLED_LPC_UART_DMA
152 return makeInfo(Bus::UART, 0, "LPC_USART_DMA", "USART TX DMA");
153#else
154 return makeNoop(Bus::UART, 0, "UART DMA disabled");
155#endif
156 }
157};
158
159#elif defined(FL_IS_RP2040) || defined(FL_IS_RP2350)
160
161template<> struct DeviceInfoResolver<Bus::FLEX_IO, 0> {
162 static inline DeviceInfo get() FL_NO_EXCEPT {
163 return makeInfo(Bus::FLEX_IO, 0, "PIO", "RP PIO0");
164 }
165};
166
167template<> struct DeviceInfoResolver<Bus::FLEX_IO, 1> {
168 static inline DeviceInfo get() FL_NO_EXCEPT {
169 return makeInfo(Bus::FLEX_IO, 1, "PIO", "RP PIO1");
170 }
171};
172
173template<> struct DeviceInfoResolver<Bus::UART, 0> {
174 static inline DeviceInfo get() FL_NO_EXCEPT {
175 return makeInfo(Bus::UART, 0, "PL011", "RP UART0");
176 }
177};
178
179template<> struct DeviceInfoResolver<Bus::UART, 1> {
180 static inline DeviceInfo get() FL_NO_EXCEPT {
181 return makeInfo(Bus::UART, 1, "PL011", "RP UART1");
182 }
183};
184
185// RP's two fixed SPI blocks are PL022 controllers, registered as concrete
186// Bus::SPI instances 0 and 1 by rp_spi_bus_traits.h. Without these the
187// generic resolver reports them as unavailable no-ops, which is wrong: they
188// are real engines that resolve and run.
189template<> struct DeviceInfoResolver<Bus::SPI, 0> {
190 static inline DeviceInfo get() FL_NO_EXCEPT {
191 return makeInfo(Bus::SPI, 0, "PL022", "RP SPI0");
192 }
193};
194
195template<> struct DeviceInfoResolver<Bus::SPI, 1> {
196 static inline DeviceInfo get() FL_NO_EXCEPT {
197 return makeInfo(Bus::SPI, 1, "PL022", "RP SPI1");
198 }
199};
200
201#if defined(FL_IS_RP2350)
202template<> struct DeviceInfoResolver<Bus::FLEX_IO, 2> {
203 static inline DeviceInfo get() FL_NO_EXCEPT {
204 return makeInfo(Bus::FLEX_IO, 2, "PIO", "RP2350 PIO2");
205 }
206};
207#endif
208
209#elif defined(FL_IS_ESP32)
210
211template<> struct DeviceInfoResolver<Bus::RMT, 0> {
212 static inline DeviceInfo get() FL_NO_EXCEPT {
213#if FASTLED_HAS_RMT5
214 return makeInfo(Bus::RMT, 0, "RMT5", "ESP32 RMT5");
215#elif FASTLED_HAS_RMT4
216 return makeInfo(Bus::RMT, 0, "RMT4", "ESP32 RMT4");
217#else
218 return makeNoop(Bus::RMT, 0, "RMT unavailable");
219#endif
220 }
221};
222
223template<> struct DeviceInfoResolver<Bus::FLEX_IO, 0> {
224 static inline DeviceInfo get() FL_NO_EXCEPT {
225#if FASTLED_HAS_PARLIO
226 return makeInfo(Bus::FLEX_IO, 0, "PARLIO", "ESP32 PARLIO");
227#elif FASTLED_HAS_LCD_SPI || FASTLED_HAS_LCD_CAM_CLOCKLESS
228 return makeInfo(Bus::FLEX_IO, 0, "LCD_CAM", "ESP32-S3 LCD_CAM");
229#elif FASTLED_HAS_I2S_SPI
230 return makeInfo(Bus::FLEX_IO, 0, "I2S", "ESP32 I2S parallel SPI");
231#else
232 return makeNoop(Bus::FLEX_IO, 0, "parallel I/O unavailable");
233#endif
234 }
235};
236
237template<> struct DeviceInfoResolver<Bus::FLEX_IO, 1> {
238 static inline DeviceInfo get() FL_NO_EXCEPT {
239#if FASTLED_HAS_LCD_CAM_CLOCKLESS || FASTLED_HAS_LCD_SPI
240 return makeInfo(Bus::FLEX_IO, 1, "LCD_CAM", "ESP32-S3 LCD_CAM secondary");
241#else
242 return makeNoop(Bus::FLEX_IO, 1, "secondary parallel I/O unavailable");
243#endif
244 }
245};
246
247template<> struct DeviceInfoResolver<Bus::SPI, 0> {
248 static inline DeviceInfo get() FL_NO_EXCEPT {
249 return makeInfo(Bus::SPI, 0, "ESP_SPI_HW", "ESP32 SPI");
250 }
251};
252
253template<> struct DeviceInfoResolver<Bus::SPI, 1> {
254 static inline DeviceInfo get() FL_NO_EXCEPT {
255#if defined(FL_IS_ESP_32S3)
256 return makeInfo(Bus::SPI, 1, "ESP_SPI_HW", "ESP32-S3 SPI2");
257#else
258 return makeNoop(Bus::SPI, 1, "out of range");
259#endif
260 }
261};
262
263template<> struct DeviceInfoResolver<Bus::UART, 0> {
264 static inline DeviceInfo get() FL_NO_EXCEPT {
265 return makeInfo(Bus::UART, 0, "ESP32_UART", "UART0");
266 }
267};
268
269template<> struct DeviceInfoResolver<Bus::UART, 1> {
270 static inline DeviceInfo get() FL_NO_EXCEPT {
271#if defined(FL_IS_ESP_32S3) || defined(FL_IS_ESP_32C6)
272 return makeInfo(Bus::UART, 1, "ESP32_UART", "UART1");
273#else
274 return makeNoop(Bus::UART, 1, "out of range");
275#endif
276 }
277};
278
279template<> struct DeviceInfoResolver<Bus::UART, 2> {
280 static inline DeviceInfo get() FL_NO_EXCEPT {
281#if defined(FL_IS_ESP_32S3)
282 return makeInfo(Bus::UART, 2, "ESP32_UART", "UART2");
283#else
284 return makeNoop(Bus::UART, 2, "out of range");
285#endif
286 }
287};
288
289#endif
290
291} // namespace detail
292
293template<Bus B, fl::u8 Which = 0>
297
298} // namespace fl
Portable compile-time identifiers for LED channel buses.
DeviceRuntime unavailableRuntime() FL_NO_EXCEPT
Definition bus_info.h:63
DeviceRuntime availableRuntime() FL_NO_EXCEPT
Definition bus_info.h:59
DeviceInfo makeNoop(Bus bus, fl::u8 which, const char *notes="") FL_NO_EXCEPT
Definition bus_info.h:73
DeviceInfo makeInfo(Bus bus, fl::u8 which, const char *vendor, const char *device, const char *notes="") FL_NO_EXCEPT
Definition bus_info.h:67
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_info.h:57
unsigned char u8
Definition stdint.h:131
FL_DISABLE_WARNING_PUSH unsigned char * B
const char * busName(Bus b, fl::u8 which=0) FL_NO_EXCEPT
Definition bus.h:153
Bus
Portable public bus selector.
Definition bus.h:27
@ FLEX_IO
Definition bus.h:36
@ SPI
Definition bus.h:31
@ BIT_BANG
Definition bus.h:29
@ RMT
Definition bus.h:35
@ UART
Definition bus.h:30
@ AUTO
Definition bus.h:28
DeviceInfo deviceInfo() FL_NO_EXCEPT
Definition bus_info.h:294
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
Base definition for an LED controller.
Definition crgb.hpp:179
const char * bus_name
Definition bus_info.h:34
const char * device_name
Definition bus_info.h:36
DeviceRuntime runtime
Definition bus_info.h:39
fl::u8 which
Definition bus_info.h:33
DeviceInfo() FL_NO_EXCEPT=default
const char * notes
Definition bus_info.h:37
const char * vendor_name
Definition bus_info.h:35
const char * error
Definition bus_info.h:17
DeviceRuntime() FL_NO_EXCEPT=default
static DeviceInfo get() FL_NO_EXCEPT
Definition bus_info.h:87
static DeviceInfo get() FL_NO_EXCEPT
Definition bus_info.h:80