FastLED 3.9.7
Loading...
Searching...
No Matches
fastpin.h
Go to the documentation of this file.
1#ifndef __INC_FASTPIN_H
2#define __INC_FASTPIN_H
3
4#include "FastLED.h"
5
6#include "led_sysdefs.h"
7#include <stddef.h>
8#include "fl/unused.h"
9
10#pragma GCC diagnostic push
11#pragma GCC diagnostic ignored "-Wignored-qualifiers"
12#ifdef ESP32
13// Get rid of the endless volatile warnings in ESP32
14#pragma GCC diagnostic ignored "-Wpragmas"
15#pragma GCC diagnostic ignored "-Wvolatile"
16#endif
17
20
22
25#define NO_PIN 255
26
28//
29// Pin access class - needs to tune for various platforms (naive fallback solution?)
30//
32
35public:
36 #ifndef __AVR__
37 virtual ~Selectable() {}
38 #endif
39 virtual void select() = 0;
40 virtual void release() = 0;
41 virtual bool isSelected() = 0;
42};
43
44#if !defined(FASTLED_NO_PINMAP)
45
47class Pin : public Selectable {
48 volatile RwReg *mPort;
49 volatile RoReg *mInPort;
50 RwReg mPinMask;
51 uint8_t mPin;
52
55 void _init() {
56 mPinMask = digitalPinToBitMask(mPin);
57 mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin));
58 mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin));
59 }
60
61public:
64 Pin(int pin) : mPin(pin) { _init(); }
65 #ifndef __AVR__
66 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
67 #endif
68
69 typedef volatile RwReg * port_ptr_t;
70 typedef RwReg port_t;
71
73 inline void setOutput() { pinMode(mPin, OUTPUT); }
74
76 inline void setInput() { pinMode(mPin, INPUT); }
77
79 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
81 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
82
84 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
87 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
88
91 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
94 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
98 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
99
103 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
104
106 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
108 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
110 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
112 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
113
115 virtual void select() { hi(); }
117 virtual void release() { lo(); }
119 virtual bool isSelected() { return (*mPort & mPinMask) == mPinMask; }
120};
121
123class OutputPin : public Pin {
124public:
126 OutputPin(int pin) : Pin(pin) { setOutput(); }
127};
128
130class InputPin : public Pin {
131public:
133 InputPin(int pin) : Pin(pin) { setInput(); }
134};
135
136#else
137// 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
138// available on a new platform
139class Pin : public Selectable {
140 volatile RwReg *mPort;
141 volatile RoReg *mInPort;
142 RwReg mPinMask;
143 uint8_t mPin;
144
145
146
147 void _init() {
148 // TODO: fill in init on a new platform
149 mPinMask = 0;
150 mPort = NULL;
151 mInPort = NULL;
152 }
153
154public:
155 Pin(int pin) : mPin(pin) { _init(); }
156 #ifndef __AVR__
157 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
158 #endif
159
160 void setPin(int pin) { mPin = pin; _init(); }
161
162 typedef volatile RwReg * port_ptr_t;
163 typedef RwReg port_t;
164
165 inline void setOutput() { /* TODO: Set pin output */ }
166 inline void setInput() { /* TODO: Set pin input */ }
167
168 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
169 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
170
171 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
172 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
173
174 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
175 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
176 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
177
178 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
179
180 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
181 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
182 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
183 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
184
185 virtual void select() override { hi(); }
186 virtual void release() override { lo(); }
187 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
188};
189
190class OutputPin : public Pin {
191public:
192 OutputPin(int pin) : Pin(pin) { setOutput(); }
193};
194
195class InputPin : public Pin {
196public:
197 InputPin(int pin) : Pin(pin) { setInput(); }
198};
199
200#endif
201
216#ifdef FASTLED_FORCE_SOFTWARE_PINS
217template<uint8_t PIN> class FastPin {
218 static RwReg sPinMask;
219 static volatile RwReg *sPort;
220 static volatile RoReg *sInPort;
221 static void _init() {
222#if !defined(FASTLED_NO_PINMAP)
223 sPinMask = digitalPinToBitMask(PIN);
224 sPort = portOutputRegister(digitalPinToPort(PIN));
225 sInPort = portInputRegister(digitalPinToPort(PIN));
226#endif
227 }
228
229public:
230 typedef volatile RwReg * port_ptr_t;
231 typedef RwReg port_t;
232
234 inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); }
236 inline static void setInput() { _init(); pinMode(PIN, INPUT); }
237
239 inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; }
241 inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; }
242
244 inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
245
247 inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; }
248
250 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; }
252 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; }
254 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *sPort = val; }
255
257 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
258
260 static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; }
262 static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; }
264 static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; }
266 static port_t mask() __attribute__ ((always_inline)) { return sPinMask; }
267};
268
269template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask;
270template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort;
271template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort;
272
273#else
274
275template<uint8_t PIN> class FastPin {
276 // This is a default implementation. If you are hitting this then FastPin<> has
277 // not be defined for your platform. You need to define a FastPin<> specialization
278 // or change what get's included for your particular build target.
279 constexpr static bool validpin() { return false; }
280 constexpr static bool LowSpeedOnlyRecommended() { // Some implementations assume this exists.
281 // Caller must always determine if high speed use if allowed on a given pin,
282 // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
283 return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
284 }
285
286 static_assert(validpin(), "Invalid pin specified");
287
288 static void _init() { }
289
290public:
291 typedef volatile RwReg * port_ptr_t;
292 typedef RwReg port_t;
293
295 inline static void setOutput() { }
297 inline static void setInput() { }
298
300 inline static void hi() __attribute__ ((always_inline)) { }
302 inline static void lo() __attribute__ ((always_inline)) { }
303
305 inline static void strobe() __attribute__ ((always_inline)) { }
306
308 inline static void toggle() __attribute__ ((always_inline)) { }
309
311 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
312 FASTLED_UNUSED(port);
313 }
315 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
316 FASTLED_UNUSED(port);
317 }
319 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
320 FASTLED_UNUSED(val);
321 }
322
324 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
325 FASTLED_UNUSED(port);
326 FASTLED_UNUSED(val);
327 }
328
330 static port_t hival() __attribute__ ((always_inline)) { return 0; }
332 static port_t loval() __attribute__ ((always_inline)) { return 0;}
334 static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
336 static port_t mask() __attribute__ ((always_inline)) { return 0; }
337};
338
339#endif
340
344template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {};
345
346typedef volatile uint32_t & reg32_t;
347typedef volatile uint32_t * ptr_reg32_t;
348
351template<uint8_t port> struct __FL_PORT_INFO {
353 static bool hasPort() { return 0; }
355 static const char *portName() { return "--"; }
357 static const void *portAddr() { return NULL; }
358};
359
360
367#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \
368 static bool hasPort() { return 1; } \
369 static const char *portName() { return #L; } \
370 typedef BASE __t_baseType; \
371 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
372
383#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \
384 static bool hasPort() { return 1; } \
385 static const char *portName() { return #L; } \
386 typedef BASE __t_baseType; \
387 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
388
390
391#pragma GCC diagnostic pop
392
393#endif // __INC_FASTPIN_H
central include file for FastLED, defines the CFastLED class/object
FastPin implementation for bit-banded access.
Definition fastpin.h:344
The simplest level of Pin class.
Definition fastpin.h:217
static port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:260
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:231
static void toggle()
Toggle the pin.
Definition fastpin.h:247
static void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:250
static port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:262
static void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:252
static void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:254
static port_t mask()
Get the pin mask.
Definition fastpin.h:266
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:230
static void lo()
Set the pin state to LOW
Definition fastpin.h:241
static port_ptr_t port()
Get the output state of the port.
Definition fastpin.h:264
static void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:234
static void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:244
static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:257
static void hi()
Set the pin state to HIGH
Definition fastpin.h:239
static void setInput()
Set the pin mode as INPUT
Definition fastpin.h:236
I/O pin initially set to INPUT.
Definition fastpin.h:130
InputPin(int pin)
Constructor.
Definition fastpin.h:133
I/O pin initially set to OUTPUT.
Definition fastpin.h:123
OutputPin(int pin)
Constructor.
Definition fastpin.h:126
Naive fallback solution for low level pin access.
Definition fastpin.h:47
void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:103
void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:94
virtual void release()
Set the pin state to LOW
Definition fastpin.h:117
void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:73
void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:98
port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:108
void setInput()
Set the pin mode as INPUT
Definition fastpin.h:76
void hi()
Set the pin state to HIGH
Definition fastpin.h:79
void toggle()
Toggle the pin.
Definition fastpin.h:87
void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:91
void lo()
Set the pin state to LOW
Definition fastpin.h:81
virtual void select()
Set the pin state to HIGH
Definition fastpin.h:115
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:69
virtual bool isSelected()
Checks if the pin is currently HIGH
Definition fastpin.h:119
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:70
port_t mask()
Get the pin mask.
Definition fastpin.h:112
port_ptr_t port()
Get the output state of the port.
Definition fastpin.h:110
void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:84
Pin(int pin)
Constructor.
Definition fastpin.h:64
port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:106
Abstract class for "selectable" things.
Definition fastpin.h:34
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.
volatile uint32_t * ptr_reg32_t
Pointer to a 32-bit register, volatile.
Definition fastpin.h:347
volatile uint32_t & reg32_t
Reference to a 32-bit register, volatile.
Definition fastpin.h:346
Determines which platform system definitions to include.
#define FASTLED_NAMESPACE_END
End of the FastLED namespace.
Definition namespace.h:16
#define FASTLED_NAMESPACE_BEGIN
Start of the FastLED namespace.
Definition namespace.h:14
Utility template for tracking down information about pins and ports.
Definition fastpin.h:351
static const void * portAddr()
Gets the raw address of the port.
Definition fastpin.h:357
static bool hasPort()
Checks whether a port exists.
Definition fastpin.h:353
static const char * portName()
Gets the name of the port, as a C-string.
Definition fastpin.h:355