wpi-32u4-library
pcint.cpp
Go to the documentation of this file.
1#include <pcint.h>
2
3//define an ISR function pointer; ISRs are of type void fxn(void)
4typedef void(*PCISR)(void);
5
6//array to hold all of the indivicual ISRs; initialize to null
7PCISR pcISR[] = {0, 0, 0, 0, 0, 0, 0, 0};
8
9//store the previous state -- needed to find which have changed
10static volatile uint8_t lastB = PINB; //these are likely all 0 at the start
11
12void attachPCInt(uint8_t pcInt, void (*pcisr)(void))
13{
14 cli();
15 PCICR = (1 << PCIE0); //enable PC interrupts (not a problem to set repeatedly)
16
17 PCMSK0 |= (1 << pcInt); //enable PCInt on the specific pin
18 pcISR[pcInt] = pcisr; //register the ISR
19
20 PCIFR = (1 << PCIF0); //clear any pending interrupt before we get started
21
22 //make sure we start with the current state, but don't clobber other pins
23 lastB &= ~(1 << pcInt); //clear the affected pin in lastB
24 lastB |= PINB & (1 << pcInt); //then set it to the current state
25 sei();
26}
27
28ISR(PCINT0_vect)
29{
30 //read the current state of the PCINT pins
31 volatile uint8_t pinsB = PINB;
32
33 //find the pins that have changed
34 volatile uint8_t deltaB = pinsB ^ lastB;
35
36 //we're only interested in pins that have changed AND are set for interrupts
37 volatile uint8_t maskedDeltaB = deltaB & PCMSK0;
38
39 //each of these checks if each ISR should run
40 if((maskedDeltaB & (1 << PCINT0))) {pcISR[PCINT0]();}
41 if((maskedDeltaB & (1 << PCINT1))) {pcISR[PCINT1]();}
42 if((maskedDeltaB & (1 << PCINT2))) {pcISR[PCINT2]();}
43 if((maskedDeltaB & (1 << PCINT3))) {pcISR[PCINT3]();}
44 if((maskedDeltaB & (1 << PCINT4))) {pcISR[PCINT4]();}
45 if((maskedDeltaB & (1 << PCINT5))) {pcISR[PCINT5]();}
46 if((maskedDeltaB & (1 << PCINT6))) {pcISR[PCINT6]();}
47 if((maskedDeltaB & (1 << PCINT7))) {pcISR[PCINT7]();}
48
49 //update last pin states
50 lastB = pinsB;
51}
52
53uint8_t digitalPinToPCInterrupt(uint8_t pin)
54{
55 uint8_t pcInt = NOT_AN_INTERRUPT;
56
57#if defined(__AVR_ATmega32U4__)
58 switch(pin)
59 {
60 case 17: pcInt = PCINT0; break;
61 case 15: pcInt = PCINT1; break;
62 case 16: pcInt = PCINT2; break;
63 case 14: pcInt = PCINT3; break;
64 case 8: pcInt = PCINT4; break;
65 case 9: pcInt = PCINT5; break;
66 case 10: pcInt = PCINT6; break;
67 case 11: pcInt = PCINT7; break;
68 default: break;
69 }
70#endif
71
72 return pcInt;
73}
void(* PCISR)(void)
Definition: pcint.cpp:4
uint8_t digitalPinToPCInterrupt(uint8_t pin)
Definition: pcint.cpp:53
static volatile uint8_t lastB
Definition: pcint.cpp:10
void attachPCInt(uint8_t pcInt, void(*pcisr)(void))
Attaches a function to a pin change interrupt.
Definition: pcint.cpp:12
ISR(PCINT0_vect)
Definition: pcint.cpp:28
PCISR pcISR[]
Definition: pcint.cpp:7