Pages: [1]   Go Down
Author Topic: External interrupts  (Read 3376 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

According to the new product page for the Due it states "interrupts 0 and 1 (pins 2 and 3 respectively)".   This is the only mention of interrupts on the page.   Are there not more than just two?
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8433
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The chip is capable of generating an interrupt from all of the IO pins, however it looks like only those on pins 2 and 3 have been implemented.

I may be wrong as I just started looking at the code 20 minutes ago but so far that's how it looks to me.

EDIT: I delved a bit deeper, it looks like there is allowance for 8 external interrupts. The docs are probably cut and pasted from another board, maybe they are wrong.

Actually I can't see any mention of interrupts at all on the product page.

_____
Rob
« Last Edit: October 22, 2012, 02:16:46 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 22
Posts: 291
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually interrupt*() functions are not implemented yet.

Sorry for that guys, but we didn't had the time to implement it on time for launch, this is one of our high priority for the next 1.5.1, that will be released ASAP.

Graynomad's description of interrupt capabilities is very accurate, but the current Arduino API (that we are going to implement) cannot be used to exploit all of them. An API update should be taken into account, but this is food for discussion on the developer's list on the coming weeks, for now we must stick to the current 1.0 API.

C

Logged

C.

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 22
Posts: 291
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Just pushed attach and detach interrupt functions

https://github.com/arduino/Arduino/commit/921dfe794f16aa282fd354997b847a7bfc92e233

i've tested the basic functionality and it seems working fine.
The actual interrupt/pin mapping is:

0 => pin 2
1 => pin 3
2 => pin 4
3 => pin 5
4 => pin 6
5 => pin 7
6 => pin 8

Note: this pin mapping is for testing purpose only. The final pin mapping will be different.

the available modes are
CHANGING, RISING, FALLING, HIGH, LOW
Logged

C.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8433
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
this pin mapping is for testing purpose only. The final pin mapping will be different.
By the time I get a Due it will be cast in stone smiley-sad

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Indeed I think he will have it all done before the Due actually gets out to the customers.   

Thanks for keeping us in the loop over the progress.  Looking forward to playing around with it.
Logged

Portland, OR
Offline Offline
Sr. Member
****
Karma: 5
Posts: 260
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for keeping us in the loop over the progress.

Yes, thanks @cmaglie and @Massimo for keeping us informed on the various things -- I've noticed you guys have been monitoring the Due forum with good frequency since the release.
Logged

Forum Administrator
Offline Offline
God Member
*****
Karma: 47
Posts: 629
I find plain exciting
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@giantsfan3

Thank you smiley
Logged

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 22
Posts: 291
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


@graynomad: in the end there will be no mapping at all..

https://github.com/arduino/Arduino/commit/0f23634230617dbce6dd4c670d6a88b9a02dee05

With the Due board you must use the attachInterrupt directly with the pin number:

attachInterrupt(pin, callback, mode)

for example:
attachInterrupt(9, myfunction, RISING);   //  RISING edge on pin 9 => calls myfunction

There is no limit on the number of interrupt that can be defined.  (Yes, you can setup a different interrupt function for each pin)

attachInterrupt() will be available again with Arduino IDE 1.5.1 (released on Nov, 5)

C
Logged

C.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8433
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, good that you're using all the interrupts.

I'll be interested to look at the code and see how it compares with my LPC version.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 22
Posts: 291
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Graynomad here the source code:

https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/cores/arduino/WInterrupts.c

There is an inner loop inside the interrupt handler, I've not optimized it yet really, but the response time should be <2uS.

If you have any suggestion on how to improve it you're welcome!

C
Logged

C.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8433
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like we've essentially done the same thing, I guess there's only so many ways to skin this particular cat

Code:
/////////////////////////////////////////////////////////////////////
//
// Function name: PIOINTx_IRQHandler
//
// Description: Replacement for the default PORT0 interrupt handler.
//
// Parameters: none
//
// Returned value: none
//
// Errors raised: none
//
// Notes: The code has to determine the pin that caused the interrupt.
// This is done by scanning the value in the MIS register
// looking for a 1 bit. When found the corresponding user handler
// is called if it exists.
//
// Whether or not the user handler exists the interrupt is cleared.
//
// Only a single interrupt at a time is called so an active pin
// cannot hog the system. This is implemented by maintaining a
// counter across invocations so for example if pin 4 is handled
// this time the scan starts from pin 5 next time.
//
// This method however has a side effect of increasing the latency
// considerably in systems that only have 1 or 2 external interrupts,
// for example after handling a pin 4 interrupt the next invocation
// has to scan 31 bits before arriving back at pin 4.
//
// This is largely reduced by writing 0 to the __force_interrupt_scan
// variable. In this case the next scan starts from the pin the
// last scan ended on.
//
// TODO: Implement a scan range to further reduce latency.
//
// Example:
//
void PIOINT0_IRQHandler() {

static uint8 pin = 0;

ATOMIC_START;

uint8 x = PINS_ON_PORT0;
uint32 misVal = LPC_GPIO0->MIS; // get the masked interrupt flags for this port

do {
if (misVal & 1) {
////////////////////////////////////////////////
// Check for a user-defined handler, if one exists
// then call it, clear the interrupt, increment the
// pin counter and exit
if (eventFunctions[EVENT_PININT_0 + pin] != NULL) {
(eventFunctions[EVENT_PININT_0 + pin]) ();
pinClearInterrupt(pin);
pin = (pin > PINS_ON_PORT0 ? 0 : pin + __force_interrupt_scan);
ATOMIC_END;
return;
}
/////////////////////////////////////////////////
// Clear the interrupt, if no user handler was called
// the interrupt is lost.
pinClearInterrupt(pin);
}
pin = (pin > PINS_ON_PORT0 ? 0 : pin +1);
misVal >>= 1;
} while (--x);

ATOMIC_END;
}

One difference is that I only allow the servicing of one interrupt per invocation, I'm not convinced that a good idea or not yet smiley

There's a big difference in our attachInterrupt() functions though

Code:
void attachInterrupt (uint8_t pin, void (*func)(void), int mode) {

switch (mode) {

case LOW:
pinSetInterruptMode(pin, PININT_LOW_LEVEL);
break;

case CHANGE:
pinSetInterruptMode(pin, PININT_BOTH_EDGES);
break;

case FALLING:
pinSetInterruptMode(pin, PININT_FALLING_EDGE);
break;

case RISING:
pinSetInterruptMode(pin, PININT_RISING_EDGE);
break;

}

attachEventHandler(EVENT_PININT_0 + pin, func);
pinEnableInterrupt(pin);

}

Although I suspect that if I inserted the code from the function calls they would be similar. Note that this is a function that's part of my Arduino port, it maps the Arduino call to my LPC equivalent, that's really why there's no real work done here.

I work with a flat model of the pins, at this level I don't care what port they are on or anything. Also I'm implementing a system of "events" whereby everything that happens on the system is an event that can have a user function supplied if required. Pin interrupts are simply another 55 events.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Pages: [1]   Go Up
Jump to: