FastLED 3.9.15
Loading...
Searching...
No Matches
fastpin.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef __INC_FASTPIN_H
4#define __INC_FASTPIN_H
5
6#include "FastLED.h"
8
9#include "led_sysdefs.h"
10#include "fl/unused.h"
11#include "fl/int.h"
12#include "fl/register.h"
13
14#pragma GCC diagnostic push
15#pragma GCC diagnostic ignored "-Wignored-qualifiers"
16#ifdef ESP32
17// Get rid of the endless volatile warnings in ESP32
18#pragma GCC diagnostic ignored "-Wpragmas"
19#pragma GCC diagnostic ignored "-Wvolatile"
20#endif
21
24
26
29#define NO_PIN 255
30
32//
33// Pin access class - needs to tune for various platforms (naive fallback solution?)
34//
36
39public:
40 #ifndef __AVR__
41 virtual ~Selectable() {}
42 #endif
43 virtual void select() = 0;
44 virtual void release() = 0;
45 virtual bool isSelected() = 0;
46};
47
48#if defined(FASTLED_STUB_IMPL) || defined(__EMSCRIPTEN__)
49
50
51class Pin : public Selectable {
52
53
54 void _init() {
55 }
56
57public:
58 Pin(int pin) { FL_UNUSED(pin); }
59
60
61 void setPin(int pin) { FL_UNUSED(pin); }
62
63 typedef volatile RwReg * port_ptr_t;
64 typedef RwReg port_t;
65
66 inline void setOutput() { /* NOOP */ }
67 inline void setInput() { /* NOOP */ }
68 inline void setInputPullup() { /* NOOP */ }
69
70
71 inline void hi() __attribute__ ((always_inline)) {}
73 inline void lo() __attribute__ ((always_inline)) {}
74
75
76 inline void strobe() __attribute__ ((always_inline)) { }
77 inline void toggle() __attribute__ ((always_inline)) { }
78
79 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { FL_UNUSED(port); }
80 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { FL_UNUSED(port); }
81 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { FL_UNUSED(val); }
82
83 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { FL_UNUSED(port); FL_UNUSED(val); }
84
85 port_t hival() __attribute__ ((always_inline)) { return 0; }
86 port_t loval() __attribute__ ((always_inline)) { return 0; }
87 port_ptr_t port() __attribute__ ((always_inline)) {
88 static volatile RwReg port = 0;
89 return &port;
90 }
91 port_t mask() __attribute__ ((always_inline)) { return 0xff; }
92
93 virtual void select() override { hi(); }
94 virtual void release() override { lo(); }
95 virtual bool isSelected() override { return true; }
96};
97
98class OutputPin : public Pin {
99public:
100 OutputPin(int pin) : Pin(pin) { setOutput(); }
101};
102
103class InputPin : public Pin {
104public:
105 InputPin(int pin) : Pin(pin) { setInput(); }
106};
107
108#elif !defined(FASTLED_NO_PINMAP)
109
111class Pin : public Selectable {
112 volatile RwReg *mPort;
113 volatile RoReg *mInPort;
114 RwReg mPinMask;
116
119 void _init() {
120 mPinMask = digitalPinToBitMask(mPin);
121 mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin));
122 mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin));
123 }
124
125public:
128 Pin(int pin) : mPin(pin) { _init(); }
129 #ifndef __AVR__
130 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
131 #endif
132
133 typedef volatile RwReg * port_ptr_t;
134 typedef RwReg port_t;
135
137 inline void setOutput() { pinMode(mPin, OUTPUT); }
138
140 inline void setInput() { pinMode(mPin, INPUT); }
141
142 inline void setInputPullup() { pinMode(mPin, INPUT_PULLUP); }
143
147 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
149 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
151
153 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
156 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
157
160 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
163 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
167 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
168
172 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
173
175 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
177 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
179 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
181 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
182
184 virtual void select() override { hi(); }
186 virtual void release() override { lo(); }
188 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
189};
190
192class OutputPin : public Pin {
193public:
195 OutputPin(int pin) : Pin(pin) { setOutput(); }
196};
197
199class InputPin : public Pin {
200public:
202 InputPin(int pin) : Pin(pin) { setInput(); }
203};
204
205#else
206// This is the empty code version of the raw pin class, method bodies should be filled in to Do The Right Thing[tm] when making this
207// available on a new platform
208
209class Pin : public Selectable {
210 volatile RwReg *mPort;
211 volatile RoReg *mInPort;
212 RwReg mPinMask;
213 fl::u8 mPin;
214
215 RwReg mPortFake = 0;
216 RoReg mInPortFake = 0;
217
218
219
220 void _init() {
221 // TODO: fill in init on a new platform
222 mPinMask = 0;
223 mPort = &mPortFake;
224 mInPort = &mInPortFake;
225 }
226
227public:
228 Pin(int pin) : mPin(pin) { _init(); }
229 #ifndef __AVR__
230 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
231 #endif
232
233 void setPin(int pin) { mPin = pin; _init(); }
234
235 typedef volatile RwReg * port_ptr_t;
236 typedef RwReg port_t;
237
238 inline void setOutput() { /* TODO: Set pin output */ }
239 inline void setInput() { /* TODO: Set pin input */ }
240 inline void setInputPullup() { /* TODO: Set pin input pullup */ }
241
245 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
247 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
249
250 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
251 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
252
253 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
254 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
255 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
256
257 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
258
259 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
260 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
261 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
262 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
263
264 virtual void select() override { hi(); }
265 virtual void release() override { lo(); }
266 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
267};
268
269class OutputPin : public Pin {
270public:
271 OutputPin(int pin) : Pin(pin) { setOutput(); }
272};
273
274class InputPin : public Pin {
275public:
276 InputPin(int pin) : Pin(pin) { setInput(); }
277};
278
279#endif
280
295#ifdef FASTLED_FORCE_SOFTWARE_PINS
296template<fl::u8 PIN> class FastPin {
297 static RwReg sPinMask;
298 static volatile RwReg *sPort;
299 static volatile RoReg *sInPort;
300 static void _init() {
301#if !defined(FASTLED_NO_PINMAP)
302 sPinMask = digitalPinToBitMask(PIN);
303 sPort = portOutputRegister(digitalPinToPort(PIN));
304 sInPort = portInputRegister(digitalPinToPort(PIN));
305#endif
306 }
307
308public:
309 typedef volatile RwReg * port_ptr_t;
310 typedef RwReg port_t;
311
313 inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); }
315 inline static void setInput() { _init(); pinMode(PIN, INPUT); }
316
318 inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; }
320 inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; }
321
323 inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
324
326 inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; }
327
329 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; }
331 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; }
333 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *sPort = val; }
334
336 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
337
339 static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; }
341 static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; }
343 static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; }
345 static port_t mask() __attribute__ ((always_inline)) { return sPinMask; }
346};
347
348template<fl::u8 PIN> RwReg FastPin<PIN>::sPinMask;
349template<fl::u8 PIN> volatile RwReg *FastPin<PIN>::sPort;
350template<fl::u8 PIN> volatile RoReg *FastPin<PIN>::sInPort;
351
352#else
353
354template<fl::u8 PIN> class FastPin {
355 // This is a default implementation. If you are hitting this then FastPin<> is either:
356 // 1) Not defined -or-
357 // 2) Not part of the set of defined FastPin<> specializations for your platform
358 // You need to define a FastPin<> specialization
359 // or change what get's included for your particular build target.
360 // Keep in mind that these messages are cryptic, so it's best to define an invalid in type.
361 constexpr static bool validpin() { return false; }
362 constexpr static bool LowSpeedOnlyRecommended() { // Some implementations assume this exists.
363 // Caller must always determine if high speed use if allowed on a given pin,
364 // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
365 return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
366 }
367
368 static_assert(validpin(), "This pin has been marked as an invalid pin, common reasons includes it being a ground pin, read only, or too noisy (e.g. hooked up to the uart).");
369
370 static void _init() { }
371
372public:
373 typedef volatile RwReg * port_ptr_t;
374 typedef RwReg port_t;
375
377 inline static void setOutput() { }
379 inline static void setInput() { }
380
382 inline static void hi() __attribute__ ((always_inline)) { }
384 inline static void lo() __attribute__ ((always_inline)) { }
385
387 inline static void strobe() __attribute__ ((always_inline)) { }
388
390 inline static void toggle() __attribute__ ((always_inline)) { }
391
393 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
395 }
397 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
399 }
401 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
402 FASTLED_UNUSED(val);
403 }
404
406 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
408 FASTLED_UNUSED(val);
409 }
410
412 static port_t hival() __attribute__ ((always_inline)) { return 0; }
414 static port_t loval() __attribute__ ((always_inline)) { return 0;}
416 static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
418 static port_t mask() __attribute__ ((always_inline)) { return 0; }
419};
420
421#endif
422
426template<fl::u8 PIN> class FastPinBB : public FastPin<PIN> {};
427
428typedef volatile fl::u32 & reg32_t;
429typedef volatile fl::u32 * ptr_reg32_t;
430
433template<fl::u8 port> struct __FL_PORT_INFO {
435 static bool hasPort() { return 0; }
437 static const char *portName() { return "--"; }
439 static const void *portAddr() { return NULL; }
440};
441
442
449#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \
450 static bool hasPort() { return 1; } \
451 static const char *portName() { return #L; } \
452 typedef BASE __t_baseType; \
453 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
454
465#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \
466 static bool hasPort() { return 1; } \
467 static const char *portName() { return #L; } \
468 typedef BASE __t_baseType; \
469 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
470
472
473#pragma GCC diagnostic pop
474
475#endif // __INC_FASTPIN_H
central include file for FastLED, defines the CFastLED class/object
#define PIN
Definition PinMode.ino:7
static volatile RoReg * sInPort
Definition fastpin.h:299
static port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:339
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:310
static void toggle()
Toggle the pin.
Definition fastpin.h:326
static void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:329
static port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:341
static void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:331
static void _init()
Definition fastpin.h:300
static void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:333
static volatile RwReg * sPort
Definition fastpin.h:298
static port_t mask()
Get the pin mask.
Definition fastpin.h:345
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:309
static void lo()
Set the pin state to LOW
Definition fastpin.h:320
static port_ptr_t port()
Definition fastpin.h:343
static void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:313
static void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:323
static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:336
static void hi()
Set the pin state to HIGH
Definition fastpin.h:318
static void setInput()
Set the pin mode as INPUT
Definition fastpin.h:315
static RwReg sPinMask
Definition fastpin.h:297
FastPin implementation for bit-banded access.
Definition fastpin.h:426
The simplest level of Pin class.
Definition fastpin.h:296
InputPin(int pin)
Constructor.
Definition fastpin.h:202
I/O pin initially set to INPUT.
Definition fastpin.h:199
OutputPin(int pin)
Constructor.
Definition fastpin.h:195
I/O pin initially set to OUTPUT.
Definition fastpin.h:192
volatile RwReg * mPort
Output register for the pin.
Definition fastpin.h:112
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_NULL_DEREFERENCE void hi()
Set the pin state to HIGH
Definition fastpin.h:147
void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:172
void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:163
void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:137
void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:167
port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:177
void setInput()
Set the pin mode as INPUT
Definition fastpin.h:140
virtual bool isSelected() override
Checks if the pin is currently HIGH
Definition fastpin.h:188
void _init()
Initialize the class by retrieving the register pointers and bitmask.
Definition fastpin.h:119
void toggle()
Toggle the pin.
Definition fastpin.h:156
void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:160
virtual void release() override
Set the pin state to LOW
Definition fastpin.h:186
void lo()
Set the pin state to LOW
Definition fastpin.h:149
FL_DISABLE_WARNING_POP void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:153
volatile RoReg * mInPort
Input register for the pin.
Definition fastpin.h:113
void setInputPullup()
Definition fastpin.h:142
RwReg mPinMask
Bitmask for the pin within its register.
Definition fastpin.h:114
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:133
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:134
port_t mask()
Get the pin mask.
Definition fastpin.h:181
virtual ~Pin()
Definition fastpin.h:130
port_ptr_t port()
Get the output state of the port.
Definition fastpin.h:179
Pin(int pin)
Constructor.
Definition fastpin.h:128
port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:175
virtual void select() override
Set the pin state to HIGH
Definition fastpin.h:184
fl::u8 mPin
Arduino digital pin number.
Definition fastpin.h:115
Naive fallback solution for low level pin access.
Definition fastpin.h:111
virtual ~Selectable()
Definition fastpin.h:41
virtual void release()=0
Release this object.
virtual void select()=0
Select this object.
virtual bool isSelected()=0
Check if this object is currently selected.
Abstract class for "selectable" things.
Definition fastpin.h:38
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_NULL_DEREFERENCE
#define FL_DISABLE_WARNING_POP
volatile fl::u32 & reg32_t
Reference to a 32-bit register, volatile.
Definition fastpin.h:428
volatile fl::u32 * ptr_reg32_t
Pointer to a 32-bit register, volatile.
Definition fastpin.h:429
Determines which platform system definitions to include.
#define FASTLED_NAMESPACE_END
Definition namespace.h:23
#define FASTLED_NAMESPACE_BEGIN
Definition namespace.h:22
unsigned char u8
Definition int.h:17
#define FASTLED_REGISTER
Helper macro to replace the deprecated 'register' keyword if we're using modern C++ where it's been r...
Definition register.h:9
static const void * portAddr()
Gets the raw address of the port.
Definition fastpin.h:439
static bool hasPort()
Checks whether a port exists.
Definition fastpin.h:435
static const char * portName()
Gets the name of the port, as a C-string.
Definition fastpin.h:437
Utility template for tracking down information about pins and ports.
Definition fastpin.h:433
#define FL_UNUSED(x)
Definition unused.h:8
#define FASTLED_UNUSED(x)
Definition unused.h:4