Skip to content

Commit 604ac62

Browse files
committed
GPIO interrupts completed
attach/detachInterrupt now supported. Also included support for interrupts with arbitrary arguments via void* pointer (advanced feature)
1 parent c64f697 commit 604ac62

File tree

5 files changed

+60
-49
lines changed

5 files changed

+60
-49
lines changed

cores/arduino/ard_sup/ap3_gpio.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ inline bool ap3_gpio_is_valid(ap3_gpio_pad_t pad){ return AP3_GPIO_IS_VALID(pad)
5454
inline bool ap3_gpio_has_gpio(ap3_gpio_pad_t pad){ return AP3_GPIO_IS_VALID(pad); }
5555

5656
// Interrupt enable/disable function
57-
uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, bool enable);
57+
uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir );
5858

5959
void padMode(uint8_t pad, am_hal_gpio_pincfg_t mode);
6060
void padMode(uint8_t pad, am_hal_gpio_pincfg_t mode, ap3_err_t* retval);

cores/arduino/ard_sup/gpio/ap3_gpio.cpp

+39-22
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ typedef struct{
1010
ap3_gpio_isr_entry_t gpio_isr_entries[AP3_GPIO_MAX_PADS] = {NULL};
1111
uint8_t gpio_num_isr = 0;
1212

13+
//*****************************************************************************
14+
// Local defines. Copied from am_hal_gpio.c
15+
//*****************************************************************************
16+
//
17+
// Generally define GPIO PADREG and GPIOCFG bitfields
18+
//
19+
#define PADREG_FLD_76_S 6
20+
#define PADREG_FLD_FNSEL_S 3
21+
#define PADREG_FLD_DRVSTR_S 2
22+
#define PADREG_FLD_INPEN_S 1
23+
#define PADREG_FLD_PULLUP_S 0
24+
25+
#define GPIOCFG_FLD_INTD_S 3
26+
#define GPIOCFG_FLD_OUTCFG_S 1
27+
#define GPIOCFG_FLD_INCFG_S 0
1328

1429

1530

@@ -126,6 +141,17 @@ extern "C" void am_gpio_isr(void)
126141
}
127142
if( !((gpio_isr_entries[indi].mode == LOW) || (gpio_isr_entries[indi].mode == HIGH)) ){ // if not a HIGH or LOW interrupt then clear the flag
128143
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(gpio_isr_entries[indi].pad));
144+
}else{ // In the case of a HIGH or LOW mode interrupt we need to manually check for the end state
145+
uint8_t val = digitalRead( gpio_isr_entries[indi].pad );
146+
if( gpio_isr_entries[indi].mode == LOW ){
147+
if( val ){
148+
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(gpio_isr_entries[indi].pad));
149+
}
150+
}else{
151+
if( !val ){
152+
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(gpio_isr_entries[indi].pad));
153+
}
154+
}
129155
}
130156
}
131157
}
@@ -149,18 +175,16 @@ void attachInterruptArg(uint8_t pin, voidFuncPtrArgs callbackArgs, void * arg, i
149175
gpio_isr_entries[indi].arg = arg;
150176
gpio_isr_entries[indi].mode = mode;
151177

152-
// todo: need to somehow enable interrupts for the pad in question (Arduino does this by default when attachInterrupt is called)
153-
// needs to respect the 'mode'
154-
// needs to no overwrite the old configuration
155-
am_hal_gpio_pincfg_t int_pincfg;
178+
// enable interrupts for the pad in question (Arduino does this by default when attachInterrupt is called)
179+
uint8_t eIntDir = 0x00;
156180
if(( mode == FALLING ) || ( mode == LOW )){
157-
int_pincfg.eIntDir = AM_HAL_GPIO_PIN_INTDIR_HI2LO;
181+
eIntDir = AM_HAL_GPIO_PIN_INTDIR_HI2LO;
158182
}else if(( mode == RISING ) || ( mode == HIGH )){
159-
int_pincfg.eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI;
183+
eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI;
160184
}else{
161-
int_pincfg.eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH;
185+
eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH;
162186
}
163-
ap3_gpio_pinconfig_ORnot( pad, int_pincfg, true);
187+
ap3_gpio_enable_interrupts( pad, eIntDir);
164188

165189
// clear the flag and enable the interrupt in the NVIC
166190
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(pad));
@@ -197,14 +221,12 @@ extern void detachInterrupt(uint8_t pin)
197221
return;
198222
}
199223

200-
// disable interrupts for the given pad without blasting the configuration
201-
am_hal_gpio_pincfg_t int_pincfg;
202-
int_pincfg.eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH; // disable any interrupts
203-
204-
ap3_gpio_pinconfig_ORnot( pad, int_pincfg, false);
205-
206224
// disable the interrupt in the NVIC
207225
am_hal_gpio_interrupt_disable(AM_HAL_GPIO_BIT(pad));
226+
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(pad));
227+
228+
// disable interrupts for the given pad without blasting the configuration
229+
ap3_gpio_enable_interrupts( pad, AM_HAL_GPIO_PIN_INTDIR_NONE);
208230

