FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
int.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 INT_HH
22 #define INT_HH
23 
24 #include "boards/board_traits.h"
25 #include <avr/interrupt.h>
26 #include "interrupts.h"
27 #include "utilities.h"
28 
39 #define REGISTER_INT_ISR_METHOD(INT_NUM, PIN, HANDLER, CALLBACK) \
40  ISR(CAT3(INT, INT_NUM, _vect)) \
41  { \
42  interrupt::isr_handler_int::int_method<INT_NUM, PIN, HANDLER, CALLBACK>(); \
43  }
44 
54 #define REGISTER_INT_ISR_FUNCTION(INT_NUM, PIN, CALLBACK) \
55  ISR(CAT3(INT, INT_NUM, _vect)) \
56  { \
57  interrupt::isr_handler_int::int_function<INT_NUM, PIN, CALLBACK>(); \
58  }
59 
69 #define REGISTER_INT_ISR_EMPTY(INT_NUM, PIN) \
70  extern "C" void CAT3(INT, INT_NUM, _vect)(void) NAKED_SIGNAL; \
71  void CAT3(INT, INT_NUM, _vect)(void) \
72  { \
73  interrupt::isr_handler_int::check_int_pin<INT_NUM, PIN>(); \
74  __asm__ __volatile__("reti" ::); \
75  }
76 
83 #define DECL_INT_ISR_HANDLERS_FRIEND \
84  friend struct interrupt::isr_handler_int; \
85  DECL_INT_ISR_FRIENDS
86 
87 namespace board
88 {
89  template<ExternalInterruptPin EXT> constexpr DigitalPin EXT_PIN() INLINE;
93  template<ExternalInterruptPin EXT> constexpr DigitalPin EXT_PIN()
94  {
95  return board_traits::ExternalInterruptPin_trait<EXT>::ACTUAL_PIN;
96  }
97 };
98 
99 namespace interrupt
100 {
106  enum class InterruptTrigger : uint8_t
107  {
109  LOW_LEVEL = 0x00,
111  ANY_CHANGE = 0x55,
113  FALLING_EDGE = 0xAA,
115  RISING_EDGE = 0xFF
116  };
117 
131  template<board::ExternalInterruptPin EXTPIN_> class INTSignal
132  {
133  public:
135  static constexpr const board::ExternalInterruptPin EXTPIN = EXTPIN_;
137  static constexpr const board::DigitalPin PIN = board::EXT_PIN<EXTPIN>();
138 
139  private:
140  using INT_TRAIT = board_traits::ExternalInterruptPin_trait<EXTPIN>;
141 
142  public:
143  INTSignal(const INTSignal<EXTPIN_>&) = delete;
144  INTSignal<EXTPIN_>& operator=(const INTSignal<EXTPIN_>&) = delete;
145 
154  explicit INTSignal(InterruptTrigger trigger = InterruptTrigger::ANY_CHANGE)
155  {
156  set_trigger_(trigger);
157  }
158 
171  {
172  synchronized INT_TRAIT::EICR_ =
173  (INT_TRAIT::EICR_ & bits::COMPL(INT_TRAIT::EICR_MASK)) | (uint8_t(trigger) & INT_TRAIT::EICR_MASK);
174  }
175 
183  void enable()
184  {
185  synchronized INT_TRAIT::EIMSK_ |= INT_TRAIT::EIMSK_MASK;
186  }
187 
195  void disable()
196  {
197  synchronized INT_TRAIT::EIMSK_ &= bits::COMPL(INT_TRAIT::EIMSK_MASK);
198  }
199 
209  void clear()
210  {
211  synchronized INT_TRAIT::EIFR_ |= INT_TRAIT::EIFR_MASK;
212  }
213 
222  {
223  INT_TRAIT::EICR_ = (INT_TRAIT::EICR_ & bits::COMPL(INT_TRAIT::EICR_MASK))
224  | (uint8_t(trigger) & INT_TRAIT::EICR_MASK);
225  }
226 
234  void enable_()
235  {
236  INT_TRAIT::EIMSK_ |= INT_TRAIT::EIMSK_MASK;
237  }
238 
246  void disable_()
247  {
248  INT_TRAIT::EIMSK_ &= bits::COMPL(INT_TRAIT::EIMSK_MASK);
249  }
250 
260  void clear_()
261  {
262  INT_TRAIT::EIFR_ |= INT_TRAIT::EIFR_MASK;
263  }
264  };
265 
267 
268  // All INT-related methods called by pre-defined ISR are defined here
269  //====================================================================
270 
271  struct isr_handler_int
272  {
273  template<uint8_t INT_NUM_, board::ExternalInterruptPin INT_PIN_> static void check_int_pin()
274  {
275  static_assert(board_traits::ExternalInterruptPin_trait<INT_PIN_>::INT == INT_NUM_,
276  "PIN INT number must match INT_NUM");
277  }
278 
279  template<uint8_t INT_NUM_, board::ExternalInterruptPin INT_PIN_, typename HANDLER_, void (HANDLER_::*CALLBACK_)()>
280  static void int_method()
281  {
282  // Check pin is compliant
283  check_int_pin<INT_NUM_, INT_PIN_>();
284  // Call handler back
285  interrupt::CallbackHandler<void (HANDLER_::*)(), CALLBACK_>::call();
286  }
287 
288  template<uint8_t INT_NUM_, board::ExternalInterruptPin INT_PIN_, void (*CALLBACK_)()> static void int_function()
289  {
290  // Check pin is compliant
291  check_int_pin<INT_NUM_, INT_PIN_>();
292  // Call handler back
293  CALLBACK_();
294  }
295  };
297 }
298 
299 #endif /* INT_HH */
300 
interrupt::INTSignal::clear
void clear()
Clear the interrupt flag for this external interrupt pin.
Definition: int.h:209
interrupt::INTSignal::PIN
static constexpr const board::DigitalPin PIN
The actual connected pin managed by this INTSignal.
Definition: int.h:137
board::EXT_PIN
constexpr DigitalPin EXT_PIN() INLINE
Convert an ExternalInterruptPin to the matching DigitalPin.
Definition: int.h:93
board::ExternalInterruptPin
ExternalInterruptPin
Defines all digital output pins of ATmega644, usable as direct external interrupt pins.
Definition: atmega_xx4.h:244
interrupt::INTSignal::set_trigger
void set_trigger(InterruptTrigger trigger)
Change the kind of level event that shall trigger an External Interrupt for EXTPIN.
Definition: int.h:170
interrupt::INTSignal::clear_
void clear_()
Clear the interrupt flag for this external interrupt pin.
Definition: int.h:260
bits::COMPL
static constexpr uint8_t COMPL(uint8_t value)
Return the uint8_t 2-complement of a byte.
Definition: bits.h:253
interrupt::InterruptTrigger
InterruptTrigger
Kind of change that will trigger an External Interrupt for a given pin.
Definition: int.h:107
interrupt
Defines API to handle AVR interruptions.
Definition: int.h:100
interrupt::INTSignal::disable
void disable()
Disable interrupts for this external interrupt pin.
Definition: int.h:195
board
Defines all types and constants specific to support Arduino MEGA board (ATmega644 MCU target).
Definition: atmega_xx4.h:39
interrupt::INTSignal
Handler of an External Interrupt.
Definition: int.h:132
interrupt::INTSignal::disable_
void disable_()
Disable interrupts for this external interrupt pin.
Definition: int.h:246
utilities.h
General utilities API that have broad application in programs.
interrupt::INTSignal::INTSignal
INTSignal(InterruptTrigger trigger=InterruptTrigger::ANY_CHANGE)
Create a handler for EXTPIN external interrupt pin.
Definition: int.h:154
interrupt::INTSignal::enable_
void enable_()
Enable interrupts for this external interrupt pin.
Definition: int.h:234
interrupt::INTSignal::set_trigger_
void set_trigger_(InterruptTrigger trigger)
Enable interrupts for this external interrupt pin.
Definition: int.h:221
interrupts.h
General API for handling AVR interrupt vectors.
interrupt::INTSignal::EXTPIN
static constexpr const board::ExternalInterruptPin EXTPIN
The External Interrupt pin managed by this INTSignal.
Definition: int.h:135
interrupt::INTSignal::enable
void enable()
Enable interrupts for this external interrupt pin.
Definition: int.h:183
interrupt::InterruptTrigger::LOW_LEVEL
@ LOW_LEVEL
Interrupt is triggered whenever pin level is low.
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