aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/exti.c58
-rw-r--r--libmaple/exti_private.h34
-rw-r--r--libmaple/include/libmaple/exti.h78
-rw-r--r--libmaple/include/libmaple/gpio.h41
-rw-r--r--libmaple/rules.mk2
-rw-r--r--libmaple/stm32f1/exti.c32
-rw-r--r--libmaple/stm32f1/gpio.c36
-rw-r--r--libmaple/stm32f1/include/series/gpio.h215
-rw-r--r--libmaple/stm32f1/rules.mk1
-rw-r--r--libmaple/stm32f2/gpio.c9
-rw-r--r--libmaple/stm32f2/include/series/gpio.h54
11 files changed, 372 insertions, 188 deletions
diff --git a/libmaple/exti.c b/libmaple/exti.c
index 248c4b6..d84b789 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
@@ -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);
@@ -135,28 +136,45 @@ void exti_detach_interrupt(afio_exti_num num) {
exti_channels[num].handler = NULL;
}
+/* Weak default exti_select(), until we get F2 support */
+__weak void exti_select(exti_num num, exti_cfg port) {
+ ASSERT(0);
+}
+
+/*
+ * 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 +195,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 +203,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 +211,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) {
diff --git a/libmaple/exti_private.h b/libmaple/exti_private.h
new file mode 100644
index 0000000..4f0a4cf
--- /dev/null
+++ b/libmaple/exti_private.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*****************************************************************************/
+
+#ifndef _LIBMAPLE_EXTI_PRIVATE_H_
+#define _LIBMAPLE_EXTI_PRIVATE_H_
+
+#include <libmaple/exti.h>
+
+void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port);
+
+#endif
diff --git a/libmaple/include/libmaple/exti.h b/libmaple/include/libmaple/exti.h
index d7bfe51..5259a44 100644
--- a/libmaple/include/libmaple/exti.h
+++ b/libmaple/include/libmaple/exti.h
@@ -26,7 +26,7 @@
/**
* @file libmaple/include/libmaple/exti.h
- * @brief External interrupt control prototypes and defines
+ * @brief External interrupt control
*/
/* See notes/exti.txt for more info */
@@ -38,8 +38,11 @@
extern "C"{
#endif
-#include <libmaple/libmaple.h>
-#include <libmaple/gpio.h>
+#include <libmaple/libmaple_types.h>
+
+/*
+ * Register map and base pointer.
+ */
/** EXTI register map type */
typedef struct exti_reg_map {
@@ -54,6 +57,51 @@ typedef struct exti_reg_map {
/** EXTI register map base pointer */
#define EXTI_BASE ((struct exti_reg_map*)0x40010400)
+/*
+ * Types: exti_num, exti_cfg, exti_trigger_mode.
+ *
+ * A combination of these three specifies an external interrupt
+ * configuration (see exti_attach_interrupt()).
+ */
+
+/** EXTI line. */
+typedef enum exti_num {
+ EXTI0, /**< EXTI line 0 */
+ EXTI1, /**< EXTI line 1 */
+ EXTI2, /**< EXTI line 2 */
+ EXTI3, /**< EXTI line 3 */
+ EXTI4, /**< EXTI line 4 */
+ EXTI5, /**< EXTI line 5 */
+ EXTI6, /**< EXTI line 6 */
+ EXTI7, /**< EXTI line 7 */
+ EXTI8, /**< EXTI line 8 */
+ EXTI9, /**< EXTI line 9 */
+ EXTI10, /**< EXTI line 10 */
+ EXTI11, /**< EXTI line 11 */
+ EXTI12, /**< EXTI line 12 */
+ EXTI13, /**< EXTI line 13 */
+ EXTI14, /**< EXTI line 14 */
+ EXTI15, /**< EXTI line 15 */
+} exti_num;
+
+/**
+ * @brief EXTI port configuration
+ *
+ * These specify which GPIO port an external interrupt line should be
+ * connected to.
+ */
+typedef enum exti_cfg {
+ EXTI_PA, /**< Use PAx pin */
+ EXTI_PB, /**< Use PBx pin */
+ EXTI_PC, /**< Use PCx pin */
+ EXTI_PD, /**< Use PDx pin */
+ EXTI_PE, /**< Use PEx pin */
+ EXTI_PF, /**< Use PFx pin */
+ EXTI_PG, /**< Use PGx pin */
+ EXTI_PH, /**< Use PHx pin */
+ EXTI_PI, /**< Use PIx pin */
+} exti_cfg;
+
/** External interrupt trigger mode */
typedef enum exti_trigger_mode {
EXTI_RISING, /**< Trigger on the rising edge */
@@ -61,11 +109,29 @@ typedef enum exti_trigger_mode {
EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */
} exti_trigger_mode;
-void exti_attach_interrupt(afio_exti_num num,
- afio_exti_port port,
+/*
+ * Routines
+ */
+
+void exti_attach_interrupt(exti_num num,
+ exti_cfg port,
voidFuncPtr handler,
exti_trigger_mode mode);
-void exti_detach_interrupt(afio_exti_num num);
+void exti_detach_interrupt(exti_num num);
+
+/**
+ * @brief Set the GPIO port for an EXTI line.
+ *
+ * This is a low-level routine that most users will not
+ * need. exti_attach_interrupt() handles calling this function
+ * appropriately.
+ *
+ * @param num EXTI line
+ * @param port EXTI configuration for GPIO port to connect to num.
+ * @see exti_num
+ * @see exti_cfg
+ */
+extern void exti_select(exti_num num, exti_cfg port);
#ifdef __cplusplus
} // extern "C"
diff --git a/libmaple/include/libmaple/gpio.h b/libmaple/include/libmaple/gpio.h
index ca7b2bf..0cc3746 100644
--- a/libmaple/include/libmaple/gpio.h
+++ b/libmaple/include/libmaple/gpio.h
@@ -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
@@ -38,22 +39,46 @@ extern "C"{
/*
* Note: Series header must define:
- * - struct gpio_dev (and declare extern pointers to series-provided ones)
- * - enum gpio_pin_mode (TODO think hard on this)
+ * - enum gpio_pin_mode (TODO think harder about portability here)
*/
#include <series/gpio.h>
-#include <libmaple/libmaple.h>
+#include <libmaple/libmaple_types.h>
+#include <libmaple/rcc.h>
+#include <libmaple/exti.h>
/*
- * GPIO Convenience routines
+ * Device type
+ */
+
+/** GPIO device type */
+typedef struct gpio_dev {
+ gpio_reg_map *regs; /**< Register map */
+ rcc_clk_id clk_id; /**< RCC clock information */
+ /**
+ * @brief (Deprecated) External interrupt port.
+ * Instead of dev->exti_port, use gpio_exti_port(dev).
+ */
+ exti_cfg exti_port;
+} gpio_dev;
+
+/*
+ * Portable routines
*/
void gpio_init(gpio_dev *dev);
void gpio_init_all(void);
-/* TODO deprecate this? We should probably take a flags argument. */
+/* TODO flags argument version? */
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
/**
+ * @brief Get a GPIO port's corresponding EXTI port configuration.
+ * @param dev GPIO port whose exti_cfg to return.
+ */
+static inline exti_cfg gpio_exti_port(gpio_dev *dev) {
+ return (exti_cfg)(EXTI_PA + (dev->clk_id - RCC_GPIOA));
+}
+
+/**
* Set or reset a GPIO pin.
*
* Pin must have previously been configured to output mode.
@@ -64,7 +89,7 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
*/
static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
val = !val; /* "set" bits are lower than "reset" bits */
- dev->regs->BSRR = BIT(pin) << (16 * val);
+ dev->regs->BSRR = (1U << pin) << (16 * val);
}
/**
@@ -77,7 +102,7 @@ static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
* @return True if the pin is set, false otherwise.
*/
static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
- return dev->regs->IDR & BIT(pin);
+ return dev->regs->IDR & (1U << pin);
}
/**
@@ -86,7 +111,7 @@ static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
* @param pin Pin on dev to toggle.
*/
static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
- dev->regs->ODR = dev->regs->ODR ^ BIT(pin);
+ dev->regs->ODR = dev->regs->ODR ^ (1U << pin);
}
#ifdef __cplusplus
diff --git a/libmaple/rules.mk b/libmaple/rules.mk
index 5c63522..b39c318 100644
--- a/libmaple/rules.mk
+++ b/libmaple/rules.mk
@@ -13,6 +13,7 @@ CFLAGS_$(d) = $(LIBMAPLE_PRIVATE_INCLUDES) $(LIBMAPLE_INCLUDES) -Wall -Werror
# Local rules and targets
cSRCS_$(d) := adc.c
# cSRCS_$(d) += dma.c
+cSRCS_$(d) += exti.c
cSRCS_$(d) += flash.c
cSRCS_$(d) += gpio.c
cSRCS_$(d) += iwdg.c
@@ -28,7 +29,6 @@ cSRCS_$(d) += usart_private.c
cSRCS_$(d) += util.c
# These still need to be brought back for F1:
# cSRCS_$(d) += dac.c
-# cSRCS_$(d) += exti.c
# cSRCS_$(d) += i2c.c
sSRCS_$(d) := exc.S
diff --git a/libmaple/stm32f1/exti.c b/libmaple/stm32f1/exti.c
new file mode 100644
index 0000000..b9ff401
--- /dev/null
+++ b/libmaple/stm32f1/exti.c
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*****************************************************************************/
+
+#include <libmaple/gpio.h>
+#include "exti_private.h"
+
+void exti_select(exti_num num, exti_cfg port) {
+ exti_do_select(&AFIO_BASE->EXTICR1 + num / 4, num, port);
+}
diff --git a/libmaple/stm32f1/gpio.c b/libmaple/stm32f1/gpio.c
index 2cbe299..4b596e9 100644
--- a/libmaple/stm32f1/gpio.c
+++ b/libmaple/stm32f1/gpio.c
@@ -39,7 +39,7 @@
gpio_dev gpioa = {
.regs = GPIOA_BASE,
.clk_id = RCC_GPIOA,
- .exti_port = AFIO_EXTI_PA,
+ .exti_port = EXTI_PA,
};
/** GPIO port A device. */
gpio_dev* const GPIOA = &gpioa;
@@ -47,7 +47,7 @@ gpio_dev* const GPIOA = &gpioa;
gpio_dev gpiob = {
.regs = GPIOB_BASE,
.clk_id = RCC_GPIOB,
- .exti_port = AFIO_EXTI_PB,
+ .exti_port = EXTI_PB,
};
/** GPIO port B device. */
gpio_dev* const GPIOB = &gpiob;
@@ -55,7 +55,7 @@ gpio_dev* const GPIOB = &gpiob;
gpio_dev gpioc = {
.regs = GPIOC_BASE,
.clk_id = RCC_GPIOC,
- .exti_port = AFIO_EXTI_PC,
+ .exti_port = EXTI_PC,
};
/** GPIO port C device. */
gpio_dev* const GPIOC = &gpioc;
@@ -63,7 +63,7 @@ gpio_dev* const GPIOC = &gpioc;
gpio_dev gpiod = {
.regs = GPIOD_BASE,
.clk_id = RCC_GPIOD,
- .exti_port = AFIO_EXTI_PD,
+ .exti_port = EXTI_PD,
};
/** GPIO port D device. */
gpio_dev* const GPIOD = &gpiod;
@@ -72,7 +72,7 @@ gpio_dev* const GPIOD = &gpiod;
gpio_dev gpioe = {
.regs = GPIOE_BASE,
.clk_id = RCC_GPIOE,
- .exti_port = AFIO_EXTI_PE,
+ .exti_port = EXTI_PE,
};
/** GPIO port E device. */
gpio_dev* const GPIOE = &gpioe;
@@ -80,7 +80,7 @@ gpio_dev* const GPIOE = &gpioe;
gpio_dev gpiof = {
.regs = GPIOF_BASE,
.clk_id = RCC_GPIOF,
- .exti_port = AFIO_EXTI_PF,
+ .exti_port = EXTI_PF,
};
/** GPIO port F device. */
gpio_dev* const GPIOF = &gpiof;
@@ -88,7 +88,7 @@ gpio_dev* const GPIOF = &gpiof;
gpio_dev gpiog = {
.regs = GPIOG_BASE,
.clk_id = RCC_GPIOG,
- .exti_port = AFIO_EXTI_PG,
+ .exti_port = EXTI_PG,
};
/** GPIO port G device. */
gpio_dev* const GPIOG = &gpiog;
@@ -132,9 +132,9 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
*cr = tmp;
if (mode == GPIO_INPUT_PD) {
- regs->ODR &= ~BIT(pin);
+ regs->ODR &= ~(1U << pin);
} else if (mode == GPIO_INPUT_PU) {
- regs->ODR |= BIT(pin);
+ regs->ODR |= (1U << pin);
}
}
@@ -153,24 +153,6 @@ void afio_init(void) {
#define AFIO_EXTI_SEL_MASK 0xF
/**
- * @brief Select a source input for an external interrupt.
- *
- * @param exti External interrupt.
- * @param gpio_port Port which contains pin to use as source input.
- * @see afio_exti_num
- * @see afio_exti_port
- */
-void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
- __io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4;
- uint32 shift = 4 * (exti % 4);
- uint32 cr = *exti_cr;
-
- cr &= ~(AFIO_EXTI_SEL_MASK << shift);
- cr |= gpio_port << shift;
- *exti_cr = cr;
-}
-
-/**
* @brief Perform an alternate function remap.
* @param remapping Remapping to perform.
*/
diff --git a/libmaple/stm32f1/include/series/gpio.h b/libmaple/stm32f1/include/series/gpio.h
index 1f209fe..0ca6d56 100644
--- a/libmaple/stm32f1/include/series/gpio.h
+++ b/libmaple/stm32f1/include/series/gpio.h
@@ -2,7 +2,7 @@
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
- * Copyright (c) 2011 LeafLabs, LLC.
+ * 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
@@ -27,7 +27,7 @@
/**
* @file libmaple/stm32f1/include/series/gpio.h
- * @brief STM32F1 GPIO support.
+ * @brief STM32F1 GPIO and AFIO support.
*
* General purpose I/O (GPIO) and Alternate Function I/O (AFIO)
* prototypes, defines, and support functions.
@@ -40,8 +40,9 @@
extern "C"{
#endif
-#include <libmaple/libmaple.h>
-#include <libmaple/rcc.h>
+#include <libmaple/stm32.h>
+#include <libmaple/libmaple_types.h>
+#include <libmaple/exti.h>
/*
* GPIO register maps and devices
@@ -58,46 +59,22 @@ typedef struct gpio_reg_map {
__io uint32 LCKR; /**< Port configuration lock register */
} gpio_reg_map;
-/**
- * @brief External interrupt line port selector.
- *
- * Used to determine which GPIO port to map an external interrupt line
- * onto. */
-/* (See AFIO sections, below) */
-typedef enum afio_exti_port {
- AFIO_EXTI_PA, /**< Use port A (PAx) pin. */
- AFIO_EXTI_PB, /**< Use port B (PBx) pin. */
- AFIO_EXTI_PC, /**< Use port C (PCx) pin. */
- AFIO_EXTI_PD, /**< Use port D (PDx) pin. */
-#ifdef STM32_HIGH_DENSITY
- AFIO_EXTI_PE, /**< Use port E (PEx) pin. */
- AFIO_EXTI_PF, /**< Use port F (PFx) pin. */
- AFIO_EXTI_PG, /**< Use port G (PGx) pin. */
-#endif
-} afio_exti_port;
-
-/** GPIO device type */
-typedef struct gpio_dev {
- gpio_reg_map *regs; /**< Register map */
- rcc_clk_id clk_id; /**< RCC clock information */
- afio_exti_port exti_port; /**< AFIO external interrupt port value */
-} gpio_dev;
-
-extern gpio_dev gpioa;
-extern gpio_dev* const GPIOA;
-extern gpio_dev gpiob;
-extern gpio_dev* const GPIOB;
-extern gpio_dev gpioc;
-extern gpio_dev* const GPIOC;
-extern gpio_dev gpiod;
-extern gpio_dev* const GPIOD;
+struct gpio_dev;
+extern struct gpio_dev gpioa;
+extern struct gpio_dev* const GPIOA;
+extern struct gpio_dev gpiob;
+extern struct gpio_dev* const GPIOB;
+extern struct gpio_dev gpioc;
+extern struct gpio_dev* const GPIOC;
+extern struct gpio_dev gpiod;
+extern struct gpio_dev* const GPIOD;
#ifdef STM32_HIGH_DENSITY
-extern gpio_dev gpioe;
-extern gpio_dev* const GPIOE;
-extern gpio_dev gpiof;
-extern gpio_dev* const GPIOF;
-extern gpio_dev gpiog;
-extern gpio_dev* const GPIOG;
+extern struct gpio_dev gpioe;
+extern struct gpio_dev* const GPIOE;
+extern struct gpio_dev gpiof;
+extern struct gpio_dev* const GPIOF;
+extern struct gpio_dev gpiog;
+extern struct gpio_dev* const GPIOG;
#endif
/** GPIO port A register map base pointer */
@@ -108,14 +85,12 @@ extern gpio_dev* const GPIOG;
#define GPIOC_BASE ((struct gpio_reg_map*)0x40011000)
/** GPIO port D register map base pointer */
#define GPIOD_BASE ((struct gpio_reg_map*)0x40011400)
-#ifdef STM32_HIGH_DENSITY
/** GPIO port E register map base pointer */
#define GPIOE_BASE ((struct gpio_reg_map*)0x40011800)
/** GPIO port F register map base pointer */
#define GPIOF_BASE ((struct gpio_reg_map*)0x40011C00)
/** GPIO port G register map base pointer */
#define GPIOG_BASE ((struct gpio_reg_map*)0x40012000)
-#endif
/*
* GPIO register bit definitions
@@ -138,7 +113,7 @@ extern gpio_dev* const GPIOG;
#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3
/**
- * @brief GPIO Pin modes.
+ * @brief GPIO pin modes.
*
* These only allow for 50MHZ max output speeds; if you want slower,
* use direct register access.
@@ -164,14 +139,6 @@ typedef enum gpio_pin_mode {
/* GPIO_INPUT_PU treated as a special case, for ODR twiddling */
} gpio_pin_mode;
-/**
- * @brief Get a GPIO port's corresponding afio_exti_port.
- * @param dev GPIO device whose afio_exti_port to return.
- */
-static inline afio_exti_port gpio_exti_port(gpio_dev *dev) {
- return dev->exti_port;
-}
-
/*
* AFIO register map
*/
@@ -232,17 +199,17 @@ typedef struct afio_reg_map {
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24)
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24)
-#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20)
-#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19)
-#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18)
-#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17)
-#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16)
-#define AFIO_MAPR_PD01_REMAP BIT(15)
+#define AFIO_MAPR_ADC2_ETRGREG_REMAP (1U << 20)
+#define AFIO_MAPR_ADC2_ETRGINJ_REMAP (1U << 19)
+#define AFIO_MAPR_ADC1_ETRGREG_REMAP (1U << 18)
+#define AFIO_MAPR_ADC1_ETRGINJ_REMAP (1U << 17)
+#define AFIO_MAPR_TIM5CH4_IREMAP (1U << 16)
+#define AFIO_MAPR_PD01_REMAP (1U << 15)
#define AFIO_MAPR_CAN_REMAP (0x3 << 13)
#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13)
#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13)
#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13)
-#define AFIO_MAPR_TIM4_REMAP BIT(12)
+#define AFIO_MAPR_TIM4_REMAP (1U << 12)
#define AFIO_MAPR_TIM3_REMAP (0x3 << 10)
#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10)
#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10)
@@ -260,10 +227,10 @@ typedef struct afio_reg_map {
#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4)
#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4)
#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4)
-#define AFIO_MAPR_USART2_REMAP BIT(3)
-#define AFIO_MAPR_USART1_REMAP BIT(2)
-#define AFIO_MAPR_I2C1_REMAP BIT(1)
-#define AFIO_MAPR_SPI1_REMAP BIT(0)
+#define AFIO_MAPR_USART2_REMAP (1U << 3)
+#define AFIO_MAPR_USART1_REMAP (1U << 2)
+#define AFIO_MAPR_I2C1_REMAP (1U << 1)
+#define AFIO_MAPR_SPI1_REMAP (1U << 0)
/* External interrupt configuration register 1 */
@@ -337,12 +304,12 @@ typedef struct afio_reg_map {
/* AF remap and debug I/O configuration register 2 */
-#define AFIO_MAPR2_FSMC_NADV BIT(10)
-#define AFIO_MAPR2_TIM14_REMAP BIT(9)
-#define AFIO_MAPR2_TIM13_REMAP BIT(8)
-#define AFIO_MAPR2_TIM11_REMAP BIT(7)
-#define AFIO_MAPR2_TIM10_REMAP BIT(6)
-#define AFIO_MAPR2_TIM9_REMAP BIT(5)
+#define AFIO_MAPR2_FSMC_NADV (1U << 10)
+#define AFIO_MAPR2_TIM14_REMAP (1U << 9)
+#define AFIO_MAPR2_TIM13_REMAP (1U << 8)
+#define AFIO_MAPR2_TIM11_REMAP (1U << 7)
+#define AFIO_MAPR2_TIM10_REMAP (1U << 6)
+#define AFIO_MAPR2_TIM9_REMAP (1U << 5)
/*
* AFIO convenience routines
@@ -350,33 +317,9 @@ typedef struct afio_reg_map {
void afio_init(void);
-/**
- * External interrupt line numbers.
- */
-typedef enum afio_exti_num {
- AFIO_EXTI_0, /**< External interrupt line 0. */
- AFIO_EXTI_1, /**< External interrupt line 1. */
- AFIO_EXTI_2, /**< External interrupt line 2. */
- AFIO_EXTI_3, /**< External interrupt line 3. */
- AFIO_EXTI_4, /**< External interrupt line 4. */
- AFIO_EXTI_5, /**< External interrupt line 5. */
- AFIO_EXTI_6, /**< External interrupt line 6. */
- AFIO_EXTI_7, /**< External interrupt line 7. */
- AFIO_EXTI_8, /**< External interrupt line 8. */
- AFIO_EXTI_9, /**< External interrupt line 9. */
- AFIO_EXTI_10, /**< External interrupt line 10. */
- AFIO_EXTI_11, /**< External interrupt line 11. */
- AFIO_EXTI_12, /**< External interrupt line 12. */
- AFIO_EXTI_13, /**< External interrupt line 13. */
- AFIO_EXTI_14, /**< External interrupt line 14. */
- AFIO_EXTI_15, /**< External interrupt line 15. */
-} afio_exti_num;
-
-void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
-
/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
* not used in either MAPR or MAPR2 */
-#define AFIO_REMAP_USE_MAPR2 (1 << 31)
+#define AFIO_REMAP_USE_MAPR2 (1U << 31)
/**
* @brief Available peripheral remaps.
@@ -474,6 +417,86 @@ static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
}
+/*
+ * Deprecated bits
+ */
+
+/**
+ * @brief Deprecated. Use exti_cfg instead.
+ *
+ * In previous versions of libmaple, exti_attach_interrupt() took an
+ * afio_exti_port argument; afio_exti_port was also a member of struct
+ * gpio_dev. This isn't portable, so we now use exti_cfg
+ * instead. This typedef (and the macros AFIO_EXTI_PA, ...,
+ * AFIO_EXTI_PG) exist to preserve backwards compatibility.
+ */
+typedef exti_cfg afio_exti_port;
+
+/** Deprecated. Use EXTI_PA instead. */
+#define AFIO_EXTI_PA EXTI_PA
+/** Deprecated. Use EXTI_PB instead. */
+#define AFIO_EXTI_PB EXTI_PB
+/** Deprecated. Use EXTI_PC instead. */
+#define AFIO_EXTI_PC EXTI_PC
+/** Deprecated. Use EXTI_PD instead. */
+#define AFIO_EXTI_PD EXTI_PD
+/** Deprecated. Use EXTI_PE instead. */
+#define AFIO_EXTI_PE EXTI_PE
+/** Deprecated. Use EXTI_PF instead. */
+#define AFIO_EXTI_PF EXTI_PF
+/** Deprecated. Use EXTI_PG instead. */
+#define AFIO_EXTI_PG EXTI_PG
+
+/**
+ * @brief Deprecated. Use exti_num instead.
+ *
+ * In previous versions of libmaple, exti_attach_interrupt() took an
+ * afio_exti_num argument. This isn't portable, so we use exti_num
+ * instead. This typedef (and the macros AFIO_EXTI_0, ...,
+ * AFIO_EXTI_15) exist to preserve backwards compatibility.
+ */
+typedef exti_num afio_exti_num;
+
+/** Deprecated. Use EXTI0 instead. */
+#define AFIO_EXTI_0 EXTI0
+/** Deprecated. Use EXTI1 instead. */
+#define AFIO_EXTI_1 EXTI1
+/** Deprecated. Use EXTI2 instead. */
+#define AFIO_EXTI_2 EXTI2
+/** Deprecated. Use EXTI3 instead. */
+#define AFIO_EXTI_3 EXTI3
+/** Deprecated. Use EXTI4 instead. */
+#define AFIO_EXTI_4 EXTI4
+/** Deprecated. Use EXTI5 instead. */
+#define AFIO_EXTI_5 EXTI5
+/** Deprecated. Use EXTI6 instead. */
+#define AFIO_EXTI_6 EXTI6
+/** Deprecated. Use EXTI7 instead. */
+#define AFIO_EXTI_7 EXTI7
+/** Deprecated. Use EXTI8 instead. */
+#define AFIO_EXTI_8 EXTI8
+/** Deprecated. Use EXTI9 instead. */
+#define AFIO_EXTI_9 EXTI9
+/** Deprecated. Use EXTI10 instead. */
+#define AFIO_EXTI_10 EXTI10
+/** Deprecated. Use EXTI11 instead. */
+#define AFIO_EXTI_11 EXTI11
+/** Deprecated. Use EXTI12 instead. */
+#define AFIO_EXTI_12 EXTI12
+/** Deprecated. Use EXTI13 instead. */
+#define AFIO_EXTI_13 EXTI13
+/** Deprecated. Use EXTI14 instead. */
+#define AFIO_EXTI_14 EXTI14
+/** Deprecated. Use EXTI15 instead. */
+#define AFIO_EXTI_15 EXTI15
+
+/**
+ * @brief Deprecated. Use exti_select(exti, port) instead.
+ */
+static __always_inline void afio_exti_select(exti_num exti, exti_cfg port) {
+ exti_select(exti, port);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/libmaple/stm32f1/rules.mk b/libmaple/stm32f1/rules.mk
index 0effea3..15f6fdb 100644
--- a/libmaple/stm32f1/rules.mk
+++ b/libmaple/stm32f1/rules.mk
@@ -17,6 +17,7 @@ sSRCS_$(d) += $(MCU_F1_LINE)/vector_table.S
cSRCS_$(d) := adc.c
cSRCS_$(d) += bkp.c
cSRCS_$(d) += dma.c
+cSRCS_$(d) += exti.c
cSRCS_$(d) += fsmc.c
cSRCS_$(d) += gpio.c
cSRCS_$(d) += rcc.c
diff --git a/libmaple/stm32f2/gpio.c b/libmaple/stm32f2/gpio.c
index f2cd776..a26edaa 100644
--- a/libmaple/stm32f2/gpio.c
+++ b/libmaple/stm32f2/gpio.c
@@ -40,6 +40,7 @@
gpio_dev gpioa = {
.regs = GPIOA_BASE,
.clk_id = RCC_GPIOA,
+ .exti_port = EXTI_PA,
};
/** GPIO port A device. */
gpio_dev* const GPIOA = &gpioa;
@@ -47,6 +48,7 @@ gpio_dev* const GPIOA = &gpioa;
gpio_dev gpiob = {
.regs = GPIOB_BASE,
.clk_id = RCC_GPIOB,
+ .exti_port = EXTI_PB,
};
/** GPIO port B device. */
gpio_dev* const GPIOB = &gpiob;
@@ -54,6 +56,7 @@ gpio_dev* const GPIOB = &gpiob;
gpio_dev gpioc = {
.regs = GPIOC_BASE,
.clk_id = RCC_GPIOC,
+ .exti_port = EXTI_PC,
};
/** GPIO port C device. */
gpio_dev* const GPIOC = &gpioc;
@@ -61,6 +64,7 @@ gpio_dev* const GPIOC = &gpioc;
gpio_dev gpiod = {
.regs = GPIOD_BASE,
.clk_id = RCC_GPIOD,
+ .exti_port = EXTI_PD,
};
/** GPIO port D device. */
gpio_dev* const GPIOD = &gpiod;
@@ -68,6 +72,7 @@ gpio_dev* const GPIOD = &gpiod;
gpio_dev gpioe = {
.regs = GPIOE_BASE,
.clk_id = RCC_GPIOE,
+ .exti_port = EXTI_PE,
};
/** GPIO port E device. */
gpio_dev* const GPIOE = &gpioe;
@@ -75,6 +80,7 @@ gpio_dev* const GPIOE = &gpioe;
gpio_dev gpiof = {
.regs = GPIOF_BASE,
.clk_id = RCC_GPIOF,
+ .exti_port = EXTI_PF,
};
/** GPIO port F device. */
gpio_dev* const GPIOF = &gpiof;
@@ -82,6 +88,7 @@ gpio_dev* const GPIOF = &gpiof;
gpio_dev gpiog = {
.regs = GPIOG_BASE,
.clk_id = RCC_GPIOG,
+ .exti_port = EXTI_PG,
};
/** GPIO port G device. */
gpio_dev* const GPIOG = &gpiog;
@@ -89,6 +96,7 @@ gpio_dev* const GPIOG = &gpiog;
gpio_dev gpioh = {
.regs = GPIOH_BASE,
.clk_id = RCC_GPIOH,
+ .exti_port = EXTI_PH,
};
/** GPIO port G device. */
gpio_dev* const GPIOH = &gpioh;
@@ -96,6 +104,7 @@ gpio_dev* const GPIOH = &gpioh;
gpio_dev gpioi = {
.regs = GPIOI_BASE,
.clk_id = RCC_GPIOI,
+ .exti_port = EXTI_PI,
};
/** GPIO port G device. */
gpio_dev* const GPIOI = &gpioi;
diff --git a/libmaple/stm32f2/include/series/gpio.h b/libmaple/stm32f2/include/series/gpio.h
index 9687247..1496e8e 100644
--- a/libmaple/stm32f2/include/series/gpio.h
+++ b/libmaple/stm32f2/include/series/gpio.h
@@ -1,7 +1,7 @@
/******************************************************************************
* The MIT License
*
- * Copyright (c) 2011 LeafLabs, LLC.
+ * 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
@@ -36,8 +36,7 @@
extern "C"{
#endif
-#include <libmaple/libmaple.h>
-#include <libmaple/rcc.h>
+#include <libmaple/libmaple_types.h>
/*
* GPIO register maps and devices
@@ -76,30 +75,25 @@ typedef struct gpio_reg_map {
/** GPIO port I register map base pointer */
#define GPIOI_BASE ((struct gpio_reg_map*)0x40022000)
-/** GPIO device type */
-typedef struct gpio_dev {
- gpio_reg_map *regs;
- rcc_clk_id clk_id;
-} gpio_dev;
-
-extern gpio_dev* const GPIOA;
-extern gpio_dev gpioa;
-extern gpio_dev* const GPIOB;
-extern gpio_dev gpiob;
-extern gpio_dev* const GPIOC;
-extern gpio_dev gpioc;
-extern gpio_dev* const GPIOD;
-extern gpio_dev gpiod;
-extern gpio_dev* const GPIOE;
-extern gpio_dev gpioe;
-extern gpio_dev* const GPIOF;
-extern gpio_dev gpiof;
-extern gpio_dev* const GPIOG;
-extern gpio_dev gpiog;
-extern gpio_dev* const GPIOH;
-extern gpio_dev gpioh;
-extern gpio_dev* const GPIOI;
-extern gpio_dev gpioi;
+struct gpio_dev;
+extern struct gpio_dev* const GPIOA;
+extern struct gpio_dev gpioa;
+extern struct gpio_dev* const GPIOB;
+extern struct gpio_dev gpiob;
+extern struct gpio_dev* const GPIOC;
+extern struct gpio_dev gpioc;
+extern struct gpio_dev* const GPIOD;
+extern struct gpio_dev gpiod;
+extern struct gpio_dev* const GPIOE;
+extern struct gpio_dev gpioe;
+extern struct gpio_dev* const GPIOF;
+extern struct gpio_dev gpiof;
+extern struct gpio_dev* const GPIOG;
+extern struct gpio_dev gpiog;
+extern struct gpio_dev* const GPIOH;
+extern struct gpio_dev gpioh;
+extern struct gpio_dev* const GPIOI;
+extern struct gpio_dev gpioi;
/*
* Register bit definitions
@@ -215,7 +209,7 @@ typedef enum gpio_mode_flags {
GPIO_MODEF_PUPD_PD = GPIO_PUPDR_PD << 3, /**< Pull-down */
} gpio_mode_flags;
-void gpio_set_modef(gpio_dev *dev,
+void gpio_set_modef(struct gpio_dev *dev,
uint8 bit,
gpio_pin_mode mode,
unsigned flags);
@@ -231,7 +225,7 @@ void gpio_set_modef(gpio_dev *dev,
* @param pin Pin on the device whose mode to set, 0--15.
* @param mode Mode to set the pin to.
*/
-static inline void gpio_set_mode(gpio_dev *dev,
+static inline void gpio_set_mode(struct gpio_dev *dev,
uint8 bit,
gpio_pin_mode mode) {
gpio_set_modef(dev, bit, mode, GPIO_MODEF_SPEED_HIGH);
@@ -261,7 +255,7 @@ typedef enum gpio_af {
GPIO_AF_EVENTOUT = 15, /**< EVENTOUT. */
} gpio_af;
-void gpio_set_af(gpio_dev *dev, uint8 bit, gpio_af af);
+void gpio_set_af(struct gpio_dev *dev, uint8 bit, gpio_af af);
#ifdef __cplusplus
}