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"
7
8#include "led_sysdefs.h"
9#include <stddef.h>
10#include "fl/unused.h"
11
12#pragma GCC diagnostic push
13#pragma GCC diagnostic ignored "-Wignored-qualifiers"
14#ifdef ESP32
15// Get rid of the endless volatile warnings in ESP32
16#pragma GCC diagnostic ignored "-Wpragmas"
17#pragma GCC diagnostic ignored "-Wvolatile"
18#endif
19
22
24
27#define NO_PIN 255
28
30//
31// Pin access class - needs to tune for various platforms (naive fallback solution?)
32//
34
37public:
38 #ifndef __AVR__
39 virtual ~Selectable() {}
40 #endif
41 virtual void select() = 0;
42 virtual void release() = 0;
43 virtual bool isSelected() = 0;
44};
45
46#if !defined(FASTLED_NO_PINMAP)
47
49class Pin : public Selectable {
50 volatile RwReg *mPort;
51 volatile RoReg *mInPort;
52 RwReg mPinMask;
53 uint8_t mPin;
54
57 void _init() {
58 mPinMask = digitalPinToBitMask(mPin);
59 mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin));
60 mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin));
61 }
62
63public:
66 Pin(int pin) : mPin(pin) { _init(); }
67 #ifndef __AVR__
68 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
69 #endif
70
71 typedef volatile RwReg * port_ptr_t;
72 typedef RwReg port_t;
73
75 inline void setOutput() { pinMode(mPin, OUTPUT); }
76
78 inline void setInput() { pinMode(mPin, INPUT); }
79
81 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
83 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
84
86 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
89 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
90
93 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
96 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
100 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
101
105 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
106
108 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
110 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
112 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
114 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
115
117 virtual void select() override { hi(); }
119 virtual void release() override { lo(); }
121 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
122};
123
125class OutputPin : public Pin {
126public:
128 OutputPin(int pin) : Pin(pin) { setOutput(); }
129};
130
132class InputPin : public Pin {
133public:
135 InputPin(int pin) : Pin(pin) { setInput(); }
136};
137
138#else
139// 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
140// available on a new platform
141class Pin : public Selectable {
142 volatile RwReg *mPort;
143 volatile RoReg *mInPort;
144 RwReg mPinMask;
145 uint8_t mPin;
146
147
148
149 void _init() {
150 // TODO: fill in init on a new platform
151 mPinMask = 0;
152 mPort = NULL;
153 mInPort = NULL;
154 }
155
156public:
157 Pin(int pin) : mPin(pin) { _init(); }
158 #ifndef __AVR__
159 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
160 #endif
161
162 void setPin(int pin) { mPin = pin; _init(); }
163
164 typedef volatile RwReg * port_ptr_t;
165 typedef RwReg port_t;
166
167 inline void setOutput() { /* TODO: Set pin output */ }
168 inline void setInput() { /* TODO: Set pin input */ }
169
170 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
171 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
172
173 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
174 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
175
176 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
177 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
178 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
179
180 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
181
182 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
183 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
184 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
185 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
186
187 virtual void select() override { hi(); }
188 virtual void release() override { lo(); }
189 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
190};
191
192class OutputPin : public Pin {
193public:
194 OutputPin(int pin) : Pin(pin) { setOutput(); }
195};
196
197class InputPin : public Pin {
198public:
199 InputPin(int pin) : Pin(pin) { setInput(); }
200};
201
202#endif
203
218#ifdef FASTLED_FORCE_SOFTWARE_PINS
219template<uint8_t PIN> class FastPin {
220 static RwReg sPinMask;
221 static volatile RwReg *sPort;
222 static volatile RoReg *sInPort;
223 static void _init() {
224#if !defined(FASTLED_NO_PINMAP)
225 sPinMask = digitalPinToBitMask(PIN);
226 sPort = portOutputRegister(digitalPinToPort(PIN));
227 sInPort = portInputRegister(digitalPinToPort(PIN));
228#endif
229 }
230
231public:
232 typedef volatile RwReg * port_ptr_t;
233 typedef RwReg port_t;
234
236 inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); }
238 inline static void setInput() { _init(); pinMode(PIN, INPUT); }
239
241 inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; }
243 inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; }
244
246 inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
247
249 inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; }
250
252 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; }
254 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; }
256 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *sPort = val; }
257
259 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
260
262 static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; }
264 static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; }
266 static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; }
268 static port_t mask() __attribute__ ((always_inline)) { return sPinMask; }
269};
270
271template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask;
272template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort;
273template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort;
274
275#else
276
277template<uint8_t PIN> class FastPin {
278 // This is a default implementation. If you are hitting this then FastPin<> is either:
279 // 1) Not defined -or-
280 // 2) Not part of the set of defined FastPin<> specializations for your platform
281 // You need to define a FastPin<> specialization
282 // or change what get's included for your particular build target.
283 // Keep in mind that these messages are cryptic, so it's best to define an invalid in type.
284 constexpr static bool validpin() { return false; }
285 constexpr static bool LowSpeedOnlyRecommended() { // Some implementations assume this exists.
286 // Caller must always determine if high speed use if allowed on a given pin,
287 // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
288 return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
289 }
290
291 static_assert(validpin(), "Invalid pin specified");
292
293 static void _init() { }
294
295public:
296 typedef volatile RwReg * port_ptr_t;
297 typedef RwReg port_t;
298
300 inline static void setOutput() { }
302 inline static void setInput() { }
303
305 inline static void hi() __attribute__ ((always_inline)) { }
307 inline static void lo() __attribute__ ((always_inline)) { }
308
310 inline static void strobe() __attribute__ ((always_inline)) { }
311
313 inline static void toggle() __attribute__ ((always_inline)) { }
314
316 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
318 }
320 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
322 }
324 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
325 FASTLED_UNUSED(val);
326 }
327
329 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
331 FASTLED_UNUSED(val);
332 }
333
335 static port_t hival() __attribute__ ((always_inline)) { return 0; }
337 static port_t loval() __attribute__ ((always_inline)) { return 0;}
339 static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
341 static port_t mask() __attribute__ ((always_inline)) { return 0; }
342};
343
344#endif
345
349template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {};
350
351typedef volatile uint32_t & reg32_t;
352typedef volatile uint32_t * ptr_reg32_t;
353
356template<uint8_t port> struct __FL_PORT_INFO {
358 static bool hasPort() { return 0; }
360 static const char *portName() { return "--"; }
362 static const void *portAddr() { return NULL; }
363};
364
365
372#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \
373 static bool hasPort() { return 1; } \
374 static const char *portName() { return #L; } \
375 typedef BASE __t_baseType; \
376 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
377
388#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \
389 static bool hasPort() { return 1; } \
390 static const char *portName() { return #L; } \
391 typedef BASE __t_baseType; \
392 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
393
395
396#pragma GCC diagnostic pop
397
398#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:222
static port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:262
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:233
static void toggle()
Toggle the pin.
Definition fastpin.h:249
static void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:252
static port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:264
static void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:254
static void _init()
Definition fastpin.h:223
static void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:256
static volatile RwReg * sPort
Definition fastpin.h:221
static port_t mask()
Get the pin mask.
Definition fastpin.h:268
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:232
static void lo()
Set the pin state to LOW
Definition fastpin.h:243
static port_ptr_t port()
Definition fastpin.h:266
static void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:236
static void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:246
static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:259
static void hi()
Set the pin state to HIGH
Definition fastpin.h:241
static void setInput()
Set the pin mode as INPUT
Definition fastpin.h:238
static RwReg sPinMask
Definition fastpin.h:220
FastPin implementation for bit-banded access.
Definition fastpin.h:349
The simplest level of Pin class.
Definition fastpin.h:219
InputPin(int pin)
Constructor.
Definition fastpin.h:135
I/O pin initially set to INPUT.
Definition fastpin.h:132
OutputPin(int pin)
Constructor.
Definition fastpin.h:128
I/O pin initially set to OUTPUT.
Definition fastpin.h:125
volatile RwReg * mPort
Output register for the pin.
Definition fastpin.h:50
void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:105
void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:96
void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:75
void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:100
port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:110
void setInput()
Set the pin mode as INPUT
Definition fastpin.h:78
virtual bool isSelected() override
Checks if the pin is currently HIGH
Definition fastpin.h:121
void _init()
Initialize the class by retrieving the register pointers and bitmask.
Definition fastpin.h:57
void hi()
Set the pin state to HIGH
Definition fastpin.h:81
void toggle()
Toggle the pin.
Definition fastpin.h:89
void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:93
virtual void release() override
Set the pin state to LOW
Definition fastpin.h:119
void lo()
Set the pin state to LOW
Definition fastpin.h:83
volatile RoReg * mInPort
Input register for the pin.
Definition fastpin.h:51
RwReg mPinMask
Bitmask for the pin within its register.
Definition fastpin.h:52
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:71
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:72
port_t mask()
Get the pin mask.
Definition fastpin.h:114
uint8_t mPin
Arduino digital pin number.
Definition fastpin.h:53
virtual ~Pin()
Definition fastpin.h:68
port_ptr_t port()
Get the output state of the port.
Definition fastpin.h:112
void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:86
Pin(int pin)
Constructor.
Definition fastpin.h:66
port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:108
virtual void select() override
Set the pin state to HIGH
Definition fastpin.h:117
Naive fallback solution for low level pin access.
Definition fastpin.h:49
virtual ~Selectable()
Definition fastpin.h:39
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:36
volatile uint32_t * ptr_reg32_t
Pointer to a 32-bit register, volatile.
Definition fastpin.h:352
volatile uint32_t & reg32_t
Reference to a 32-bit register, volatile.
Definition fastpin.h:351
Determines which platform system definitions to include.
#define FASTLED_NAMESPACE_END
Definition namespace.h:23
#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:8
static const void * portAddr()
Gets the raw address of the port.
Definition fastpin.h:362
static bool hasPort()
Checks whether a port exists.
Definition fastpin.h:358
static const char * portName()
Gets the name of the port, as a C-string.
Definition fastpin.h:360
Utility template for tracking down information about pins and ports.
Definition fastpin.h:356
#define FASTLED_UNUSED(x)
Definition unused.h:3