Skip to content

Commit 921dfe7

Browse files
committed
{attach/detach}Interrupt() functions.
1 parent e7193ac commit 921dfe7

File tree

4 files changed

+144
-354
lines changed

4 files changed

+144
-354
lines changed

hardware/arduino/sam/cores/arduino/WInterrupts.c

Lines changed: 136 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2011 Arduino. All right reserved.
2+
Copyright (c) 2011-2012 Arduino. All right reserved.
33
44
This library is free software; you can redistribute it and/or
55
modify it under the terms of the GNU Lesser General Public
@@ -18,38 +18,152 @@
1818

1919
#include "WInterrupts.h"
2020

21-
#ifdef __cplusplus
22-
extern "C" {
23-
#endif
21+
typedef void (*interruptCB)(void);
22+
23+
static int pinMapping[EXTERNAL_NUM_INTERRUPTS] = { 2, 3, 4, 5, 6, 7, 8 };
24+
25+
static interruptCB callbacksPioA[32];
26+
static interruptCB callbacksPioB[32];
27+
static interruptCB callbacksPioC[32];
28+
29+
/* Configure PIO interrupt sources */
30+
static void __initialize() {
31+
int i;
32+
for (i=0; i<32; i++) {
33+
callbacksPioA[i] = NULL;
34+
callbacksPioB[i] = NULL;
35+
callbacksPioC[i] = NULL;
36+
}
2437

25-
/** PIO interrupt handlers array */
26-
/*volatile*/ static voidFuncPtr g_apfn_IntFunc[EXTERNAL_NUM_INTERRUPTS]={ 0 } ;
38+
pmc_enable_periph_clk(ID_PIOA);
39+
NVIC_DisableIRQ(PIOA_IRQn);
40+
NVIC_ClearPendingIRQ(PIOA_IRQn);
41+
NVIC_SetPriority(PIOA_IRQn, 0);
42+
NVIC_EnableIRQ(PIOA_IRQn);
2743

28-
void attachInterrupt( uint32_t ulInterrupt, void (*pfn_UserFunc)(void), uint32_t ulMode )
44+
pmc_enable_periph_clk(ID_PIOB);
45+
NVIC_DisableIRQ(PIOB_IRQn);
46+
NVIC_ClearPendingIRQ(PIOB_IRQn);
47+
NVIC_SetPriority(PIOB_IRQn, 0);
48+
NVIC_EnableIRQ(PIOB_IRQn);
49+
50+
pmc_enable_periph_clk(ID_PIOC);
51+
NVIC_DisableIRQ(PIOC_IRQn);
52+
NVIC_ClearPendingIRQ(PIOC_IRQn);
53+
NVIC_SetPriority(PIOC_IRQn, 0);
54+
NVIC_EnableIRQ(PIOC_IRQn);
55+
}
56+
57+
58+
void attachInterrupt(uint32_t interruptNum, void (*callback)(void), uint32_t mode)
2959
{
30-
if ( ulInterrupt < EXTERNAL_NUM_INTERRUPTS )
31-
{
32-
g_apfn_IntFunc[ulInterrupt] = pfn_UserFunc ;
60+
if (interruptNum >= EXTERNAL_NUM_INTERRUPTS)
61+
return;
62+
63+
static int enabled = 0;
64+
if (!enabled) {
65+
__initialize();
66+
enabled = 1;
67+
}
68+
69+
// Retrieve pin information
70+
uint32_t pin = pinMapping[interruptNum];
71+
Pio *pio = g_APinDescription[pin].pPort;
72+
uint32_t mask = g_APinDescription[pin].ulPin;
73+
uint32_t pos = 0;
3374

34-
// Configure the interrupt mode (trigger on low input, any change, rising
35-
// edge, or falling edge). The mode constants were chosen to correspond
36-
// to the configuration bits in the hardware register, so we simply shift
37-
// the mode into place.
75+
uint32_t t;
76+
for (t = mask; t>1; t>>=1, pos++)
77+
;
3878

39-
// Enable the interrupt.
79+
// Set callback function
80+
if (pio == PIOA)
81+
callbacksPioA[pos] = callback;
82+
if (pio == PIOB)
83+
callbacksPioB[pos] = callback;
84+
if (pio == PIOC)
85+
callbacksPioC[pos] = callback;
4086

41-
}
87+
// Configure the interrupt mode
88+
if (mode == CHANGE) {
89+
// Disable additional interrupt mode (detects both rising and falling edges)
90+
pio->PIO_AIMDR = mask;
91+
} else {
92+
// Enable additional interrupt mode
93+
pio->PIO_AIMER = mask;
94+
95+
// Select mode of operation
96+
if (mode == LOW) {
97+
pio->PIO_LSR = mask; // "Level" Select Register
98+
pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register
99+
}
100+
if (mode == HIGH) {
101+
pio->PIO_LSR = mask; // "Level" Select Register
102+
pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register
103+
}
104+
if (mode == FALLING) {
105+
pio->PIO_ESR = mask; // "Edge" Select Register
106+
pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register
107+
}
108+
if (mode == RISING) {
109+
pio->PIO_ESR = mask; // "Edge" Select Register
110+
pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register
111+
}
112+
}
113+
114+
// Enable interrupt
115+
pio->PIO_IER = mask;
42116
}
43117

44-
void detachInterrupt( uint32_t ulInterrupt )
118+
void detachInterrupt( uint32_t interruptNum )
45119
{
46-
if ( ulInterrupt < EXTERNAL_NUM_INTERRUPTS )
47-
{
48-
/* Disable the interrupt. */
120+
if (interruptNum >= EXTERNAL_NUM_INTERRUPTS)
121+
return;
122+
123+
// Retrieve pin information
124+
uint32_t pin = pinMapping[interruptNum];
125+
Pio *pio = g_APinDescription[pin].pPort;
126+
uint32_t mask = g_APinDescription[pin].ulPin;
127+
128+
// Disable interrupt
129+
pio->PIO_IDR = mask;
130+
}
131+
132+
#ifdef __cplusplus
133+
extern "C" {
134+
#endif
49135

136+
void PIOA_Handler(void) {
137+
uint32_t isr = PIOA->PIO_ISR;
138+
uint32_t i;
139+
for (i=0; i<32; i++, isr>>=1) {
140+
if ((isr & 0x1) == 0)
141+
continue;
142+
if (callbacksPioA[i])
143+
callbacksPioA[i]();
144+
}
145+
}
146+
147+
void PIOB_Handler(void) {
148+
uint32_t isr = PIOB->PIO_ISR;
149+
uint32_t i;
150+
for (i=0; i<32; i++, isr>>=1) {
151+
if ((isr & 0x1) == 0)
152+
continue;
153+
if (callbacksPioB[i])
154+
callbacksPioB[i]();
155+
}
156+
}
50157

51-
g_apfn_IntFunc[ulInterrupt] = NULL ;
52-
}
158+
void PIOC_Handler(void) {
159+
uint32_t isr = PIOC->PIO_ISR;
160+
uint32_t i;
161+
for (i=0; i<32; i++, isr>>=1) {
162+
if ((isr & 0x1) == 0)
163+
continue;
164+
if (callbacksPioC[i])
165+
callbacksPioC[i]();
166+
}
53167
}
54168

55169
#ifdef __cplusplus

hardware/arduino/sam/cores/arduino/WInterrupts.h

Lines changed: 3 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2011 Arduino. All right reserved.
2+
Copyright (c) 2011-2012 Arduino. All right reserved.
33
44
This library is free software; you can redistribute it and/or
55
modify it under the terms of the GNU Lesser General Public
@@ -25,55 +25,9 @@
2525
extern "C" {
2626
#endif
2727

28+
void attachInterrupt(uint32_t interruptNum, void (*callback)(void), uint32_t mode);
2829

29-
//typedef struct _InterruptSource
30-
//{
31-
// /* Pointer to the source pin instance. */
32-
// PinDescription *pPin ;
33-
//
34-
// /* Interrupt handler. */
35-
// void (*handler)( const PinDescription *pPin ) ;
36-
//} InterruptSource ;
37-
38-
39-
/*
40-
* \brief Specifies a function to call when an external interrupt occurs.
41-
* Replaces any previous function that was attached to the interrupt.
42-
* All Arduino SAM3 based boards pins can be switched into INPUT mode and have
43-
* an interrupt user function attached to an event.
44-
*
45-
* \param ulInterrupt
46-
* \param pfn_UserFunc
47-
* \param ulMode
48-
*
49-
PIO_IT_RE_OR_HL = Interrupt High Level/Rising Edge detection is active
50-
PIO_IT_EDGE = Interrupt Edge detection is active
51-
PIO_IT_LOW_LEVEL = Low level interrupt is active
52-
PIO_IT_HIGH_LEVEL = High level interrupt is active
53-
PIO_IT_FALL_EDGE = Falling edge interrupt is active
54-
PIO_IT_RISE_EDGE = Rising edge interrupt is active
55-
56-
interrupt: the number of the interrupt (int)
57-
58-
function: the function to call when the interrupt occurs; this function must take no parameters and return nothing. This function is sometimes referred to as an interrupt service routine.
59-
60-
mode defines when the interrupt should be triggered. Four contstants are predefined as valid values:
61-
62-
LOW to trigger the interrupt whenever the pin is low,
63-
CHANGE to trigger the interrupt whenever the pin changes value
64-
RISING to trigger when the pin goes from low to high,
65-
FALLING for when the pin goes from high to low.
66-
*/
67-
extern void attachInterrupt( uint32_t ulInterrupt, void (*pfn_UserFunc)(void), uint32_t ulMode ) ;
68-
69-
/*
70-
Turns off the given interrupt.
71-
72-
Parameters
73-
74-
interrupt: the number of interrupt to disable (0 or 1).
75-
*/
76-
extern void detachInterrupt( uint32_t ulInterrupt ) ;
30+
void detachInterrupt(uint32_t interruptNum);
7731

7832
#ifdef __cplusplus
7933
}

hardware/arduino/sam/cores/arduino/wiring_constants.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ enum BitOrder {
4747
MSBFIRST = 1
4848
};
4949

50-
#define CHANGE 1
51-
#define FALLING 2
52-
#define RISING 3
50+
// LOW 0
51+
// HIGH 1
52+
#define CHANGE 2
53+
#define FALLING 3
54+
#define RISING 4
5355

5456
#define DEFAULT 1
5557
#define EXTERNAL 0

0 commit comments

Comments
 (0)