aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/include/libmaple/gpio.h
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-03 20:30:13 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-03 22:40:40 -0400
commita5b5d4f27f94befaf5577563a0319e8194377118 (patch)
tree770ced66d348e14435fb32b05824dccd077b456a /libmaple/include/libmaple/gpio.h
parent41c909dd2a9f6311d443550cb7c2ca3337fe3a20 (diff)
downloadlibrambutan-a5b5d4f27f94befaf5577563a0319e8194377118.tar.gz
librambutan-a5b5d4f27f94befaf5577563a0319e8194377118.zip
Bring back EXTI on F1, with deprecations for gpio.h on F1.
Tested on Maple Mini with examples/mini-exti-test. Changes to Wirish are minor: use the new EXTI types exti_num and exti_cfg (see below) in place of now-deprecated variants in ext_interrupts.cpp. The way I originally did libmaple/exti.h was stupid, and fixing it turned out to be a little disruptive. libmaple/exti.h depends on libmaple/gpio.h (for AFIO), but that's a classic case of exposed implementation detail. So invert the dependency: make gpio.h depend on exti.h. Do this by adding exti_num and exti_cfg to exti.h; these respectively replace afio_exti_num and afio_exti_port. The afio_* variants are now deprecated. (Throw in a typedef and some macros at the bottom of the F1 series/gpio.h for backwards compatibility). Make exti_attach_interrupt() and exti_detach_interrupt() take exti_num/exti_cfg arguments instead of the afio_* variants. Make the EXTI dispatch routines __always_inline to defeat GCC -Os. Many renames throughout libmaple/stm32f1/ to stop using the deprecated names. Also move the previously F1-only gpio_exti_port() function into the public libmaple header. Reimplementing it in terms of rcc_clk_ids lets us deprecate the gpio_dev->exti_port field, which will save space in the future. While we're there, I notice that struct gpio_dev is defined once per series. That's dumb, as it misses the entire point of having device structs: they contain what's portable. So put the F1 version (which has the extra EXTI port field) into libmaple/gpio.h, and add the necessary exti_ports to libmaple/stm32f2/gpio.c. Sigh. We'll get rid of it eventually, at least. Clean up some other mistakes in gpio.h files as well (mostly removing util.h dependency). Sorry for the messy commit. For portability, add a new series-specific exti function, exti_select(). The F1 version in (new) libmaple/stm32f1/exti.c uses AFIO and some new private functionality in libmaple/exti.c and (new) libmaple/exti_private.h to make this convenient. We'll be able to do the SYSCFG equivalent on F2 without any trouble. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'libmaple/include/libmaple/gpio.h')
-rw-r--r--libmaple/include/libmaple/gpio.h41
1 files changed, 33 insertions, 8 deletions
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