FastLED  3.1
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 
8 #pragma GCC diagnostic push
9 #pragma GCC diagnostic ignored "-Wignored-qualifiers"
10 
13 
14 FASTLED_NAMESPACE_BEGIN
15 
16 #define NO_PIN 255
17 
19 //
20 // Pin access class - needs to tune for various platforms (naive fallback solution?)
21 //
23 
24 class Selectable {
25 public:
26  virtual void select() = 0;
27  virtual void release() = 0;
28  virtual bool isSelected() = 0;
29 };
30 
31 #if !defined(FASTLED_NO_PINMAP)
32 
33 class Pin : public Selectable {
34  volatile RwReg *mPort;
35  volatile RoReg *mInPort;
36  RwReg mPinMask;
37  uint8_t mPin;
38 
39  void _init() {
40  mPinMask = digitalPinToBitMask(mPin);
41  mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin));
42  mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin));
43  }
44 public:
45  Pin(int pin) : mPin(pin) { _init(); }
46 
47  typedef volatile RwReg * port_ptr_t;
48  typedef RwReg port_t;
49 
50  inline void setOutput() { pinMode(mPin, OUTPUT); }
51  inline void setInput() { pinMode(mPin, INPUT); }
52 
53  inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
54  inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
55 
56  inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
57  inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
58 
59  inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
60  inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
61  inline void set(register port_t val) __attribute__ ((always_inline)) { *mPort = val; }
62 
63  inline void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
64 
65  port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
66  port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
67  port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
68  port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
69 
70  virtual void select() { hi(); }
71  virtual void release() { lo(); }
72  virtual bool isSelected() { return (*mPort & mPinMask) == mPinMask; }
73 };
74 
75 class OutputPin : public Pin {
76 public:
77  OutputPin(int pin) : Pin(pin) { setOutput(); }
78 };
79 
80 class InputPin : public Pin {
81 public:
82  InputPin(int pin) : Pin(pin) { setInput(); }
83 };
84 
85 #else
86 // 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
87 // available on a new platform
88 class Pin : public Selectable {
89  volatile RwReg *mPort;
90  volatile RoReg *mInPort;
91  RwReg mPinMask;
92  uint8_t mPin;
93 
94  void _init() {
95  // TODO: fill in init on a new platform
96  mPinMask = 0;
97  mPort = NULL;
98  mInPort = NULL;
99  }
100 public:
101  Pin(int pin) : mPin(pin) { _init(); }
102 
103  void setPin(int pin) { mPin = pin; _init(); }
104 
105  typedef volatile RwReg * port_ptr_t;
106  typedef RwReg port_t;
107 
108  inline void setOutput() { /* TODO: Set pin output */ }
109  inline void setInput() { /* TODO: Set pin input */ }
110 
111  inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; }
112  inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; }
113 
114  inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
115  inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; }
116 
117  inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; }
118  inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; }
119  inline void set(register port_t val) __attribute__ ((always_inline)) { *mPort = val; }
120 
121  inline void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
122 
123  port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; }
124  port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; }
125  port_ptr_t port() __attribute__ ((always_inline)) { return mPort; }
126  port_t mask() __attribute__ ((always_inline)) { return mPinMask; }
127 
128  virtual void select() { hi(); }
129  virtual void release() { lo(); }
130  virtual bool isSelected() { return (*mPort & mPinMask) == mPinMask; }
131 };
132 
133 class OutputPin : public Pin {
134 public:
135  OutputPin(int pin) : Pin(pin) { setOutput(); }
136 };
137 
138 class InputPin : public Pin {
139 public:
140  InputPin(int pin) : Pin(pin) { setInput(); }
141 };
142 
143 #endif
144 
159 #ifdef FASTLED_FORCE_SOFTWARE_PINS
160 template<uint8_t PIN> class FastPin {
161  static RwReg sPinMask;
162  static volatile RwReg *sPort;
163  static volatile RoReg *sInPort;
164  static void _init() {
165 #if !defined(FASTLED_NO_PINMAP)
166  sPinMask = digitalPinToBitMask(PIN);
167  sPort = portOutputRegister(digitalPinToPort(PIN));
168  sInPort = portInputRegister(digitalPinToPort(PIN));
169 #endif
170  }
171 public:
172  typedef volatile RwReg * port_ptr_t;
173  typedef RwReg port_t;
174 
175  inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); }
176  inline static void setInput() { _init(); pinMode(PIN, INPUT); }
177 
178  inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; }
179  inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; }
180 
181  inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
182 
183  inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; }
184 
185  inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; }
186  inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; }
187  inline static void set(register port_t val) __attribute__ ((always_inline)) { *sPort = val; }
188 
189  inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
190 
191  static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; }
192  static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; }
193  static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; }
194  static port_t mask() __attribute__ ((always_inline)) { return sPinMask; }
195 };
196 
197 template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask;
198 template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort;
199 template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort;
200 
201 #else
202 
203 template<uint8_t PIN> class FastPin {
204  constexpr static bool validpin() { return false; }
205 
206  static_assert(validpin(), "Invalid pin specified");
207 
208  static void _init() {
209  }
210 public:
211  typedef volatile RwReg * port_ptr_t;
212  typedef RwReg port_t;
213 
214  inline static void setOutput() { }
215  inline static void setInput() { }
216 
217  inline static void hi() __attribute__ ((always_inline)) { }
218  inline static void lo() __attribute__ ((always_inline)) { }
219 
220  inline static void strobe() __attribute__ ((always_inline)) { }
221 
222  inline static void toggle() __attribute__ ((always_inline)) { }
223 
224  inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { }
225  inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { }
226  inline static void set(register port_t val) __attribute__ ((always_inline)) { }
227 
228  inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { }
229 
230  static port_t hival() __attribute__ ((always_inline)) { return 0; }
231  static port_t loval() __attribute__ ((always_inline)) { return 0;}
232  static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
233  static port_t mask() __attribute__ ((always_inline)) { return 0; }
234 };
235 
236 #endif
237 
238 template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {};
239 
240 typedef volatile uint32_t & reg32_t;
241 typedef volatile uint32_t * ptr_reg32_t;
242 
243 FASTLED_NAMESPACE_END
244 
245 #pragma GCC diagnostic pop
246 
247 #endif // __INC_FASTPIN_H
Definition: fastpin.h:33
central include file for FastLED, defines the CFastLED class/object
The simplest level of Pin class.
Definition: fastpin.h:160
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
Definition: fastled_delay.h:92