MySensors Library & Examples  2.3.2-62-ge298769
DigitalPin.h
Go to the documentation of this file.
1 /* Arduino DigitalIO Library
2  * Copyright (C) 2013 by William Greiman
3  *
4  * This file is part of the Arduino DigitalIO Library
5  *
6  * This Library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This Library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with the Arduino DigitalIO Library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
28 #ifndef DigitalPin_h
29 #define DigitalPin_h
30 #if defined(__AVR__) || defined(DOXYGEN)
31 #include <avr/io.h>
33 struct GpioPinMap_t {
34  volatile uint8_t* pin;
35  volatile uint8_t* ddr;
36  volatile uint8_t* port;
37  uint8_t mask;
38 };
39 
41 #define GPIO_PIN(reg, bit) {&PIN##reg, &DDR##reg, &PORT##reg, 1 << bit}
42 
43 // Include pin map for current board.
44 #include "boards/GpioPinMap.h"
45 //------------------------------------------------------------------------------
47 void badPinNumber(void)
48 __attribute__((error("Pin number is too large or not a constant")));
49 //------------------------------------------------------------------------------
53 static inline __attribute__((always_inline))
54 void badPinCheck(uint8_t pin)
55 {
56  if (!__builtin_constant_p(pin) || pin >= NUM_DIGITAL_PINS) {
57  badPinNumber();
58  }
59 }
60 //------------------------------------------------------------------------------
65 static inline __attribute__((always_inline))
66 volatile uint8_t* ddrReg(uint8_t pin)
67 {
68  badPinCheck(pin);
69  return GpioPinMap[pin].ddr;
70 }
71 //------------------------------------------------------------------------------
76 static inline __attribute__((always_inline))
77 uint8_t pinMask(uint8_t pin)
78 {
79  badPinCheck(pin);
80  return GpioPinMap[pin].mask;
81 }
82 //------------------------------------------------------------------------------
87 static inline __attribute__((always_inline))
88 volatile uint8_t* pinReg(uint8_t pin)
89 {
90  badPinCheck(pin);
91  return GpioPinMap[pin].pin;
92 }
93 //------------------------------------------------------------------------------
98 static inline __attribute__((always_inline))
99 volatile uint8_t* portReg(uint8_t pin)
100 {
101  badPinCheck(pin);
102  return GpioPinMap[pin].port;
103 }
104 //------------------------------------------------------------------------------
110 static inline __attribute__((always_inline))
111 void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level)
112 {
113  uint8_t s;
114  if (address > reinterpret_cast<uint8_t*>(0X3F)) {
115  s = SREG;
116  cli();
117  }
118  if (level) {
119  *address |= mask;
120  } else {
121  *address &= ~mask;
122  }
123  if (address > reinterpret_cast<uint8_t*>(0X3F)) {
124  SREG = s;
125  }
126 }
127 //------------------------------------------------------------------------------
132 static inline __attribute__((always_inline))
133 bool fastDigitalRead(uint8_t pin)
134 {
135  return *pinReg(pin) & pinMask(pin);
136 }
137 //------------------------------------------------------------------------------
144 static inline __attribute__((always_inline))
145 void fastDigitalToggle(uint8_t pin)
146 {
147  if (pinReg(pin) > reinterpret_cast<uint8_t*>(0X3F)) {
148  // must write bit to high address port
149  *pinReg(pin) = pinMask(pin);
150  } else {
151  // will compile to sbi and PIN register will not be read.
152  *pinReg(pin) |= pinMask(pin);
153  }
154 }
155 //------------------------------------------------------------------------------
160 static inline __attribute__((always_inline))
161 void fastDigitalWrite(uint8_t pin, bool level)
162 {
163  fastBitWriteSafe(portReg(pin), pinMask(pin), level);
164 }
165 //------------------------------------------------------------------------------
170 static inline __attribute__((always_inline))
171 void fastDdrWrite(uint8_t pin, bool level)
172 {
173  fastBitWriteSafe(ddrReg(pin), pinMask(pin), level);
174 }
175 //------------------------------------------------------------------------------
183 static inline __attribute__((always_inline))
184 void fastPinMode(uint8_t pin, uint8_t mode)
185 {
186  fastDdrWrite(pin, mode == OUTPUT);
187  if (mode != OUTPUT) {
188  fastDigitalWrite(pin, mode == INPUT_PULLUP);
189  }
190 }
191 #else // defined(__AVR__)
192 #if defined(CORE_TEENSY)
193 //------------------------------------------------------------------------------
198 static inline __attribute__((always_inline))
199 bool fastDigitalRead(uint8_t pin)
200 {
201  return *portInputRegister(pin);
202 }
203 //------------------------------------------------------------------------------
208 static inline __attribute__((always_inline))
209 void fastDigitalWrite(uint8_t pin, bool value)
210 {
211  if (value) {
212  *portSetRegister(pin) = 1;
213  } else {
214  *portClearRegister(pin) = 1;
215  }
216 }
217 #elif defined(__SAM3X8E__) || defined(__SAM3X8H__)
218 //------------------------------------------------------------------------------
223 static inline __attribute__((always_inline))
224 bool fastDigitalRead(uint8_t pin)
225 {
226  return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin;
227 }
228 //------------------------------------------------------------------------------
233 static inline __attribute__((always_inline))
234 void fastDigitalWrite(uint8_t pin, bool value)
235 {
236  if (value) {
237  g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin;
238  } else {
239  g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin;
240  }
241 }
242 #elif defined(ESP8266)
243 //------------------------------------------------------------------------------
248 static inline __attribute__((always_inline))
249 void fastDigitalWrite(uint8_t pin, uint8_t val)
250 {
251  if (pin < 16) {
252  if (val) {
253  GPOS = (1 << pin);
254  } else {
255  GPOC = (1 << pin);
256  }
257  } else if (pin == 16) {
258  if (val) {
259  GP16O |= 1;
260  } else {
261  GP16O &= ~1;
262  }
263  }
264 }
265 //------------------------------------------------------------------------------
270 static inline __attribute__((always_inline))
271 bool fastDigitalRead(uint8_t pin)
272 {
273  if (pin < 16) {
274  return GPIP(pin);
275  } else if (pin == 16) {
276  return GP16I & 0x01;
277  }
278  return 0;
279 }
280 #else // CORE_TEENSY
281 //------------------------------------------------------------------------------
282 inline void fastDigitalWrite(uint8_t pin, bool value)
283 {
284  digitalWrite(pin, value);
285 }
286 //------------------------------------------------------------------------------
287 inline bool fastDigitalRead(uint8_t pin)
288 {
289  return digitalRead(pin);
290 }
291 #endif // CORE_TEENSY
292 //------------------------------------------------------------------------------
293 inline void fastDigitalToggle(uint8_t pin)
294 {
295  fastDigitalWrite(pin, !fastDigitalRead(pin));
296 }
297 //------------------------------------------------------------------------------
298 inline void fastPinMode(uint8_t pin, uint8_t mode)
299 {
300  pinMode(pin, mode);
301 }
302 #endif // __AVR__
303 //------------------------------------------------------------------------------
310 #define fastPinConfig(pin, mode, level)\
311  {fastPinMode(pin, mode); fastDigitalWrite(pin, level);}
312 //==============================================================================
317 template<uint8_t PinNumber>
319 {
320 public:
321  //----------------------------------------------------------------------------
324  //----------------------------------------------------------------------------
331  inline DigitalPin & operator = (bool value) __attribute__((always_inline))
332  {
333  write(value);
334  return *this;
335  }
336  //----------------------------------------------------------------------------
340  inline operator bool () const __attribute__((always_inline))
341  {
342  return read();
343  }
344  //----------------------------------------------------------------------------
350  inline __attribute__((always_inline))
351  void config(uint8_t mode, bool level)
352  {
353  fastPinConfig(PinNumber, mode, level);
354  }
355  //----------------------------------------------------------------------------
359  inline __attribute__((always_inline))
360  void high()
361  {
362  write(true);
363  }
364  //----------------------------------------------------------------------------
368  inline __attribute__((always_inline))
369  void low()
370  {
371  write(false);
372  }
373  //----------------------------------------------------------------------------
381  inline __attribute__((always_inline))
382  void mode(uint8_t mode)
383  {
384  fastPinMode(PinNumber, mode);
385  }
386  //----------------------------------------------------------------------------
388  inline __attribute__((always_inline))
389  bool read() const
390  {
391  return fastDigitalRead(PinNumber);
392  }
393  //----------------------------------------------------------------------------
399  inline __attribute__((always_inline))
400  void toggle()
401  {
402  fastDigitalToggle(PinNumber);
403  }
404  //----------------------------------------------------------------------------
409  inline __attribute__((always_inline))
410  void write(bool value)
411  {
412  fastDigitalWrite(PinNumber, value);
413  }
414 };
415 #endif // DigitalPin_h
416 
GpioPinMap_t::pin
volatile uint8_t * pin
Definition: DigitalPin.h:34
fastPinConfig
#define fastPinConfig(pin, mode, level)
Definition: DigitalPin.h:310
DigitalPin::__attribute__
__attribute__((always_inline)) void write(bool value)
Definition: DigitalPin.h:409
config
Config file.
Definition: config.h:30
DigitalPin::DigitalPin
DigitalPin()
Definition: DigitalPin.h:323
GpioPinMap_t
Definition: DigitalPin.h:33
GpioPinMap_t::port
volatile uint8_t * port
Definition: DigitalPin.h:36
DigitalPin::__attribute__
__attribute__((always_inline)) void mode(uint8_t mode)
Definition: DigitalPin.h:381
badPinNumber
void badPinNumber(void) __attribute__((error("Pin number is too large or not a const ant")))
DigitalPin::__attribute__
__attribute__((always_inline)) void low()
Definition: DigitalPin.h:368
GpioPinMap_t::mask
uint8_t mask
Definition: DigitalPin.h:37
DigitalPin
Fast digital port I/O.
Definition: DigitalPin.h:318
DigitalPin::__attribute__
__attribute__((always_inline)) void toggle()
Definition: DigitalPin.h:399
__attribute__
FW config structure, stored in eeprom.
Definition: MyOTAFirmwareUpdate.h:117
DigitalPin::__attribute__
__attribute__((always_inline)) bool read() const
Definition: DigitalPin.h:388
DigitalPin::operator=
DigitalPin & operator=(bool value) __attribute__((always_inline))
Definition: DigitalPin.h:331
DigitalPin::__attribute__
__attribute__((always_inline)) void config(uint8_t mode
DigitalPin::__attribute__
__attribute__((always_inline)) void high()
Definition: DigitalPin.h:359
GpioPinMap_t::ddr
volatile uint8_t * ddr
Definition: DigitalPin.h:35