/* * Copyright (C) 2015 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @defgroup drivers_periph_gpio GPIO * @ingroup drivers_periph * @brief Low-level GPIO peripheral driver * * This is a basic GPIO (General-purpose input/output) interface to allow * platform independent access to a MCU's input/output pins. This interface is * intentionally designed to be as simple as possible, to allow for easy * implementation and maximum portability. * * The interface provides capabilities to initialize a pin as output-, * input- and interrupt pin. With the API you can basically set/clear/toggle the * digital signal at the hardware pin when in output mode. Configured as input you can * read a digital value that is being applied to the pin externally. When initializing * an external interrupt pin, you can register a callback function that is executed * in interrupt context once the interrupt condition applies to the pin. Usually you * can react to rising or falling signal flanks (or both). * * In addition the API provides to set standard input/output circuit modes such as * e.g. internal push-pull configurations. * * All modern micro controllers organize their GPIOs in some form of ports, * often named 'PA', 'PB', 'PC'..., or 'P0', 'P1', 'P2'..., or similar. Each of * these ports is then assigned a number of pins, often 8, 16, or 32. A hardware * pin can thus be described by its port/pin tuple. To access a pin, the * @p GPIO_PIN(port, pin) macro should be used. For example: If your platform has * a pin PB22, it will be port=1 and pin=22. The @p GPIO_PIN macro should be * overridden by a MCU, to allow for efficient encoding of the the port/pin tuple. * For example, on many platforms it is possible to `OR` the pin number with the * corresponding ports base register address. This allows for efficient decoding * of pin number and base address without the need of any address lookup. * * In case the driver does not define it, the below macro definition is used to * simply map the port/pin tuple to the pin value. In that case, predefined GPIO * definitions in `RIOT/boards/ * /include/periph_conf.h` will define the selected * GPIO pin. * * @{ * @file * @brief Low-level GPIO peripheral driver interface definitions * * @author Hauke Petersen */ #ifndef GPIO_H #define GPIO_H #include #include "periph_cpu.h" #include "periph_conf.h" /* TODO: remove once all platforms are ported to this interface */ #include "periph/dev_enums.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Default GPIO macro maps port-pin tuples to the pin value */ #ifndef GPIO_PIN #define GPIO_PIN(x,y) ((x & 0) | y) #endif /** * @brief Define global value for GPIO not defined */ #ifndef GPIO_UNDEF #define GPIO_UNDEF (UINT_MAX) #endif /** * @brief Define the default GPIO type identifier */ #ifndef HAVE_GPIO_T typedef unsigned int gpio_t; #endif /** * @brief Definition of available pin directions */ #ifndef HAVE_GPIO_DIR_T typedef enum { GPIO_DIR_IN = 0, /**< configure pin as input */ GPIO_DIR_OUT = 1 /**< configure pin as output */ } gpio_dir_t; #endif /** * @brief Definition of pull-up/pull-down modes */ #ifndef HAVE_GPIO_PP_T typedef enum { GPIO_NOPULL = 0, /**< do not use internal pull resistors */ GPIO_PULLUP = 1, /**< enable internal pull-up resistor */ GPIO_PULLDOWN = 2 /**< enable internal pull-down resistor */ } gpio_pp_t; #endif /** * @brief Definition of possible active flanks for external interrupt mode */ #ifndef HAVE_GPIO_FLANK_T typedef enum { GPIO_FALLING = 0, /**< emit interrupt on falling flank */ GPIO_RISING = 1, /**< emit interrupt on rising flank */ GPIO_BOTH = 2 /**< emit interrupt on both flanks */ } gpio_flank_t; #endif /** * @brief Signature of event callback functions triggered from interrupts * * @param[in] arg optional context for the callback */ typedef void (*gpio_cb_t)(void *arg); /** * @brief Default interrupt context for GPIO pins * @{ */ #ifndef HAVE_GPIO_ISR_CTX_T typedef struct { gpio_cb_t cb; /**< interrupt callback */ void *arg; /**< optional argument */ } gpio_isr_ctx_t; #endif /** @} */ /** * @brief Initialize the given pin as general purpose input or output * * @param[in] pin pin to initialize * @param[in] dir direction for the pin, input or output * @param[in] pullup define what pull resistors should be used * * @return 0 on success * @return -1 on error */ int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pullup); /** * @brief Initialize a GPIO pin for external interrupt usage * * The registered callback function will be called in interrupt context every * time the defined flank(s) are detected. * * The interrupt is activated automatically after the initialization. * * @param[in] pin pin to initialize * @param[in] pullup define what pull resistors should be enabled * @param[in] flank define the active flank(s) * @param[in] cb callback that is called from interrupt context * @param[in] arg optional argument passed to the callback * * @return 0 on success * @return -1 on error */ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb, void *arg); /** * @brief Enable pin's interrupt if configured as interrupt source * * @param[in] pin the pin to enable the interrupt for */ void gpio_irq_enable(gpio_t pin); /** * @brief Disable the pin's interrupt if configured as interrupt source * * @param[in] pin the pin to disable the interrupt for */ void gpio_irq_disable(gpio_t pin); /** * @brief Get the current value of the given pin * * @param[in] pin the pin to read * @return the current value, 0 for LOW, != 0 for HIGH * * @return 0 when pin is LOW * @return greater 0 for HIGH */ int gpio_read(gpio_t pin); /** * @brief Set the given pin to HIGH * * @param[in] pin the pin to set */ void gpio_set(gpio_t pin); /** * @brief Set the given pin to LOW * * @param[in] pin the pin to clear */ void gpio_clear(gpio_t pin); /** * @brief Toggle the value of the given pin * * @param[in] pin the pin to toggle */ void gpio_toggle(gpio_t pin); /** * @brief Set the given pin to the given value * * @param[in] pin the pin to set * @param[in] value value to set the pin to, 0 for LOW, HIGH otherwise */ void gpio_write(gpio_t pin, int value); #ifdef __cplusplus } #endif #endif /* GPIO_H */ /** @} */