25#ifdef FASTLED_ALL_PINS_VALID
27namespace pin_port_table {
29constexpr int TABLE_SIZE = 64;
31using port_ptr_t =
typename FastPin<0>::port_ptr_t;
33template <
int N>
struct PortEntry {
38 static port_ptr_t table[TABLE_SIZE] = {
39 PortEntry<0>::get(), PortEntry<1>::get(), PortEntry<2>::get(), PortEntry<3>::get(),
40 PortEntry<4>::get(), PortEntry<5>::get(), PortEntry<6>::get(), PortEntry<7>::get(),
41 PortEntry<8>::get(), PortEntry<9>::get(), PortEntry<10>::get(), PortEntry<11>::get(),
42 PortEntry<12>::get(), PortEntry<13>::get(), PortEntry<14>::get(), PortEntry<15>::get(),
43 PortEntry<16>::get(), PortEntry<17>::get(), PortEntry<18>::get(), PortEntry<19>::get(),
44 PortEntry<20>::get(), PortEntry<21>::get(), PortEntry<22>::get(), PortEntry<23>::get(),
45 PortEntry<24>::get(), PortEntry<25>::get(), PortEntry<26>::get(), PortEntry<27>::get(),
46 PortEntry<28>::get(), PortEntry<29>::get(), PortEntry<30>::get(), PortEntry<31>::get(),
47 PortEntry<32>::get(), PortEntry<33>::get(), PortEntry<34>::get(), PortEntry<35>::get(),
48 PortEntry<36>::get(), PortEntry<37>::get(), PortEntry<38>::get(), PortEntry<39>::get(),
49 PortEntry<40>::get(), PortEntry<41>::get(), PortEntry<42>::get(), PortEntry<43>::get(),
50 PortEntry<44>::get(), PortEntry<45>::get(), PortEntry<46>::get(), PortEntry<47>::get(),
51 PortEntry<48>::get(), PortEntry<49>::get(), PortEntry<50>::get(), PortEntry<51>::get(),
52 PortEntry<52>::get(), PortEntry<53>::get(), PortEntry<54>::get(), PortEntry<55>::get(),
53 PortEntry<56>::get(), PortEntry<57>::get(), PortEntry<58>::get(), PortEntry<59>::get(),
54 PortEntry<60>::get(), PortEntry<61>::get(), PortEntry<62>::get(), PortEntry<63>::get(),
60 if (pin < 0 || pin >= TABLE_SIZE)
return nullptr;
61 return portTable()[pin];
65 const port_ptr_t* table = portTable();
66 for (
int i = 0; i < TABLE_SIZE; ++i) {
67 if (table[i] !=
nullptr)
return false;
75 if (pin < 0)
return -1;
77 if (!pin_port_table::allPortsNull()) {
78 auto ptr = pin_port_table::getPortPtr(pin);
79 if (ptr ==
nullptr)
return -1;
82 const auto* table = pin_port_table::portTable();
83 for (
int i = 0; i < pin_port_table::TABLE_SIZE; ++i) {
84 if (table[i] == ptr) {
86 for (
int j = 0; j < i; ++j) {
88 for (
int k = 0; k < j; ++k) {
89 if (table[k] == table[j]) { unique =
false;
break; }
91 if (unique && table[j] !=
nullptr) ++id;
103#elif defined(FASTLED_NO_PINMAP)
109 if (pin < 0)
return -1;
130 return static_cast<int>(v);
138 static T* seen[8] = {};
140 for (
int i = 0; i < n; ++i) {
141 if (seen[i] == ptr)
return i;
152 if (pin < 0)
return -1;
153 return portValueToId(digitalPinToPort(pin));
159 for (
u8 i = 0; i < 8; ++i) {
164 int port_counts[32] = {};
165 int port_ids[8] = {};
167 for (
u8 i = 0; i < 8; ++i) {
174 if (p >= 0 && p < 32) {
183 for (
int p = 0; p < 32; ++p) {
184 if (port_counts[p] > best_count) {
185 best_count = port_counts[p];
191 if (best_port >= 0 && best_count < num_active) {
192 for (
u8 i = 0; i < 8; ++i) {
196 if (port_ids[i] != best_port) {
197 FL_WARN(
"digitalMultiWrite8: pin " <<
mPins[i] <<
" (port " << port_ids[i] <<
") disabled — not on majority port " << best_port);
208 for (fl::size i = 0; i < pin_data.size(); ++i) {
209 const u8 byte = pin_data[i];
210 const u8 lo_nib =
byte & 0x0F;
211 const u8 hi_nib = (
byte >> 4) & 0x0F;
219 for (
u8 i = 0; i < 8; ++i) {
224 if (first_port < 0) {
226 }
else if (port != first_port) {
235 for (u16 nib = 0; nib < 16; ++nib) {
240 for (
u8 b = 0; b < 4; ++b) {
241 int pin =
mPins[bit_offset + b];
245 if (nib & (1 << b)) {
258 for (
u8 i = 0; i < clr.count; ++i) {
266 writer.
write(pin_data);
274 for (
u8 i = 0; i < 16; ++i) {
279 int port_counts[64] = {};
280 int port_ids[16] = {};
282 for (
u8 i = 0; i < 16; ++i) {
289 if (p >= 0 && p < 64) {
298 for (
int p = 0; p < 64; ++p) {
299 if (port_counts[p] > best_count) {
300 best_count = port_counts[p];
306 if (best_port >= 0 && best_count < num_active) {
307 for (
u8 i = 0; i < 16; ++i) {
311 if (port_ids[i] != best_port) {
312 FL_WARN(
"digitalMultiWrite16: pin " <<
mPins[i] <<
" (port " << port_ids[i] <<
") disabled — not on majority port " << best_port);
318 for (
u8 n = 0; n < 4; ++n) {
324 for (fl::size i = 0; i < pin_data.size(); ++i) {
325 const u16 word = pin_data[i];
326 for (
u8 n = 0; n < 4; ++n) {
327 const u8 nib = (word >> (n * 4)) & 0x0F;
335 for (
u8 i = 0; i < 16; ++i) {
340 if (first_port < 0) {
342 }
else if (port != first_port) {
352 for (u16 nib = 0; nib < 16; ++nib) {
357 for (
u8 b = 0; b < 4; ++b) {
358 int pin =
mPins[bit_offset + b];
362 if (nib & (1 << b)) {
375 for (
u8 i = 0; i < clr.count; ++i) {
383 writer.
write(pin_data);
391 for (fl::size i = 0; i <
pins.size(); ++i) {
392 if (
pins[i].pin >= 0) {
void init(const Pins16 &pins) FL_NO_EXCEPT
Initialize from 16 pin numbers. -1 means "skip this bit position".
static void applyNibble(const PinList &set, const PinList &clr) FL_NO_EXCEPT
void buildNibbleLut(u8 bit_offset, PinList(&set_lut)[16], PinList(&clr_lut)[16]) FL_NO_EXCEPT
void write(fl::span< const u16 > pin_data) const FL_NO_EXCEPT
Write pre-transposed 16-bit data to the 16 pins.
bool allSamePort() const FL_NO_EXCEPT
Check whether all active pins (non -1) share the same GPIO port.
Pre-computed nibble LUT for fast 16-pin digital writes.
void buildNibbleLut(u8 bit_offset, PinList(&set_lut)[16], PinList(&clr_lut)[16]) FL_NO_EXCEPT
void write(fl::span< const u8 > pin_data) const FL_NO_EXCEPT
Write pre-transposed byte data to the 8 pins.
bool allSamePort() const FL_NO_EXCEPT
Check whether all active pins (non -1) share the same GPIO port.
static void applyNibble(const PinList &set, const PinList &clr) FL_NO_EXCEPT
void init(const Pins8 &pins) FL_NO_EXCEPT
Initialize from 8 pin numbers. -1 means "skip this bit position".
Pre-computed nibble LUT for fast 8-pin digital writes.
size_type count(const Key &key) const
fl::FastPin< PIN > FastPin
Centralized logging categories for FastLED hardware interfaces and subsystems.
int portValueToId(unsigned char v) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
@ Low
Logic low (0V / GND)
@ High
Logic high (3.3V / 5V, platform-dependent)
void pinMap(fl::span< PinInfo > pins) FL_NO_EXCEPT
Resolve port IDs for an array of PinInfo in-place.
void digitalMultiWrite8(const Pins8 &pins, fl::span< const u8 > pin_data) FL_NO_EXCEPT
Convenience free function — creates a temporary DigitalMultiWrite8, initializes it,...
int pinToPort(int pin) FL_NO_EXCEPT
Map a runtime pin number to an integer port ID using FastPin<N>::port().
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NO_EXCEPT
void digitalMultiWrite16(const Pins16 &pins, fl::span< const u16 > pin_data) FL_NO_EXCEPT
Convenience free function — creates a temporary DigitalMultiWrite16, initializes it,...
void digitalWrite(int pin, PinValue val) FL_NO_EXCEPT
Write digital value to pin.
Base definition for an LED controller.
POD struct holding 16 pin numbers for bulk pin writes.
POD struct holding 8 pin numbers for bulk pin writes.