209231
// Shift down the remaining interrupt entries
210232
for(indi; indi < gpio_num_isr-1; indi++){
@@ -236,7 +258,7 @@ extern void detachInterrupt(uint8_t pin)
236258

237259

238260

239-
uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, bool enable)
261+
uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir )
240262
{
241263
uint32_t ui32Padreg, ui32AltPadCfg, ui32GPCfg;
242264
uint32_t ui32Funcsel, ui32PowerSw;
@@ -262,7 +284,7 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, bool enable)
262284
// Bit0 of eIntDir maps to GPIOCFG.INTD (b3).
263285
// Bit1 of eIntDir maps to GPIOCFG.INCFG (b0).
264286
//
265-
ui32GPCfg |= (((bfGpioCfg.eIntDir >> 0) & 0x1) << GPIOCFG_FLD_INTD_S) | (((bfGpioCfg.eIntDir >> 1) & 0x1) << GPIOCFG_FLD_INCFG_S);
287+
ui32GPCfg |= (((eIntDir >> 0) & 0x1) << GPIOCFG_FLD_INTD_S) | (((eIntDir >> 1) & 0x1) << GPIOCFG_FLD_INCFG_S);
266288

267289

268290
//
@@ -296,12 +318,7 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, bool enable)
296318
GPIO->PADKEY = GPIO_PADKEY_PADKEY_Key;
297319

298320
// Here's where the magic happens
299-
if(ORnot){
300-
AM_REGVAL(ui32GPCfgAddr) = (AM_REGVAL(ui32GPCfgAddr) & ui32GPCfgClearMask) | ui32GPCfg;
301-
}else{
302-
AM_REGVAL(ui32GPCfgAddr) = (AM_REGVAL(ui32GPCfgAddr) & ui32GPCfgClearMask) & ~ui32GPCfg;
303-
}
304-
321+
AM_REGVAL(ui32GPCfgAddr) = (AM_REGVAL(ui32GPCfgAddr) & ui32GPCfgClearMask) | ui32GPCfg;
305322

306323
GPIO->PADKEY = 0;
307324

libraries/CoreTesting/examples/example10_interrupts/example10_interrupts.ino

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
/* Author: Owen Lyke
2-
Created: April 9 2019
2+
Created: June 19 2019
33
License: MIT. See SparkFun Arduino Apollo3 Project for more information
44
5-
This example demonstrates usage of Arduino interrupts
6-
*/
5+
This example demonstrates usage of Arduino interrupts.
6+
All interrupt modes are enabled, however HIGH and LOW are software controlled because the Apollo3 does not
7+
support HIGH or LOW interrupt states in hardware.
8+
9+
When HIGH or LOW is selected as an interrupt mode the pad value is read during each ISR call and if the value
10+
no longer matches the mode the ISR flag is cleared. Keep in mind that as long as the interrupt condition
11+
remains true only registered ISRs will execute (in order of first attachment for each pin)
712
8-
#include "structs.h"
13+
The edge-based interrupts will clear the flag automatically.
14+
15+
*/
916

1017
#define INT_PIN 16
1118
static uint32_t count = 0;
19+
bool interruptsEnabled = false;
1220

1321
void setup() {
1422
// put your setup code here, to run once:
1523

1624
Serial.begin(9600);
17-
Serial.print("Interrupt testing");
25+
Serial.println("Interrupt testing");
1826

19-
am_hal_gpio_pinconfig(INT_PIN, g_deepsleep_button0);
27+
pinMode(INT_PIN, INPUT_PULLUP);
2028

2129
attachInterrupt(digitalPinToInterrupt(INT_PIN), myISR, RISING);
2230
// attachInterrupt(digitalPinToInterrupt(INT_PIN), myISR, FALLING);
@@ -25,12 +33,17 @@ void setup() {
2533

2634
// // attaching a different interrupt to the same pin overwrites the existing ISR
2735
// attachInterruptArg(digitalPinToInterrupt(INT_PIN), myISRArg, &count, RISING);
36+
37+
interruptsEnabled = true;
2838
}
2939

3040
void loop() {
3141
count++;
3242
if( count > 5 ){
33-
detachInterrupt(digitalPinToInterrupt(INT_PIN));
43+
if(interruptsEnabled){
44+
detachInterrupt(digitalPinToInterrupt(INT_PIN));
45+
interruptsEnabled = false;
46+
}
3447
}
3548
delay(1000);
3649
}

libraries/CoreTesting/examples/example10_interrupts/structs.c

-9
This file was deleted.

libraries/CoreTesting/examples/example10_interrupts/structs.h

-10
This file was deleted.

0 commit comments

Comments
 (0)