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
80 inline void setInputPullup() { pinMode(mPin, INPUT_PULLUP); }
81
83 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
85 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
86
88 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
91 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
92
95 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
98 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
102 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
103
107 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
108
110 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
112 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
114 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
116 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
117
119 virtual void select() override { hi(); }
121 virtual void release() override { lo(); }
123 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
124};
125
127class OutputPin : public Pin {
128public:
130 OutputPin(int pin) : Pin(pin) { setOutput(); }
131};
132
134class InputPin : public Pin {
135public:
137 InputPin(int pin) : Pin(pin) { setInput(); }
138};
139
140#else
141// 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
142// available on a new platform
143class Pin : public Selectable {
144 volatile RwReg *mPort;
145 volatile RoReg *mInPort;
146 RwReg mPinMask;
147 uint8_t mPin;
148
149
150
151 void _init() {
152 // TODO: fill in init on a new platform
153 mPinMask = 0;
154 mPort = NULL;
155 mInPort = NULL;
156 }
157
158public:
159 Pin(int pin) : mPin(pin) { _init(); }
160 #ifndef __AVR__
161 virtual ~Pin() {} // Shut up the compiler warning, but don't steal bytes from AVR.
162 #endif
163
164 void setPin(int pin) { mPin = pin; _init(); }
165
166 typedef volatile RwReg * port_ptr_t;
167 typedef RwReg port_t;
168
169 inline void setOutput() { /* TODO: Set pin output */ }
170 inline void setInput() { /* TODO: Set pin input */ }
171 inline void setInputPullup() { /* TODO: Set pin input pullup */ }
172
173 inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
174 inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
175
176 inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
177 inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
178
179 inline void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
180 inline void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
181 inline void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *mPort = val; }
182
183 inline void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
184
185 port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
186 port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
187 port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
188 port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
189
190 virtual void select() override { hi(); }
191 virtual void release() override { lo(); }
192 virtual bool isSelected() override { return (*mPort & mPinMask) == mPinMask; }
193};
194
195class OutputPin : public Pin {
196public:
197 OutputPin(int pin) : Pin(pin) { setOutput(); }
198};
199
200class InputPin : public Pin {
201public:
202 InputPin(int pin) : Pin(pin) { setInput(); }
203};
204
205#endif
206
221#ifdef FASTLED_FORCE_SOFTWARE_PINS
222template<uint8_t PIN> class FastPin {
223 static RwReg sPinMask;
224 static volatile RwReg *sPort;
225 static volatile RoReg *sInPort;
226 static void _init() {
227#if !defined(FASTLED_NO_PINMAP)
228 sPinMask = digitalPinToBitMask(PIN);
229 sPort = portOutputRegister(digitalPinToPort(PIN));
230 sInPort = portInputRegister(digitalPinToPort(PIN));
231#endif
232 }
233
234public:
235 typedef volatile RwReg * port_ptr_t;
236 typedef RwReg port_t;
237
239 inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); }
241 inline static void setInput() { _init(); pinMode(PIN, INPUT); }
242
244 inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; }
246 inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; }
247
249 inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
250
252 inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; }
253
255 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; }
257 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; }
259 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *sPort = val; }
260
262 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) { *port = val; }
263
265 static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; }
267 static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; }
269 static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; }
271 static port_t mask() __attribute__ ((always_inline)) { return sPinMask; }
272};
273
274template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask;
275template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort;
276template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort;
277
278#else
279
280template<uint8_t PIN> class FastPin {
281 // This is a default implementation. If you are hitting this then FastPin<> is either:
282 // 1) Not defined -or-
283 // 2) Not part of the set of defined FastPin<> specializations for your platform
284 // You need to define a FastPin<> specialization
285 // or change what get's included for your particular build target.
286 // Keep in mind that these messages are cryptic, so it's best to define an invalid in type.
287 constexpr static bool validpin() { return false; }
288 constexpr static bool LowSpeedOnlyRecommended() { // Some implementations assume this exists.
289 // Caller must always determine if high speed use if allowed on a given pin,
290 // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
291 return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
292 }
293
294 static_assert(validpin(), "Invalid pin specified");
295
296 static void _init() { }
297
298public:
299 typedef volatile RwReg * port_ptr_t;
300 typedef RwReg port_t;
301
303 inline static void setOutput() { }
305 inline static void setInput() { }
306
308 inline static void hi() __attribute__ ((always_inline)) { }
310 inline static void lo() __attribute__ ((always_inline)) { }
311
313 inline static void strobe() __attribute__ ((always_inline)) { }
314
316 inline static void toggle() __attribute__ ((always_inline)) { }
317
319 inline static void hi(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
321 }
323 inline static void lo(FASTLED_REGISTER port_ptr_t port) __attribute__ ((always_inline)) {
325 }
327 inline static void set(FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
328 FASTLED_UNUSED(val);
329 }
330
332 inline static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val) __attribute__ ((always_inline)) {
334 FASTLED_UNUSED(val);
335 }
336
338 static port_t hival() __attribute__ ((always_inline)) { return 0; }
340 static port_t loval() __attribute__ ((always_inline)) { return 0;}
342 static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
344 static port_t mask() __attribute__ ((always_inline)) { return 0; }
345};
346
347#endif
348
352template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {};
353
354typedef volatile uint32_t & reg32_t;
355typedef volatile uint32_t * ptr_reg32_t;
356
359template<uint8_t port> struct __FL_PORT_INFO {
361 static bool hasPort() { return 0; }
363 static const char *portName() { return "--"; }
365 static const void *portAddr() { return NULL; }
366};
367
368
375#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \
376 static bool hasPort() { return 1; } \
377 static const char *portName() { return #L; } \
378 typedef BASE __t_baseType; \
379 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
380
391#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \
392 static bool hasPort() { return 1; } \
393 static const char *portName() { return #L; } \
394 typedef BASE __t_baseType; \
395 static const void *portAddr() { return (void*)&__t_baseType::r(); } };
396
398
399#pragma GCC diagnostic pop
400
401#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:225
static port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:265
RwReg port_t
type for a pin read/write register, non-volatile
Definition fastpin.h:236
static void toggle()
Toggle the pin.
Definition fastpin.h:252
static void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:255
static port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:267
static void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:257
static void _init()
Definition fastpin.h:226
static void set(FASTLED_REGISTER port_t val)
Set the state of the output register.
Definition fastpin.h:259
static volatile RwReg * sPort
Definition fastpin.h:224
static port_t mask()
Get the pin mask.
Definition fastpin.h:271
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
Definition fastpin.h:235
static void lo()
Set the pin state to LOW
Definition fastpin.h:246
static port_ptr_t port()
Definition fastpin.h:269
static void setOutput()
Set the pin mode as OUTPUT
Definition fastpin.h:239
static void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:249
static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
Definition fastpin.h:262
static void hi()
Set the pin state to HIGH
Definition fastpin.h:244
static void setInput()
Set the pin mode as INPUT
Definition fastpin.h:241
static RwReg sPinMask
Definition fastpin.h:223
FastPin implementation for bit-banded access.
Definition fastpin.h:352
The simplest level of Pin class.
Definition fastpin.h:222
InputPin(int pin)
Constructor.
Definition fastpin.h:137
I/O pin initially set to INPUT.
Definition fastpin.h:134
OutputPin(int pin)
Constructor.
Definition fastpin.h:130
I/O pin initially set to OUTPUT.
Definition fastpin.h:127
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:107
void lo(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to LOW
Definition fastpin.h:98
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:102
port_t loval()
Gets the state of the port with this pin LOW
Definition fastpin.h:112
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:123
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:83
void toggle()
Toggle the pin.
Definition fastpin.h:91
void hi(FASTLED_REGISTER port_ptr_t port)
Set the same pin on another port to HIGH
Definition fastpin.h:95
virtual void release() override
Set the pin state to LOW
Definition fastpin.h:121
void lo()
Set the pin state to LOW
Definition fastpin.h:85
volatile RoReg * mInPort
Input register for the pin.
Definition fastpin.h:51
void setInputPullup()
Definition fastpin.h:80
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:116
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:114
void strobe()
Toggle the pin twice to create a short pulse.
Definition fastpin.h:88
Pin(int pin)
Constructor.
Definition fastpin.h:66
port_t hival()
Gets the state of the port with this pin HIGH
Definition fastpin.h:110
virtual void select() override
Set the pin state to HIGH
Definition fastpin.h:119
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:355
volatile uint32_t & reg32_t
Reference to a 32-bit register, volatile.
Definition fastpin.h:354
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:365
static bool hasPort()
Checks whether a port exists.
Definition fastpin.h:361
static const char * portName()
Gets the name of the port, as a C-string.
Definition fastpin.h:363
Utility template for tracking down information about pins and ports.
Definition fastpin.h:359
#define FASTLED_UNUSED(x)
Definition unused.h:3