aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/stm32f2/gpio.c157
-rw-r--r--libmaple/stm32f2/include/series/gpio.h222
-rw-r--r--libmaple/stm32f2/rules.mk1
3 files changed, 380 insertions, 0 deletions
diff --git a/libmaple/stm32f2/gpio.c b/libmaple/stm32f2/gpio.c
new file mode 100644
index 0000000..61b71f7
--- /dev/null
+++ b/libmaple/stm32f2/gpio.c
@@ -0,0 +1,157 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 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.
+ *****************************************************************************/
+
+/**
+ * @file libmaple/stm32f2/gpio.c
+ * @brief GPIO support for STM32F2 line.
+ */
+
+#include <libmaple/gpio.h>
+#include <libmaple/rcc.h>
+#include <libmaple/bitband.h>
+
+/*
+ * GPIO devices
+ */
+
+gpio_dev gpioa = {
+ .regs = GPIOA_BASE,
+ .clk_id = RCC_GPIOA,
+};
+/** GPIO port A device. */
+gpio_dev* const GPIOA = &gpioa;
+
+gpio_dev gpiob = {
+ .regs = GPIOB_BASE,
+ .clk_id = RCC_GPIOB,
+};
+/** GPIO port B device. */
+gpio_dev* const GPIOB = &gpiob;
+
+gpio_dev gpioc = {
+ .regs = GPIOC_BASE,
+ .clk_id = RCC_GPIOC,
+};
+/** GPIO port C device. */
+gpio_dev* const GPIOC = &gpioc;
+
+gpio_dev gpiod = {
+ .regs = GPIOD_BASE,
+ .clk_id = RCC_GPIOD,
+};
+/** GPIO port D device. */
+gpio_dev* const GPIOD = &gpiod;
+
+gpio_dev gpioe = {
+ .regs = GPIOE_BASE,
+ .clk_id = RCC_GPIOE,
+};
+/** GPIO port E device. */
+gpio_dev* const GPIOE = &gpioe;
+
+gpio_dev gpiof = {
+ .regs = GPIOF_BASE,
+ .clk_id = RCC_GPIOF,
+};
+/** GPIO port F device. */
+gpio_dev* const GPIOF = &gpiof;
+
+gpio_dev gpiog = {
+ .regs = GPIOG_BASE,
+ .clk_id = RCC_GPIOG,
+};
+/** GPIO port G device. */
+gpio_dev* const GPIOG = &gpiog;
+
+gpio_dev gpioh = {
+ .regs = GPIOG_BASE,
+ .clk_id = RCC_GPIOH,
+};
+/** GPIO port G device. */
+gpio_dev* const GPIOH = &gpioh;
+
+gpio_dev gpioi = {
+ .regs = GPIOI_BASE,
+ .clk_id = RCC_GPIOI,
+};
+/** GPIO port G device. */
+gpio_dev* const GPIOI = &gpioi;
+
+/*
+ * GPIO routines
+ */
+
+/**
+ * Initialize and reset all available GPIO devices.
+ */
+void gpio_init_all(void) {
+ gpio_init(GPIOA);
+ gpio_init(GPIOB);
+ gpio_init(GPIOC);
+ gpio_init(GPIOD);
+ gpio_init(GPIOE);
+ gpio_init(GPIOF);
+ gpio_init(GPIOG);
+ gpio_init(GPIOH);
+ gpio_init(GPIOI);
+}
+
+/**
+ * @brief Set the mode of a GPIO pin.
+ * @param dev GPIO device.
+ * @param pin Pin on the device whose mode to set, 0--15.
+ * @param mode Mode to set the pin to.
+ * @param flags Flags to modify basic mode configuration
+ */
+void gpio_set_modef(gpio_dev *dev,
+ uint8 pin,
+ gpio_pin_mode mode,
+ unsigned flags) {
+ gpio_reg_map *regs = dev->regs;
+ unsigned shift = pin * 2;
+ uint32 tmp;
+
+ /* Mode */
+ tmp = regs->MODER;
+ tmp &= ~(0x3 << shift);
+ tmp |= mode << shift;
+ regs->MODER = tmp;
+
+ /* Output type */
+ bb_peri_set_bit(&regs->OTYPER, pin, flags & 0x1);
+
+ /* Speed */
+ tmp = regs->OSPEEDR;
+ tmp &= ~(0x3 << shift);
+ tmp |= (flags >> 1) << shift;
+ regs->OSPEEDR = tmp;
+
+ /* Pull-up/pull-down */
+ tmp = regs->PUPDR;
+ tmp &= ~(0x3 << shift);
+ tmp |= (flags >> 2) << shift;
+ regs->PUPDR = tmp;
+}
diff --git a/libmaple/stm32f2/include/series/gpio.h b/libmaple/stm32f2/include/series/gpio.h
new file mode 100644
index 0000000..86ee4aa
--- /dev/null
+++ b/libmaple/stm32f2/include/series/gpio.h
@@ -0,0 +1,222 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 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.
+*****************************************************************************/
+
+/**
+ * @file libmaple/stm32f2/gpio.h
+ * @brief STM32F2 General Purpose I/O (GPIO) header.
+ */
+
+#ifndef _LIBMAPLE_STM32F2_GPIO_H_
+#define _LIBMAPLE_STM32F2_GPIO_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#include <libmaple/libmaple.h>
+#include <libmaple/rcc.h>
+
+/*
+ * GPIO register maps and devices
+ */
+
+/** GPIO register map type */
+typedef struct gpio_reg_map {
+ __io uint32 MODER; /**< Mode register */
+ __io uint32 OTYPER; /**< Output type register */
+ __io uint32 OSPEEDR; /**< Output speed register */
+ __io uint32 PUPDR; /**< Pull-up/pull-down register */
+ __io uint32 IDR; /**< Input data register */
+ __io uint32 ODR; /**< Output data register */
+ __io uint32 BSRR; /**< Bit set/reset register */
+ __io uint32 LCKR; /**< Configuration lock register */
+ __io uint32 AFRL; /**< Alternate function low register */
+ __io uint32 AFRH; /**< Alternate function high register */
+} gpio_reg_map;
+
+/** GPIO port A register map base pointer */
+#define GPIOA_BASE ((struct gpio_reg_map*)0x40020000)
+/** GPIO port B register map base pointer */
+#define GPIOB_BASE ((struct gpio_reg_map*)0x40020400)
+/** GPIO port C register map base pointer */
+#define GPIOC_BASE ((struct gpio_reg_map*)0x40020800)
+/** GPIO port D register map base pointer */
+#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00)
+/** GPIO port E register map base pointer */
+#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000)
+/** GPIO port F register map base pointer */
+#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400)
+/** GPIO port G register map base pointer */
+#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800)
+/** GPIO port H register map base pointer */
+#define GPIOH_BASE ((struct gpio_reg_map*)0x40021C00)
+/** 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;
+
+/*
+ * Register bit definitions
+ *
+ * Currently, we only provide masks to be used for shifting, rather
+ * than repeating the same values 16 times.
+ */
+
+/* Mode register */
+
+#define GPIO_MODER_INPUT 0x0
+#define GPIO_MODER_OUTPUT 0x1
+#define GPIO_MODER_AF 0x2
+#define GPIO_MODER_ANALOG 0x3
+
+/* Output type register */
+
+#define GPIO_OTYPER_PP 0x0
+#define GPIO_OTYPER_OD 0x1
+
+/* Output speed register */
+
+#define GPIO_OSPEEDR_LOW 0x0
+#define GPIO_OSPEEDR_MED 0x1
+#define GPIO_OSPEEDR_FAST 0x2
+#define GPIO_OSPEEDR_HIGH 0x3
+
+/* Pull-up/pull-down register */
+
+#define GPIO_PUPDR_NOPUPD 0x0
+#define GPIO_PUPDR_PU 0x1
+#define GPIO_PUPDR_PD 0x2
+
+/*
+ * GPIO routines
+ */
+
+/**
+ * @brief GPIO pin modes
+ */
+typedef enum gpio_pin_mode {
+ GPIO_MODE_INPUT = GPIO_MODER_INPUT, /**< Input mode */
+ GPIO_MODE_OUTPUT = GPIO_MODER_OUTPUT, /**< Output mode */
+ GPIO_MODE_AF = GPIO_MODER_AF, /**< Alternate function mode */
+ GPIO_MODE_ANALOG = GPIO_MODER_ANALOG, /**< Analog mode */
+} gpio_pin_mode;
+
+/**
+ * @brief Additional flags to be used when setting a pin's mode.
+ *
+ * Beyond the basic modes (input, general purpose output, alternate
+ * function, and analog), there are three parameters that can affect a
+ * pin's mode:
+ *
+ * 1. Output type: push/pull or open-drain. This only has an effect
+ * for output modes. Choices are: GPIO_MODEF_TYPE_PP (the default)
+ * and GPIO_MODEF_TYPE_OD.
+ *
+ * 2. Output speed: specifies the frequency at which a pin changes
+ * state. This only has an effect for output modes. Choices are:
+ * GPIO_MODEF_SPEED_LOW (default), GPIO_MODEF_SPEED_MED,
+ * GPIO_MODEF_SPEED_FAST, and GPIO_MODEF_SPEED_HIGH.
+ *
+ * 3. Push/pull setting: All GPIO pins have weak pull-up and pull-down
+ * resistors that can be enabled when the pin's mode is
+ * set. Choices are: GPIO_MODEF_PUPD_NONE (default),
+ * GPIO_MODEF_PUPD_PU, and GPIO_MODEF_PUPD_PD.
+ */
+typedef enum gpio_mode_flags {
+ /* Output type in bit 0 */
+ GPIO_MODEF_TYPE_PP = GPIO_OTYPER_PP, /**< Output push/pull (default).
+ Applies only when the mode
+ specifies output. */
+ GPIO_MODEF_TYPE_OD = GPIO_OTYPER_OD, /**< Output open drain.
+ Applies only when the mode
+ specifies output. */
+
+ /* Speed in bits 2:1 */
+ GPIO_MODEF_SPEED_LOW = GPIO_OSPEEDR_LOW << 1, /**< Low speed (default):
+ 2 MHz. */
+ GPIO_MODEF_SPEED_MED = GPIO_OSPEEDR_MED << 1, /**< Medium speed: 25 MHz. */
+ GPIO_MODEF_SPEED_FAST = GPIO_OSPEEDR_FAST << 1, /**< Fast speed: 50 MHz. */
+ GPIO_MODEF_SPEED_HIGH = GPIO_OSPEEDR_HIGH << 1, /**< High speed:
+ 100 MHz on 30 pF,
+ 80 MHz on 15 pF. */
+
+ /* Pull-up/pull-down in bits 4:3 */
+ GPIO_MODEF_PUPD_NONE = GPIO_PUPDR_NOPUPD << 3, /**< No pull-up/pull-down
+ (default). */
+ GPIO_MODEF_PUPD_PU = GPIO_PUPDR_PU << 3, /**< Pull-up */
+ GPIO_MODEF_PUPD_PD = GPIO_PUPDR_PD << 3, /**< Pull-down */
+} gpio_mode_flags;
+
+void gpio_set_modef(gpio_dev *dev,
+ uint8 pin,
+ gpio_pin_mode mode,
+ unsigned flags);
+
+/**
+ * @brief Set the mode of a GPIO pin.
+ *
+ * Calling this function is equivalent to calling gpio_set_modef(dev,
+ * pin, mode, GPIO_MODE_SPEED_HIGH). Note that this overrides the
+ * default speed.
+ *
+ * @param dev GPIO device.
+ * @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,
+ uint8 pin,
+ gpio_pin_mode mode) {
+ gpio_set_modef(dev, pin, mode, GPIO_MODEF_SPEED_HIGH);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libmaple/stm32f2/rules.mk b/libmaple/stm32f2/rules.mk
index a865340..83ab043 100644
--- a/libmaple/stm32f2/rules.mk
+++ b/libmaple/stm32f2/rules.mk
@@ -10,6 +10,7 @@ CFLAGS_$(d) = -I$(d) $(LIBMAPLE_INCLUDES) $(LIBMAPLE_PRIVATE_INCLUDES) -Wall -We
# Local rules and targets
sSRCS_$(d) := isrs.S vector_table.S
cSRCS_$(d) := rcc.c
+cSRCS_$(d) += gpio.c
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)