From 2e1cbcae223eb6ebe1067a6f9d3230f4f81b5136 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 3 Jul 2014 20:26:25 +0200 Subject: [PATCH] vf6xx: initial GPIO support This adds GPIO module support. GPIO can be controlled using the GPIO number as stated in the reference manual, similar to Linux. Also 32-bit access to whole ports is possible. Reading a GPIO is possible without muxing the pad as GPIO, however writing a GPIO needs the pad to be muxed as GPIO. --- include/libopencm3/vf6xx/gpio.h | 80 ++++++++++++++++ include/libopencm3/vf6xx/memorymap.h | 3 + lib/vf6xx/Makefile | 2 +- lib/vf6xx/gpio.c | 131 +++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 include/libopencm3/vf6xx/gpio.h create mode 100644 lib/vf6xx/gpio.c diff --git a/include/libopencm3/vf6xx/gpio.h b/include/libopencm3/vf6xx/gpio.h new file mode 100644 index 0000000000..c575b3dc46 --- /dev/null +++ b/include/libopencm3/vf6xx/gpio.h @@ -0,0 +1,80 @@ +/** @defgroup VF6xx_gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the VF6xx GPIO Module + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 03 July 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_VF6XX_GPIO_H +#define LIBOPENCM3_VF6XX_GPIO_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup gpio_reg_base GPIO register base addresses +@ingroup VF6xx_gpio_defines + +@{*/ +#define GPIO(port) (GPIO_BASE + (0x040 * (port))) +#define GPIO0 (GPIO_BASE + 0x000) +#define GPIO1 (GPIO_BASE + 0x040) +#define GPIO2 (GPIO_BASE + 0x080) +#define GPIO3 (GPIO_BASE + 0x0C0) +#define GPIO4 (GPIO_BASE + 0x100) + +#define GPIO_OFFSET(gpio) (0x1 << (gpio % 32)) + +/* --- GPIO registers ------------------------------------------------------ */ + +#define GPIO_PDOR(gpio_base) MMIO32(gpio_base + 0x00) +#define GPIO_PSOR(gpio_base) MMIO32(gpio_base + 0x04) +#define GPIO_PCOR(gpio_base) MMIO32(gpio_base + 0x08) +#define GPIO_PTOR(gpio_base) MMIO32(gpio_base + 0x0C) +#define GPIO_PDIR(gpio_base) MMIO32(gpio_base + 0x10) + +/* --- Function prototypes ------------------------------------------------- */ + +#include + +BEGIN_DECLS + +void gpio_set(uint32_t gpio); +void gpio_clear(uint32_t gpio); +bool gpio_get(uint32_t gpio); +void gpio_toggle(uint32_t gpio); +uint32_t gpio_port_read(uint32_t gpioport); +void gpio_port_write(uint32_t gpioport, uint32_t data); + +END_DECLS + +#endif diff --git a/include/libopencm3/vf6xx/memorymap.h b/include/libopencm3/vf6xx/memorymap.h index eeed63ff9d..0644930610 100644 --- a/include/libopencm3/vf6xx/memorymap.h +++ b/include/libopencm3/vf6xx/memorymap.h @@ -52,4 +52,7 @@ #define UART4_BASE (PERIPH_BASE_AIPS1 + 0x29000) #define UART5_BASE (PERIPH_BASE_AIPS1 + 0x2A000) +/* GPIO module */ +#define GPIO_BASE (PERIPH_BASE + 0xff000) + #endif diff --git a/lib/vf6xx/Makefile b/lib/vf6xx/Makefile index bf5392c897..61f3044a5c 100644 --- a/lib/vf6xx/Makefile +++ b/lib/vf6xx/Makefile @@ -34,7 +34,7 @@ CFLAGS = -Os -g \ -mcpu=cortex-m4 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ -ffunction-sections -fdata-sections -MD -DVF6XX ARFLAGS = rcs -OBJS = ccm.o uart.o +OBJS = ccm.o uart.o gpio.o VPATH += ../cm3 diff --git a/lib/vf6xx/gpio.c b/lib/vf6xx/gpio.c new file mode 100644 index 0000000000..01bde8991b --- /dev/null +++ b/lib/vf6xx/gpio.c @@ -0,0 +1,131 @@ +/** @defgroup VF6xx_gpio GPIO + * + * @ingroup VF6xx + * + * @section vf6xx_gpio_api_ex GPIO API. + * + * @brief VF6xx General-Purpose Input/Output (GPIO) + * + * @author @htmlonly © @endhtmlonly 2014 Stefan Agner + * + * @date 03 July 2014 + * + * This library supports the GPIO module in the VF6xx SoC of Freescale. + * Access is provided by GPIO number according to the Pinmux list of the + * Reference Manual, similar as GPIOs are available on Linux. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO + +Set GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_set(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PSOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO + +Clears GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_clear(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PCOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get GPIOs logic state + +Get logic level of GPIO given by GPIO number according to MUX list. Reading +a GPIO value is possible even if the port is not muxed for GPIO. + +@param[in] gpio unsigned 32 bit. GPIO number +@returns the logic state of the given GPIO. +*/ + +bool gpio_get(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + return !!(GPIO_PDIR(port) & GPIO_OFFSET(gpio)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Toggles GPIO + +Toggles GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_toggle(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PTOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read a whole GPIO Port + +Gets all 32 GPIOs of a Port. + +@param[in] gpioport unsigned 32 bit. GPIO port @ref gpio_reg_base +@returns the logic states of the given GPIO port. +*/ + +uint32_t gpio_port_read(uint32_t gpioport) +{ + return GPIO_PDIR(gpioport); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Write a whole GPIO Port + +Sets all 32 GPIOs of a Port. + +@param[in] gpioport unsigned 32 bit. GPIO port @ref gpio_reg_base +@param[in] gpio unsigned 32 bit. 1 for a logic 1 driven at port, 0 for a logic +0 driven at port. +*/ + +void gpio_port_write(uint32_t gpioport, uint32_t data) +{ + GPIO_PDOR(gpioport) = data; +} + +/**@}*/ +