-
-
Notifications
You must be signed in to change notification settings - Fork 740
solve issue #199, improve issue #200 in Winterrupts #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
22181b5
b53f8b6
27eb6b3
4436dcd
a1ff112
0c4ffdd
1be5cf0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,12 +21,17 @@ | |
|
|
||
| #include <string.h> | ||
|
|
||
| static voidFuncPtr callbacksInt[EXTERNAL_NUM_INTERRUPTS]; | ||
| static voidFuncPtr ISRcallback[EXTERNAL_NUM_INTERRUPTS]; | ||
| static EExt_Interrupts ISRlist[EXTERNAL_NUM_INTERRUPTS]; | ||
| static uint32_t nints; //stores total nr of attached interrupts | ||
|
|
||
|
|
||
| /* Configure I/O interrupt sources */ | ||
| static void __initialize() | ||
| { | ||
| memset(callbacksInt, 0, sizeof(callbacksInt)); | ||
| memset(ISRlist, 0, sizeof(ISRlist)); | ||
| memset(ISRcallback, 0, sizeof(ISRcallback)); | ||
| nints=0; | ||
|
|
||
| NVIC_DisableIRQ(EIC_IRQn); | ||
| NVIC_ClearPendingIRQ(EIC_IRQn); | ||
|
|
@@ -76,41 +81,64 @@ void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode) | |
| // Assign pin to EIC | ||
| pinPeripheral(pin, PIO_EXTINT); | ||
|
|
||
| // Assign callback to interrupt | ||
| callbacksInt[in] = callback; | ||
| if (callback){ //only store when there is really an ISR to call | ||
| //this allow for calling attachInterrupt(pin, NULL, mode), we set up all needed register | ||
| //but won't service the interrupt, this way we also don't need to check it inside the ISR | ||
|
|
||
| // Store interrupts to service in order of when they were attached | ||
| // to allow for first come first serve handler | ||
| uint32_t current=0; | ||
| //check if we already have this interrupt | ||
| int id=-1; | ||
| for (uint32_t i=0; i<nints; i++){ | ||
| if (ISRlist[i]==in) id=in; | ||
| } | ||
|
|
||
| // Look for right CONFIG register to be addressed | ||
| if (in > EXTERNAL_INT_7) { | ||
| config = 1; | ||
| } else { | ||
| config = 0; | ||
| } | ||
| if (id==-1){ | ||
| //need to make a new entry | ||
| current=nints; | ||
| nints++; | ||
| } | ||
| else{ | ||
| //we already have an entry for this pin | ||
| current=id; | ||
| } | ||
| ISRlist[current]=in; //list with nr of interrupt in order of when they were attached | ||
| ISRcallback[current]=callback; //list of callback adresses | ||
|
|
||
| // Look for right CONFIG register to be addressed | ||
| if (in > EXTERNAL_INT_7) { | ||
| config = 1; | ||
| } else { | ||
| config = 0; | ||
| } | ||
|
|
||
| // Configure the interrupt mode | ||
| pos = (in - (8 * config)) << 2; | ||
| switch (mode) | ||
| { | ||
| case LOW: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_LOW_Val << pos; | ||
| break; | ||
|
|
||
| case HIGH: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_HIGH_Val << pos; | ||
| break; | ||
|
|
||
| case CHANGE: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_BOTH_Val << pos; | ||
| break; | ||
|
|
||
| case FALLING: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_FALL_Val << pos; | ||
| break; | ||
|
|
||
| case RISING: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_RISE_Val << pos; | ||
| break; | ||
| } | ||
| // Configure the interrupt mode | ||
| pos = (in - (8 * config)) << 2; | ||
| EIC->CONFIG[config].reg &=~ (EIC_CONFIG_SENSE0_Msk << pos);//reset sense mode, important when changing trigger mode during runtime | ||
| switch (mode) | ||
| { | ||
| case LOW: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_LOW_Val << pos; | ||
| break; | ||
|
|
||
| case HIGH: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_HIGH_Val << pos; | ||
| break; | ||
|
|
||
| case CHANGE: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_BOTH_Val << pos; | ||
| break; | ||
|
|
||
| case FALLING: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_FALL_Val << pos; | ||
| break; | ||
|
|
||
| case RISING: | ||
| EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_RISE_Val << pos; | ||
| break; | ||
| } | ||
| } | ||
| // Enable the interrupt | ||
| EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << in); | ||
| } | ||
|
|
@@ -132,25 +160,37 @@ void detachInterrupt(uint32_t pin) | |
|
|
||
| // Disable wakeup capability on pin during sleep | ||
| EIC->WAKEUP.reg &= ~(1 << in); | ||
|
|
||
| //and take it out of the ISR list | ||
| int id=-1; //find its location first | ||
| for (uint32_t i=0; i<nints; i++){ | ||
| if (ISRlist[i]==in) id=in; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here it too should be |
||
| } | ||
| if (id==-1) return; //apparently we didn't have it | ||
| for (uint32_t i=id; i<nints-1; i++){ //and shift the ones above one down | ||
| ISRlist[i]=ISRlist[i+1]; | ||
| ISRcallback[i]=ISRcallback[i+1]; | ||
| } | ||
| //and remove the top item | ||
| ISRlist[nints]=0; | ||
| ISRcallback[nints]=NULL; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is erasing the list element really needed? IMHO just decreasing |
||
| nints--; | ||
| } | ||
|
|
||
| /* | ||
| * External Interrupt Controller NVIC Interrupt Handler | ||
| */ | ||
| void EIC_Handler(void) | ||
| { | ||
| // Test the 16 normal interrupts | ||
| for (uint32_t i=EXTERNAL_INT_0; i<=EXTERNAL_INT_15; i++) | ||
| { | ||
| if ((EIC->INTFLAG.reg & (1 << i)) != 0) | ||
| { | ||
| // Call the callback function if assigned | ||
| if (callbacksInt[i]) { | ||
| callbacksInt[i](); | ||
| } | ||
|
|
||
| // Clear the interrupt | ||
| EIC->INTFLAG.reg = 1 << i; | ||
| //calling the routine directly from -here- takes about 1us | ||
| //depending on where you are in the list it will take longer | ||
| for (uint32_t i=0; i<nints; i++) // Loop over all enabled interrupts in the list | ||
| { | ||
| if ((EIC->INTFLAG.reg & 1<<ISRlist[i]) != 0) | ||
| { | ||
| ISRcallback[i]();// Call the callback function if assigned | ||
| EIC->INTFLAG.reg = 1<<ISRlist[i]; // Clear the interrupt | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we can gain something if we store |
||
| } | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition here should be
id = iI guess?