From 6b2700e2b1a03b7e0191f3dd9b34f8c51eea3c84 Mon Sep 17 00:00:00 2001 From: Aditya Gaddam Date: Fri, 31 Aug 2012 14:19:57 -0400 Subject: "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 " --- libmaple/exti.c | 110 ++++++++++++++++++++++------- libmaple/include/libmaple/exti.h | 5 ++ libmaple/include/libmaple/libmaple_types.h | 1 + 3 files changed, 92 insertions(+), 24 deletions(-) (limited to 'libmaple') 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"))) -- cgit v1.2.3