FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
int.h
Go to the documentation of this file.
1// Copyright 2016-2023 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
87namespace 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
99namespace 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&) = delete;
144 INTSignal& operator=(const INTSignal&) = delete;
145
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 */
Handler of an External Interrupt.
Definition: int.h:132
void enable_()
Enable interrupts for this external interrupt pin.
Definition: int.h:234
static constexpr const board::ExternalInterruptPin EXTPIN
The External Interrupt pin managed by this INTSignal.
Definition: int.h:135
static constexpr const board::DigitalPin PIN
The actual connected pin managed by this INTSignal.
Definition: int.h:137
void clear()
Clear the interrupt flag for this external interrupt pin.
Definition: int.h:209
void set_trigger(InterruptTrigger trigger)
Change the kind of level event that shall trigger an External Interrupt for EXTPIN.
Definition: int.h:170
void clear_()
Clear the interrupt flag for this external interrupt pin.
Definition: int.h:260
INTSignal(InterruptTrigger trigger=InterruptTrigger::ANY_CHANGE)
Create a handler for EXTPIN external interrupt pin.
Definition: int.h:154
void disable()
Disable interrupts for this external interrupt pin.
Definition: int.h:195
void enable()
Enable interrupts for this external interrupt pin.
Definition: int.h:183
void disable_()
Disable interrupts for this external interrupt pin.
Definition: int.h:246
void set_trigger_(InterruptTrigger trigger)
Enable interrupts for this external interrupt pin.
Definition: int.h:221
#define INLINE
Specific GCC attribute to force the compiler to always inline code of a given function.
Definition: defines.h:57
General API for handling AVR interrupt vectors.
static constexpr uint8_t COMPL(uint8_t value)
Return the uint8_t 2-complement of a byte.
Definition: bits.h:253
Defines all types and constants specific to support a specific MCU target.
Definition: empty.h:38
DigitalPin
Defines all available digital input/output pins of the target MCU.
Definition: empty.h:56
constexpr DigitalPin EXT_PIN() INLINE
Convert an ExternalInterruptPin to the matching DigitalPin.
Definition: int.h:93
ExternalInterruptPin
Defines all digital output pins of target MCU, usable as direct external interrupt pins.
Definition: empty.h:91
Defines API to handle AVR interruptions.
Definition: int.h:100
InterruptTrigger
Kind of change that will trigger an External Interrupt for a given pin.
Definition: int.h:107
@ ANY_CHANGE
Interrupt is triggered whenever pin level is changing (rising or falling).
@ FALLING_EDGE
Interrupt is triggered whenever pin level is falling from high to low.
@ LOW_LEVEL
Interrupt is triggered whenever pin level is low.
@ RISING_EDGE
Interrupt is triggered whenever pin level is rising from low to high.
General utilities API that have broad application in programs.