aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAditya Gaddam <adityagaddam@gmail.com>2012-08-31 14:19:57 -0400
committerAditya Gaddam <adityagaddam@gmail.com>2012-08-31 14:19:57 -0400
commit6b2700e2b1a03b7e0191f3dd9b34f8c51eea3c84 (patch)
tree5693873124e4ac1f4a9c311f859fe6bce0f64d24
parente98633a041cfc9d5ba9122951aad65dcc4e33012 (diff)
downloadlibrambutan-6b2700e2b1a03b7e0191f3dd9b34f8c51eea3c84.tar.gz
librambutan-6b2700e2b1a03b7e0191f3dd9b34f8c51eea3c84.zip
"Added ability to set callbacks for interrupts that get an argument. This argument can be the instance that needs to handle the interrupt, or just a random argument you might find useful later. Suggestions from mbolivar and iperry from pull53 on libmaple were taken into account.
Signed-off-by: Aditya Gaddam <adityagaddam@gmail.com>"
-rw-r--r--libmaple/exti.c110
-rw-r--r--libmaple/include/libmaple/exti.h5
-rw-r--r--libmaple/include/libmaple/libmaple_types.h1
-rw-r--r--wirish/ext_interrupts.cpp28
-rw-r--r--wirish/include/wirish/ext_interrupts.h21
5 files changed, 141 insertions, 24 deletions
diff --git a/libmaple/exti.c b/libmaple/exti.c
index 9023782..b620c77 100644
--- a/libmaple/exti.c
+++ b/libmaple/exti.c
@@ -43,27 +43,27 @@ static inline void dispatch_extis(uint32 start, uint32 stop);
*/
typedef struct exti_channel {
- void (*handler)(void);
- uint32 irq_line;
+ void (*handler)(void *);
+ void *arg;
} exti_channel;
static exti_channel exti_channels[] = {
- { .handler = NULL, .irq_line = NVIC_EXTI0 }, // EXTI0
- { .handler = NULL, .irq_line = NVIC_EXTI1 }, // EXTI1
- { .handler = NULL, .irq_line = NVIC_EXTI2 }, // EXTI2
- { .handler = NULL, .irq_line = NVIC_EXTI3 }, // EXTI3
- { .handler = NULL, .irq_line = NVIC_EXTI4 }, // EXTI4
- { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI5
- { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI6
- { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI7
- { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI8
- { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI9
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI10
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI11
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI12
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI13
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI14
- { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI15
+ { .handler = NULL, .arg = NULL }, // EXTI0
+ { .handler = NULL, .arg = NULL }, // EXTI1
+ { .handler = NULL, .arg = NULL }, // EXTI2
+ { .handler = NULL, .arg = NULL }, // EXTI3
+ { .handler = NULL, .arg = NULL }, // EXTI4
+ { .handler = NULL, .arg = NULL }, // EXTI5
+ { .handler = NULL, .arg = NULL }, // EXTI6
+ { .handler = NULL, .arg = NULL }, // EXTI7
+ { .handler = NULL, .arg = NULL }, // EXTI8
+ { .handler = NULL, .arg = NULL }, // EXTI9
+ { .handler = NULL, .arg = NULL }, // EXTI10
+ { .handler = NULL, .arg = NULL }, // EXTI11
+ { .handler = NULL, .arg = NULL }, // EXTI12
+ { .handler = NULL, .arg = NULL }, // EXTI13
+ { .handler = NULL, .arg = NULL }, // EXTI14
+ { .handler = NULL, .arg = NULL }, // EXTI15
};
/*
@@ -90,10 +90,39 @@ void exti_attach_interrupt(exti_num num,
exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode) {
+
+ // Call callback version with arg being null
+ exti_attach_callback(num, port, handler, NULL, mode);
+}
+
+/**
+ * @brief Register a handler with an argument to run upon external interrupt.
+ *
+ * This function assumes that the interrupt request corresponding to
+ * the given external interrupt is masked.
+ *
+ * @param num External interrupt line number.
+ * @param port Port to use as source input for external interrupt.
+ * @param handler Function handler to execute when interrupt is triggered.
+ * @param arg Argument to pass to the interrupt handler.
+ * @param mode Type of transition to trigger on, one of:
+ * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
+ * @see exti_num
+ * @see exti_cfg
+ * @see voidFuncPtr
+ * @see exti_trigger_mode
+ */
+void exti_attach_callback(exti_num num,
+ exti_cfg port,
+ voidFuncPtr handler,
+ void *arg,
+ exti_trigger_mode mode) {
+
ASSERT(handler);
/* Register the handler */
- exti_channels[num].handler = handler;
+ exti_channels[num].handler = (voidArgumentFuncPtr)handler;
+ exti_channels[num].arg = arg;
/* Set trigger mode */
switch (mode) {
@@ -116,7 +145,39 @@ void exti_attach_interrupt(exti_num num,
bb_peri_set_bit(&EXTI_BASE->IMR, num, 1);
/* Enable the interrupt line */
- nvic_irq_enable(exti_channels[num].irq_line);
+ switch(num)
+ {
+ case 0:
+ nvic_irq_enable(NVIC_EXTI0);
+ break;
+ case 1:
+ nvic_irq_enable(NVIC_EXTI1);
+ break;
+ case 2:
+ nvic_irq_enable(NVIC_EXTI2);
+ break;
+ case 3:
+ nvic_irq_enable(NVIC_EXTI3);
+ break;
+ case 4:
+ nvic_irq_enable(NVIC_EXTI4);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ nvic_irq_enable(NVIC_EXTI_9_5);
+ break;
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ nvic_irq_enable(NVIC_EXTI_15_10);
+ break;
+ }
}
/**
@@ -134,6 +195,7 @@ void exti_detach_interrupt(exti_num num) {
/* Finally, unregister the user's handler */
exti_channels[num].handler = NULL;
+ exti_channels[num].arg = NULL;
}
/*
@@ -199,13 +261,13 @@ static __always_inline void clear_pending_msk(uint32 exti_msk) {
/* This dispatch routine is for non-multiplexed EXTI lines only; i.e.,
* it doesn't check EXTI_PR. */
static __always_inline void dispatch_single_exti(uint32 exti) {
- voidFuncPtr handler = exti_channels[exti].handler;
+ voidArgumentFuncPtr handler = exti_channels[exti].handler;
if (!handler) {
return;
}
- handler();
+ handler(exti_channels[exti].arg);
clear_pending_msk(1U << exti);
}
@@ -219,9 +281,9 @@ static __always_inline void dispatch_extis(uint32 start, uint32 stop) {
for (exti = start; exti <= stop; exti++) {
uint32 eb = (1U << exti);
if (pr & eb) {
- voidFuncPtr handler = exti_channels[exti].handler;
+ voidArgumentFuncPtr handler = exti_channels[exti].handler;
if (handler) {
- handler();
+ handler(exti_channels[exti].arg);
handled_msk |= eb;
}
}
diff --git a/libmaple/include/libmaple/exti.h b/libmaple/include/libmaple/exti.h
index 3800b4a..530b442 100644
--- a/libmaple/include/libmaple/exti.h
+++ b/libmaple/include/libmaple/exti.h
@@ -115,6 +115,11 @@ void exti_attach_interrupt(exti_num num,
exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode);
+void exti_attach_callback(exti_num num,
+ exti_cfg port,
+ voidFuncPtr handler,
+ void *arg,
+ exti_trigger_mode mode);
void exti_detach_interrupt(exti_num num);
/**
diff --git a/libmaple/include/libmaple/libmaple_types.h b/libmaple/include/libmaple/libmaple_types.h
index 9e1fbb3..60dd2ff 100644
--- a/libmaple/include/libmaple/libmaple_types.h
+++ b/libmaple/include/libmaple/libmaple_types.h
@@ -48,6 +48,7 @@ typedef int int32;
typedef long long int64;
typedef void (*voidFuncPtr)(void);
+typedef void (*voidArgumentFuncPtr)(void *);
#define __io volatile
#define __attr_flash __attribute__((section (".USER_FLASH")))
diff --git a/wirish/ext_interrupts.cpp b/wirish/ext_interrupts.cpp
index a3e61fd..f72efbf 100644
--- a/wirish/ext_interrupts.cpp
+++ b/wirish/ext_interrupts.cpp
@@ -60,6 +60,34 @@ void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) {
}
/**
+ * @brief Registers an interrupt handler on a pin.
+ *
+ * @param pin Pin number
+ * @param handler Static class member function to run upon external interrupt
+ * trigger. The handler should take 1 argument and return void
+ * @param arg Argument that the handler will be passed when it's called. One
+ * use of this is to pass the specific instance of the class that
+ * will handle the interrupt.
+ * @param mode Type of transition to trigger on, e.g. falling, rising, etc.
+ *
+ * @sideeffect Registers a handler
+ * @see detachInterrupt()
+ */
+void attachInterrupt(uint8 pin, voidFuncPtr handler, void *arg, ExtIntTriggerMode mode) {
+ if (pin >= BOARD_NR_GPIO_PINS || !handler) {
+ return;
+ }
+
+ exti_trigger_mode outMode = exti_out_mode(mode);
+
+ exti_attach_callback((exti_num)(PIN_MAP[pin].gpio_bit),
+ gpio_exti_port(PIN_MAP[pin].gpio_device),
+ handler,
+ arg,
+ outMode);
+}
+
+/**
* @brief Disable any external interrupt attached to a pin.
* @param pin Pin number to detach any interrupt from.
*/
diff --git a/wirish/include/wirish/ext_interrupts.h b/wirish/include/wirish/ext_interrupts.h
index 933be04..1bd7956 100644
--- a/wirish/include/wirish/ext_interrupts.h
+++ b/wirish/include/wirish/ext_interrupts.h
@@ -69,6 +69,27 @@ typedef enum ExtIntTriggerMode {
void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode);
/**
+ * @brief Registers an interrupt handler on a pin.
+ *
+ * The interrupt will be triggered on a given transition on the pin,
+ * as specified by the mode parameter. The handler runs in interrupt
+ * context. The new handler will replace whatever handler is
+ * currently registered for the pin, if any.
+ *
+ * @param pin Pin number
+ * @param handler Static class member function to run upon external interrupt
+ * trigger. The handler should take 1 argument and return void
+ * @param arg Argument that the handler will be passed when it's called. One
+ * use of this is to pass the specific instance of the class that
+ * will handle the interrupt.
+ * @param mode Type of transition to trigger on, e.g. falling, rising, etc.
+ *
+ * @sideeffect Registers a handler
+ * @see detachInterrupt()
+ */
+void attachInterrupt(uint8 pin, voidFuncPtr handler, void *arg, ExtIntTriggerMode mode);
+
+/**
* @brief Disable any registered external interrupt.
* @param pin Maple pin number
* @sideeffect unregisters external interrupt handler