FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
gpio.h
Go to the documentation of this file.
1 // Copyright 2016-2021 Jean-Francois Poilpret
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
21 #ifndef FASTIO_HH
22 #define FASTIO_HH
23 
24 #include "boards/board_traits.h"
25 #include "int.h"
26 #include "pci.h"
27 #include "utilities.h"
28 
29 namespace board
30 {
31  template<DigitalPin PIN> constexpr uint8_t BIT() INLINE;
32  template<DigitalPin PIN> constexpr uint8_t MASK() INLINE;
33 
37  template<DigitalPin PIN> constexpr uint8_t BIT()
38  {
40  }
41 
45  template<DigitalPin PIN> constexpr uint8_t MASK()
46  {
48  }
49 };
50 
54 namespace gpio
55 {
59  enum class PinMode : uint8_t
60  {
62  INPUT,
64  INPUT_PULLUP,
66  OUTPUT,
67  };
68 
89  template<board::Port PORT_, uint8_t BIT_> class FastPin
90  {
91  private:
92  using TRAIT = board_traits::Port_trait<PORT_>;
93 
94  public:
95  FastPin(const FastPin<PORT_, BIT_>&) = default;
96  FastPin<PORT_, BIT_>& operator=(const FastPin<PORT_, BIT_>&) = default;
97 
99  static constexpr const board::Port PORT = PORT_;
101  static constexpr const uint8_t BIT = BIT_;
103  static constexpr const uint8_t MASK = bits::BV8(BIT);
104 
111  {
112  static_assert(TRAIT::DPIN_MASK & bits::BV8(BIT), "BIT must be compatible with PORT available pins");
113  }
114 
124  FastPin(PinMode mode, bool value = false) INLINE
125  {
126  static_assert(TRAIT::DPIN_MASK & bits::BV8(BIT), "BIT must be compatible with PORT available pins");
127  set_mode(mode, value);
128  }
129 
137  void set_mode(PinMode mode, bool value = false) INLINE
138  {
139  if (mode == PinMode::OUTPUT)
140  TRAIT::DDR |= bits::BV8(BIT);
141  else
142  TRAIT::DDR &= bits::CBV8(BIT);
143  if (value || (mode == PinMode::INPUT_PULLUP))
144  TRAIT::PORT |= bits::BV8(BIT);
145  else
146  TRAIT::PORT &= bits::CBV8(BIT);
147  }
148 
153  void set() INLINE
154  {
155  TRAIT::PORT |= bits::BV8(BIT);
156  }
157 
162  void clear() INLINE
163  {
164  TRAIT::PORT &= bits::CBV8(BIT);
165  }
166 
172  void toggle() INLINE
173  {
174  TRAIT::PIN |= bits::BV8(BIT);
175  }
176 
182  bool value() INLINE
183  {
184  return TRAIT::PIN & bits::BV8(BIT);
185  }
186  };
187 
201  template<board::Port PORT_> class FastPort
202  {
203  private:
204  using TRAIT = board_traits::Port_trait<PORT_>;
205 
206  public:
207  FastPort(const FastPort<PORT_>&) = default;
208  FastPort<PORT_>& operator=(const FastPort<PORT_>&) = default;
209 
211  static constexpr const board::Port PORT = PORT_;
212 
218  FastPort() = default;
219 
235  FastPort(uint8_t ddr, uint8_t port = 0) INLINE
236  {
237  set_DDR(ddr);
238  set_PORT(port);
239  }
240 
254  template<uint8_t BIT> FastPin<PORT, BIT> get_pin(PinMode mode, bool value = false)
255  {
256  return FastPin<PORT, BIT>{mode, value};
257  }
258 
269  template<uint8_t BIT> FastPin<PORT, BIT> get_pin()
270  {
271  return FastPin<PORT, BIT>{};
272  }
273 
287  void set_PORT(uint8_t port) INLINE
288  {
289  TRAIT::PORT = port;
290  }
291 
301  uint8_t get_PORT() INLINE
302  {
303  return TRAIT::PORT;
304  }
305 
315  void set_DDR(uint8_t ddr) INLINE
316  {
317  TRAIT::DDR = ddr;
318  }
319 
326  uint8_t get_DDR() INLINE
327  {
328  return TRAIT::DDR;
329  }
330 
337  void set_PIN(uint8_t pin) INLINE
338  {
339  TRAIT::PIN = pin;
340  }
341 
348  uint8_t get_PIN() INLINE
349  {
350  return TRAIT::PIN;
351  }
352  };
353 
375  template<board::Port PORT_, uint8_t MASK_> class FastMaskedPort
376  {
377  private:
378  using TRAIT = board_traits::Port_trait<PORT_>;
379 
380  public:
382  FastMaskedPort<PORT_, MASK_>& operator=(const FastMaskedPort<PORT_, MASK_>&) = default;
383 
385  static constexpr const board::Port PORT = PORT_;
386 
388  static constexpr const uint8_t MASK = MASK_;
389 
395  FastMaskedPort() = default;
396 
413  FastMaskedPort(uint8_t ddr, uint8_t port = 0)
414  {
415  set_DDR(ddr);
416  set_PORT(port);
417  }
418 
433  void set_PORT(uint8_t port) INLINE
434  {
435  TRAIT::PORT = uint8_t(TRAIT::PORT & bits::COMPL(MASK)) | uint8_t(port & MASK);
436  }
437 
449  uint8_t get_PORT() INLINE
450  {
451  return TRAIT::PORT & MASK;
452  }
453 
464  void set_DDR(uint8_t ddr) INLINE
465  {
466  TRAIT::DDR = uint8_t(TRAIT::DDR & bits::COMPL(MASK)) | uint8_t(ddr & MASK);
467  }
468 
477  uint8_t get_DDR() INLINE
478  {
479  return TRAIT::DDR & MASK;
480  }
481 
490  void set_PIN(uint8_t pin) INLINE
491  {
492  TRAIT::PIN = pin & MASK;
493  }
494 
501  uint8_t get_PIN() INLINE
502  {
503  return TRAIT::PIN & MASK;
504  }
505  };
506 
544  template<board::DigitalPin DPIN_> class FastPinType
545  {
546  private:
547  using TRAIT = board_traits::DigitalPin_trait<DPIN_>;
548  using PTRAIT = board_traits::Port_trait<TRAIT::PORT>;
549 
550  public:
551  FastPinType() = delete;
552 
554  static constexpr const board::DigitalPin DPIN = DPIN_;
556  static constexpr const board::Port PORT = TRAIT::PORT;
558  static constexpr const uint8_t BIT = TRAIT::BIT;
560  static constexpr const uint8_t MASK = bits::BV8(BIT);
561 
566 
574  static void set_mode(PinMode mode, bool value = false)
575  {
576  if (mode == PinMode::OUTPUT)
577  PTRAIT::DDR |= bits::BV8(BIT);
578  else
579  PTRAIT::DDR &= bits::CBV8(BIT);
580  if (value || (mode == PinMode::INPUT_PULLUP))
581  PTRAIT::PORT |= bits::BV8(BIT);
582  else
583  PTRAIT::PORT &= bits::CBV8(BIT);
584  }
585 
590  static void set()
591  {
592  PTRAIT::PORT |= bits::BV8(BIT);
593  }
594 
599  static void clear()
600  {
601  PTRAIT::PORT &= bits::CBV8(BIT);
602  }
603 
609  static void toggle()
610  {
611  PTRAIT::PIN |= bits::BV8(BIT);
612  }
613 
619  static bool value()
620  {
621  return PTRAIT::PIN & bits::BV8(BIT);
622  }
623  };
624 
626  template<> class FastPinType<board::DigitalPin::NONE>
627  {
628  public:
629  FastPinType() = delete;
630 
631  static constexpr const board::Port PORT = board::Port::NONE;
632  static constexpr const uint8_t BIT = 0;
633  static constexpr const uint8_t MASK = 0;
634  using TYPE = FastPin<PORT, BIT>;
635  using PORT_TYPE = FastPort<PORT>;
636 
637  static void set_mode(UNUSED PinMode mode, UNUSED bool value = false) {}
638  static void set() {}
639  static void clear() {}
640  static void toggle() {}
641  static bool value()
642  {
643  return false;
644  }
645  };
647 
649  template<> class FastPin<board::Port::NONE, 0>
650  {
651  public:
652  FastPin(const FastPin<board::Port::NONE, 0>&) = default;
653  FastPin<board::Port::NONE, 0>& operator=(const FastPin<board::Port::NONE, 0>&) = default;
654  FastPin() INLINE = default;
655  FastPin(PinMode mode UNUSED, bool value UNUSED = false) INLINE {}
656  void set() INLINE {}
657  void clear() INLINE {}
658  void toggle() INLINE {}
659  bool value() INLINE
660  {
661  return false;
662  }
663  };
665 
687  template<board::DigitalPin DPIN_>
689 
710  template<board::InterruptPin IPIN_>
712 
733  template<board::ExternalInterruptPin EPIN_>
735 }
736 
737 #endif /* FASTIO_HH */
738 
gpio::FastPinType::TYPE
FastPin< PORT, BIT > TYPE
The exact FastPin parameterized type for DPIN IO pin.
Definition: gpio.h:563
gpio::FastPinType::set_mode
static void set_mode(PinMode mode, bool value=false)
Set mode (direction) and value (if output) of DPIN.
Definition: gpio.h:574
gpio::FastPinType::DPIN
static constexpr const board::DigitalPin DPIN
The digital pin for this FastPinType.
Definition: gpio.h:554
gpio::FastPort
API that manipulates a whole digital IO port.
Definition: gpio.h:202
gpio::FastMaskedPort::get_DDR
uint8_t get_DDR() INLINE
Get the current 8-bit value of port DDR (direction) register, masked according to the bit mask provid...
Definition: gpio.h:477
gpio::FastMaskedPort::FastMaskedPort
FastMaskedPort()=default
Construct a FastMaskedPort without any physical setup on target MCU.
gpio::FastPinType
API that manipulates a given digital IO pin of a the target MCU.
Definition: gpio.h:545
gpio::FastPinType::value
static bool value()
Return the current level pin DPIN.
Definition: gpio.h:619
gpio::FAST_INT_PIN
typename FastPinType< board::PCI_PIN< IPIN_ >()>::TYPE FAST_INT_PIN
Useful alias type to the FastPin type matching a given board::InterruptPin.
Definition: gpio.h:711
gpio::FastPin::set_mode
void set_mode(PinMode mode, bool value=false) INLINE
Set mode (direction) and value (if output) of this pin.
Definition: gpio.h:137
gpio::FastMaskedPort::get_PIN
uint8_t get_PIN() INLINE
Get the current 8-bit value of PIN register for this port, masked according to the bit mask provided ...
Definition: gpio.h:501
gpio::FastPin::clear
void clear() INLINE
Set pin level to LOW (i.e.
Definition: gpio.h:162
gpio::FastPort::PORT
static constexpr const board::Port PORT
The actual port in target MCU.
Definition: gpio.h:211
gpio::FastPinType::BIT
static constexpr const uint8_t BIT
The bit position of DPIN within its port.
Definition: gpio.h:558
gpio::FastPin
API that manipulates one digital IO pin of a given port.
Definition: gpio.h:90
bits::COMPL
static constexpr uint8_t COMPL(uint8_t value)
Return the uint8_t 2-complement of a byte.
Definition: bits.h:253
gpio::FastPinType::clear
static void clear()
Set pin level to LOW (i.e.
Definition: gpio.h:599
gpio::FastPin::toggle
void toggle() INLINE
Toggle pin level, i.e.
Definition: gpio.h:172
gpio::FastPort::get_pin
FastPin< PORT, BIT > get_pin()
Create a FastPin instance for a given pin of this port.
Definition: gpio.h:269
gpio::FastPort::get_pin
FastPin< PORT, BIT > get_pin(PinMode mode, bool value=false)
Create a FastPin instance for a given pin of this port, and sets its direction mode and level value (...
Definition: gpio.h:254
gpio::FAST_PIN
typename FastPinType< DPIN_ >::TYPE FAST_PIN
Useful alias type to the FastPin type matching a given board::DigitalPin.
Definition: gpio.h:688
bits::BV8
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Definition: bits.h:41
gpio::FastPort::get_PORT
uint8_t get_PORT() INLINE
Get the current 8-bit value of port PORT register.
Definition: gpio.h:301
pci.h
General API for handling Pin Change Interrupts.
gpio::FastPort::FastPort
FastPort()=default
Construct a FastPort without any physical setup on target MCU.
board::MASK
constexpr uint8_t MASK() INLINE
Determine the bit mask representing the given DigitalPin inside its port.
Definition: gpio.h:45
gpio::FastMaskedPort
API that manipulates a part of a digital IO port.
Definition: gpio.h:376
gpio::FastPin::value
bool value() INLINE
Return the current level of this pin.
Definition: gpio.h:182
gpio::FastPort::set_PORT
void set_PORT(uint8_t port) INLINE
Set the 8-bits value for port PORT register.
Definition: gpio.h:287
gpio::FastPin::PORT
static constexpr const board::Port PORT
The port to which this pin belongs.
Definition: gpio.h:99
board
Defines all types and constants specific to support Arduino MEGA board (ATmega644 MCU target).
Definition: atmega_xx4.h:39
gpio::FastPinType::toggle
static void toggle()
Toggle pin level, i.e.
Definition: gpio.h:609
gpio::FastMaskedPort::set_DDR
void set_DDR(uint8_t ddr) INLINE
Set the 8-bits value for port DDR (direction) register, this value will be masked according to the pr...
Definition: gpio.h:464
board::Port
Port
Defines all available ports of ATmega644.
Definition: atmega_xx4.h:55
gpio::FastPin::BIT
static constexpr const uint8_t BIT
The bit position (from 0 to 7), in port, of this pin.
Definition: gpio.h:101
gpio::FastPort::set_PIN
void set_PIN(uint8_t pin) INLINE
Set the 8-bits value for port PIN register.
Definition: gpio.h:337
UNUSED
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
utilities.h
General utilities API that have broad application in programs.
gpio::FastPort::set_DDR
void set_DDR(uint8_t ddr) INLINE
Set the 8-bits value for port DDR (direction) register.
Definition: gpio.h:315
gpio::FastPinType::PORT
static constexpr const board::Port PORT
The port to which DPIN belongs.
Definition: gpio.h:556
board::BIT
constexpr uint8_t BIT() INLINE
Determine the bit position, inside its IO port, of the given DigitalPin.
Definition: gpio.h:37
bits::CBV8
static constexpr uint8_t CBV8(uint8_t bit)
Create a uint8_t inverted bitmask for the given bit number.
Definition: bits.h:137
gpio
Defines all API to manipulate general-purpose digital input/output pins.
Definition: gpio.h:55
gpio::FastMaskedPort::set_PORT
void set_PORT(uint8_t port) INLINE
Set the 8-bits value for port PORT register, this value will be masked according to the provided bit ...
Definition: gpio.h:433
gpio::FastMaskedPort::PORT
static constexpr const board::Port PORT
The actual port in target MCU.
Definition: gpio.h:385
gpio::FastPin::FastPin
FastPin(PinMode mode, bool value=false) INLINE
Construct a FastPin with the given mode and initial value.
Definition: gpio.h:124
gpio::FastMaskedPort::get_PORT
uint8_t get_PORT() INLINE
Get the current 8-bit value of port PORT register, masked according to the bit mask provided at const...
Definition: gpio.h:449
gpio::FastPort::FastPort
FastPort(uint8_t ddr, uint8_t port=0) INLINE
Construct a FastPort with the given direction byte and initial values byte.
Definition: gpio.h:235
gpio::FastPin::MASK
static constexpr const uint8_t MASK
The bit-mask to use when accessing DPIN through PORT.
Definition: gpio.h:103
gpio::PinMode
PinMode
Defines the configurable mode of a digital IO pin.
Definition: gpio.h:60
gpio::FastPinType::PORT_TYPE
FastPort< PORT > PORT_TYPE
The exact FastPort parameterized type that DPIN IO pin belongs to.
Definition: gpio.h:565
gpio::FAST_EXT_PIN
typename FastPinType< board::EXT_PIN< EPIN_ >()>::TYPE FAST_EXT_PIN
Useful alias type to the FastPin type matching a given board::ExternalInterruptPin.
Definition: gpio.h:734
gpio::PinMode::OUTPUT
@ OUTPUT
Digital pin is configured as output.
gpio::FastPinType::set
static void set()
Set pin level to HIGH (i.e.
Definition: gpio.h:590
gpio::FastPinType::MASK
static constexpr const uint8_t MASK
The bit-mask to use when accessing DPIN through PORT.
Definition: gpio.h:560
gpio::FastPort::get_PIN
uint8_t get_PIN() INLINE
Get the 8-bits value of PIN register for this port, i.e.
Definition: gpio.h:348
gpio::FastPort::get_DDR
uint8_t get_DDR() INLINE
Get the current 8-bit value of port DDR (direction) register.
Definition: gpio.h:326
gpio::FastMaskedPort::set_PIN
void set_PIN(uint8_t pin) INLINE
Set the 8-bits value for port PIN register, this value will be masked according to the provided bit m...
Definition: gpio.h:490
gpio::FastPin::FastPin
FastPin() INLINE
Construct a FastPin without any physical setup on target MCU.
Definition: gpio.h:110
gpio::FastPin::set
void set() INLINE
Set pin level to HIGH (i.e.
Definition: gpio.h:153
int.h
General API for handling External Interrupt pins.
gpio::FastMaskedPort::MASK
static constexpr const uint8_t MASK
The bit mask used for this FastMaskedPort.
Definition: gpio.h:388
board::DigitalPin
DigitalPin
Defines all available digital input/output pins of ATmega644, with reference to Arduino MEGA pins.
Definition: atmega_xx4.h:76
INLINE
#define INLINE
Specific GCC attribute to force the compiler to always inline code of a given function.
Definition: defines.h:57
gpio::FastMaskedPort::FastMaskedPort
FastMaskedPort(uint8_t ddr, uint8_t port=0)
Construct a FastMaskedPort for the pins selected by the provide bits mask, with the given direction b...
Definition: gpio.h:413