24#ifdef FASTLED_ALL_PINS_VALID
26namespace pin_port_table {
28constexpr int TABLE_SIZE = 64;
30using port_ptr_t =
typename FastPin<0>::port_ptr_t;
32template <
int N>
struct PortEntry {
36inline const port_ptr_t* portTable() {
37 static port_ptr_t table[TABLE_SIZE] = {
38 PortEntry<0>::get(), PortEntry<1>::get(), PortEntry<2>::get(), PortEntry<3>::get(),
39 PortEntry<4>::get(), PortEntry<5>::get(), PortEntry<6>::get(), PortEntry<7>::get(),
40 PortEntry<8>::get(), PortEntry<9>::get(), PortEntry<10>::get(), PortEntry<11>::get(),
41 PortEntry<12>::get(), PortEntry<13>::get(), PortEntry<14>::get(), PortEntry<15>::get(),
42 PortEntry<16>::get(), PortEntry<17>::get(), PortEntry<18>::get(), PortEntry<19>::get(),
43 PortEntry<20>::get(), PortEntry<21>::get(), PortEntry<22>::get(), PortEntry<23>::get(),
44 PortEntry<24>::get(), PortEntry<25>::get(), PortEntry<26>::get(), PortEntry<27>::get(),
45 PortEntry<28>::get(), PortEntry<29>::get(), PortEntry<30>::get(), PortEntry<31>::get(),
46 PortEntry<32>::get(), PortEntry<33>::get(), PortEntry<34>::get(), PortEntry<35>::get(),
47 PortEntry<36>::get(), PortEntry<37>::get(), PortEntry<38>::get(), PortEntry<39>::get(),
48 PortEntry<40>::get(), PortEntry<41>::get(), PortEntry<42>::get(), PortEntry<43>::get(),
49 PortEntry<44>::get(), PortEntry<45>::get(), PortEntry<46>::get(), PortEntry<47>::get(),
50 PortEntry<48>::get(), PortEntry<49>::get(), PortEntry<50>::get(), PortEntry<51>::get(),
51 PortEntry<52>::get(), PortEntry<53>::get(), PortEntry<54>::get(), PortEntry<55>::get(),
52 PortEntry<56>::get(), PortEntry<57>::get(), PortEntry<58>::get(), PortEntry<59>::get(),
53 PortEntry<60>::get(), PortEntry<61>::get(), PortEntry<62>::get(), PortEntry<63>::get(),
58inline port_ptr_t getPortPtr(
int pin) {
59 if (pin < 0 || pin >= TABLE_SIZE)
return nullptr;
60 return portTable()[pin];
63inline bool allPortsNull() {
64 const port_ptr_t* table = portTable();
65 for (
int i = 0; i < TABLE_SIZE; ++i) {
66 if (table[i] !=
nullptr)
return false;
74 if (pin < 0)
return -1;
76 if (!pin_port_table::allPortsNull()) {
77 auto ptr = pin_port_table::getPortPtr(pin);
78 if (ptr ==
nullptr)
return -1;
81 const auto* table = pin_port_table::portTable();
82 for (
int i = 0; i < pin_port_table::TABLE_SIZE; ++i) {
83 if (table[i] == ptr) {
85 for (
int j = 0; j < i; ++j) {
87 for (
int k = 0; k < j; ++k) {
88 if (table[k] == table[j]) { unique =
false;
break; }
90 if (unique && table[j] !=
nullptr) ++id;
102#elif defined(FASTLED_NO_PINMAP)
108 if (pin < 0)
return -1;
129 return static_cast<int>(v);
137 static T* seen[8] = {};
139 for (
int i = 0; i < n; ++i) {
140 if (seen[i] == ptr)
return i;
151 if (pin < 0)
return -1;
152 return portValueToId(digitalPinToPort(pin));
158 for (
u8 i = 0; i < 8; ++i) {
163 int port_counts[32] = {};
164 int port_ids[8] = {};
166 for (
u8 i = 0; i < 8; ++i) {
173 if (p >= 0 && p < 32) {
182 for (
int p = 0; p < 32; ++p) {
183 if (port_counts[p] > best_count) {
184 best_count = port_counts[p];
190 if (best_port >= 0 && best_count < num_active) {
191 for (
u8 i = 0; i < 8; ++i) {
195 if (port_ids[i] != best_port) {
196 FL_WARN(
"digitalMultiWrite8: pin "
197 <<
mPins[i] <<
" (port " << port_ids[i]
198 <<
") disabled — not on majority port "
210 for (fl::size i = 0; i < pin_data.
size(); ++i) {
211 const u8 byte = pin_data[i];
212 const u8 lo_nib =
byte & 0x0F;
213 const u8 hi_nib = (
byte >> 4) & 0x0F;
221 for (
u8 i = 0; i < 8; ++i) {
226 if (first_port < 0) {
228 }
else if (port != first_port) {
237 for (u16 nib = 0; nib < 16; ++nib) {
242 for (
u8 b = 0; b < 4; ++b) {
243 int pin =
mPins[bit_offset + b];
247 if (nib & (1 << b)) {
260 for (
u8 i = 0; i < clr.
count; ++i) {
268 writer.
write(pin_data);
276 for (
u8 i = 0; i < 16; ++i) {
281 int port_counts[64] = {};
282 int port_ids[16] = {};
284 for (
u8 i = 0; i < 16; ++i) {
291 if (p >= 0 && p < 64) {
300 for (
int p = 0; p < 64; ++p) {
301 if (port_counts[p] > best_count) {
302 best_count = port_counts[p];
308 if (best_port >= 0 && best_count < num_active) {
309 for (
u8 i = 0; i < 16; ++i) {
313 if (port_ids[i] != best_port) {
314 FL_WARN(
"digitalMultiWrite16: pin "
315 <<
mPins[i] <<
" (port " << port_ids[i]
316 <<
") disabled — not on majority port "
323 for (
u8 n = 0; n < 4; ++n) {
329 for (fl::size i = 0; i < pin_data.
size(); ++i) {
330 const u16 word = pin_data[i];
331 for (
u8 n = 0; n < 4; ++n) {
332 const u8 nib = (word >> (n * 4)) & 0x0F;
340 for (
u8 i = 0; i < 16; ++i) {
345 if (first_port < 0) {
347 }
else if (port != first_port) {
357 for (u16 nib = 0; nib < 16; ++nib) {
362 for (
u8 b = 0; b < 4; ++b) {
363 int pin =
mPins[bit_offset + b];
367 if (nib & (1 << b)) {
380 for (
u8 i = 0; i < clr.
count; ++i) {
388 writer.
write(pin_data);
396 for (fl::size i = 0; i <
pins.size(); ++i) {
397 if (
pins[i].pin >= 0) {
bool allSamePort() const
Check whether all active pins (non -1) share the same GPIO port.
void write(fl::span< const u16 > pin_data) const
Write pre-transposed 16-bit data to the 16 pins.
void init(const Pins16 &pins)
Initialize from 16 pin numbers. -1 means "skip this bit position".
void buildNibbleLut(u8 bit_offset, PinList(&set_lut)[16], PinList(&clr_lut)[16])
static void applyNibble(const PinList &set, const PinList &clr)
Pre-computed nibble LUT for fast 16-pin digital writes.
void init(const Pins8 &pins)
Initialize from 8 pin numbers. -1 means "skip this bit position".
void buildNibbleLut(u8 bit_offset, PinList(&set_lut)[16], PinList(&clr_lut)[16])
static void applyNibble(const PinList &set, const PinList &clr)
bool allSamePort() const
Check whether all active pins (non -1) share the same GPIO port.
void write(fl::span< const u8 > pin_data) const
Write pre-transposed byte data to the 8 pins.
Pre-computed nibble LUT for fast 8-pin digital writes.
size_type count(const Key &key) const
constexpr fl::size size() const FL_NOEXCEPT
fl::FastPin< PIN > FastPin
Centralized logging categories for FastLED hardware interfaces and subsystems.
int portValueToId(unsigned char v)
void digitalMultiWrite8(const Pins8 &pins, fl::span< const u8 > pin_data)
Convenience free function — creates a temporary DigitalMultiWrite8, initializes it,...
int pinToPort(int pin)
Map a runtime pin number to an integer port ID using FastPin<N>::port().
@ Low
Logic low (0V / GND)
@ High
Logic high (3.3V / 5V, platform-dependent)
void digitalMultiWrite16(const Pins16 &pins, fl::span< const u16 > pin_data)
Convenience free function — creates a temporary DigitalMultiWrite16, initializes it,...
void digitalWrite(int pin, PinValue val)
Write digital value to pin.
void pinMap(fl::span< PinInfo > pins)
Resolve port IDs for an array of PinInfo in-place.
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NOEXCEPT
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.