aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/exti.c
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-26 18:24:49 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-26 18:32:57 -0400
commitf005bd3a5c087e3d5559f2858a1e7898a4f92a8d (patch)
tree0701628a68056f7b5f92d5a5af5f281f58e6a71e /libmaple/exti.c
parent761e059962e8f53f3cceef61d65bf2bf3025319a (diff)
parentc6073e4886da4606679bc3e9d770c9cff9390597 (diff)
downloadlibrambutan-f005bd3a5c087e3d5559f2858a1e7898a4f92a8d.tar.gz
librambutan-f005bd3a5c087e3d5559f2858a1e7898a4f92a8d.zip
Merge branch 'wip-family-support'
Merge the long-lived (too long; future changes like these will need to proceed more incrementally) development branch of libmaple, containing experimental STM32F2 and STM32F1 value line support, into master. This required many changes to the structure of the library. The most important structural reorganizations occurred in: - 954f9e5: moves public headers to include directories - 3efa313: uses "series" instead of "family" - c0d60e3: adds board files to the build system, to make it easier to add new boards - 096d86c: adds build logic for targeting different STM32 series (e.g. STM32F1, STM32F2) This last commit in particular (096d86c) is the basis for the repartitioning of libmaple into portable sections, which work on all supported MCUs, and nonportable sections, which are segregated into separate directories and contain all series-specific code. Moving existing STM32F1-only code into libmaple/stm32f1 and wirish/stm32f1, along with adding equivalents under .../stm32f2 directories, was the principal project of this branch. Important API changes occur in several places. Existing code is still expected to work on STM32F1 targets, but there have been many deprecations. A detailed changelog explaining the situation needs to be prepared. F2 and F1 value line support is not complete; the merge is proceeding prematurely in this respect. We've been getting more libmaple patches from the community lately, and I'm worried that the merge conflicts with the old tree structure will become painful to manage. Conflicts: Makefile Resolved Makefile conflicts manually; this required propagating -Xlinker usage into support/make/target-config.mk. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'libmaple/exti.c')
-rw-r--r--libmaple/exti.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/libmaple/exti.c b/libmaple/exti.c
index 1fcc35b..9023782 100644
--- a/libmaple/exti.c
+++ b/libmaple/exti.c
@@ -2,6 +2,7 @@
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -25,14 +26,14 @@
*****************************************************************************/
/**
- * @file exti.c
+ * @file libmaple/exti.c
* @brief External interrupt control routines
*/
-#include "exti.h"
-#include "libmaple.h"
-#include "nvic.h"
-#include "bitband.h"
+#include <libmaple/exti.h>
+#include <libmaple/libmaple.h>
+#include <libmaple/nvic.h>
+#include <libmaple/bitband.h>
static inline void dispatch_single_exti(uint32 exti_num);
static inline void dispatch_extis(uint32 start, uint32 stop);
@@ -66,7 +67,7 @@ static exti_channel exti_channels[] = {
};
/*
- * Convenience routines
+ * Portable routines
*/
/**
@@ -80,13 +81,13 @@ static exti_channel exti_channels[] = {
* @param handler Function handler to execute when interrupt is triggered.
* @param mode Type of transition to trigger on, one of:
* EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
- * @see afio_exti_num
- * @see afio_exti_port
+ * @see exti_num
+ * @see exti_cfg
* @see voidFuncPtr
* @see exti_trigger_mode
*/
-void exti_attach_interrupt(afio_exti_num num,
- afio_exti_port port,
+void exti_attach_interrupt(exti_num num,
+ exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode) {
ASSERT(handler);
@@ -108,8 +109,8 @@ void exti_attach_interrupt(afio_exti_num num,
break;
}
- /* Map num to port */
- afio_exti_select(num, port);
+ /* Use the chip-specific exti_select() to map num to port */
+ exti_select(num, port);
/* Unmask external interrupt request */
bb_peri_set_bit(&EXTI_BASE->IMR, num, 1);
@@ -120,10 +121,10 @@ void exti_attach_interrupt(afio_exti_num num,
/**
* @brief Unregister an external interrupt handler
- * @param num Number of the external interrupt line to disable.
- * @see afio_exti_num
+ * @param num External interrupt line to disable.
+ * @see exti_num
*/
-void exti_detach_interrupt(afio_exti_num num) {
+void exti_detach_interrupt(exti_num num) {
/* First, mask the interrupt request */
bb_peri_set_bit(&EXTI_BASE->IMR, num, 0);
@@ -136,27 +137,39 @@ void exti_detach_interrupt(afio_exti_num num) {
}
/*
+ * Private routines
+ */
+
+void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) {
+ uint32 shift = 4 * (num % 4);
+ uint32 cr = *exti_cr;
+ cr &= ~(0xF << shift);
+ cr |= port << shift;
+ *exti_cr = cr;
+}
+
+/*
* Interrupt handlers
*/
void __irq_exti0(void) {
- dispatch_single_exti(AFIO_EXTI_0);
+ dispatch_single_exti(EXTI0);
}
void __irq_exti1(void) {
- dispatch_single_exti(AFIO_EXTI_1);
+ dispatch_single_exti(EXTI1);
}
void __irq_exti2(void) {
- dispatch_single_exti(AFIO_EXTI_2);
+ dispatch_single_exti(EXTI2);
}
void __irq_exti3(void) {
- dispatch_single_exti(AFIO_EXTI_3);
+ dispatch_single_exti(EXTI3);
}
void __irq_exti4(void) {
- dispatch_single_exti(AFIO_EXTI_4);
+ dispatch_single_exti(EXTI4);
}
void __irq_exti9_5(void) {
@@ -177,7 +190,7 @@ void __irq_exti15_10(void) {
* won't actually be cleared in time and the ISR will fire again. To
* compensate, this function NOPs for 2 cycles after clearing the
* pending bits to ensure it takes effect. */
-static inline void clear_pending_msk(uint32 exti_msk) {
+static __always_inline void clear_pending_msk(uint32 exti_msk) {
EXTI_BASE->PR = exti_msk;
asm volatile("nop");
asm volatile("nop");
@@ -185,7 +198,7 @@ static 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 inline void dispatch_single_exti(uint32 exti) {
+static __always_inline void dispatch_single_exti(uint32 exti) {
voidFuncPtr handler = exti_channels[exti].handler;
if (!handler) {
@@ -193,18 +206,18 @@ static inline void dispatch_single_exti(uint32 exti) {
}
handler();
- clear_pending_msk(BIT(exti));
+ clear_pending_msk(1U << exti);
}
/* Dispatch routine for EXTIs which share an IRQ. */
-static inline void dispatch_extis(uint32 start, uint32 stop) {
+static __always_inline void dispatch_extis(uint32 start, uint32 stop) {
uint32 pr = EXTI_BASE->PR;
uint32 handled_msk = 0;
uint32 exti;
/* Dispatch user handlers for pending EXTIs. */
for (exti = start; exti <= stop; exti++) {
- uint32 eb = BIT(exti);
+ uint32 eb = (1U << exti);
if (pr & eb) {
voidFuncPtr handler = exti_channels[exti].handler;
if (handler) {