nes-proj/cpu/cc2538/dev/gpio.h
Benoît Thébaudeau 1e67ab3941 cc2538: gpio: Add macros to get interrupt status
Introduce new useful GPIO macros to:
 - get the raw interrupt status of a port,
 - get the masked interrupt status of a port,
 - get the power-up interrupt status of a port.

These macros are cleaner and less error-prone than raw register access
code copied all over the place.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-04-27 01:14:51 +02:00

622 lines
29 KiB
C

/*
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538
* @{
*
* \defgroup cc2538-gpio cc2538 General-Purpose I/O
*
* Driver for the cc2538 GPIO controller
* @{
*
* \file
* Header file with register and macro declarations for the cc2538 GPIO module
*/
#ifndef GPIO_H_
#define GPIO_H_
#include "reg.h"
#include <stdint.h>
/**
* \brief Type definition for callbacks invoked by the GPIO ISRs
* \param port The port that triggered the GPIO interrupt. \e port is passed
* by its numeric representation (Port A:0, B:1 etc). Defines for
* these numeric representations are GPIO_x_NUM
* \param pin The pin that triggered the interrupt, specified by number
* (0, 1, ..., 7)
*
* This is the prototype of a function pointer passed to
* gpio_register_callback(). These callbacks are registered on a port/pin
* basis. When a GPIO port generates an interrupt, if a callback has been
* registered for the port/pin combination, the ISR will invoke it. The ISR
* will pass the port/pin as arguments in that call, so that a developer can
* re-use the same callback for multiple port/pin combinations
*/
typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
/*---------------------------------------------------------------------------*/
/** \name Base addresses for the GPIO register instances
* @{
*/
#define GPIO_A_BASE 0x400D9000 /**< GPIO_A */
#define GPIO_B_BASE 0x400DA000 /**< GPIO_B */
#define GPIO_C_BASE 0x400DB000 /**< GPIO_C */
#define GPIO_D_BASE 0x400DC000 /**< GPIO_D */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name Numeric representation of the four GPIO ports
* @{
*/
#define GPIO_A_NUM 0 /**< GPIO_A: 0 */
#define GPIO_B_NUM 1 /**< GPIO_B: 1 */
#define GPIO_C_NUM 2 /**< GPIO_C: 2 */
#define GPIO_D_NUM 3 /**< GPIO_D: 3 */
/** @} */
/*---------------------------------------------------------------------------*/
/**
* \name GPIO Manipulation macros
* @{
*/
/** \brief Set pins with PIN_MASK of port with PORT_BASE to input.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_DIR) &= ~(PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to output.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_DIR) |= (PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE high.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0xFF; } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE low.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0x00; } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to value.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
* \param value The new value to write to the register. Only pins specified
* by PIN_MASK will be set.
*
* \note The outcome of this macro invocation will be to write to the register
* a new value for multiple pins. For that reason, the value argument cannot be
* a simple 0 or 1. Instead, it must be the value corresponding to the pins that
* you wish to set.
*
* Thus, if you only want to set a single pin (e.g. pin 2), do \e not pass 1,
* but you must pass 0x04 instead (1 << 2). This may seem counter-intuitive at
* first glance, but it allows a single invocation of this macro to set
* multiple pins in one go if so desired. For example, you can set pins 3 and 1
* and the same time clear pins 2 and 0. To do so, pass 0x0F as the PIN_MASK
* and then use 0x0A as the value ((1 << 3) | (1 << 1) for pins 3 and 1)
*/
#define GPIO_WRITE_PIN(PORT_BASE, PIN_MASK, value) \
do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = (value); } while(0)
/** \brief Read pins with PIN_MASK of port with PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
* \return The value of the pins specified by PIN_MASK
*
* This macro will \e not return 0 or 1. Instead, it will return the values of
* the pins specified by PIN_MASK ORd together. Thus, if you pass 0xC3
* (0x80 | 0x40 | 0x02 | 0x01) as the PIN_MASK and pins 7 and 0 are high,
* the macro will return 0x81.
*/
#define GPIO_READ_PIN(PORT_BASE, PIN_MASK) \
REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2))
/** \brief Set pins with PIN_MASK of port with PORT_BASE to detect edge.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IS) &= ~(PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to detect level.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DETECT_LEVEL(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IS) |= (PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
* interrupt on both edges.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_TRIGGER_BOTH_EDGES(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IBE) |= (PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
* interrupt on single edge (controlled by GPIO_IEV).
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IBE) &= ~(PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
* interrupt on rising edge.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DETECT_RISING(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IEV) |= (PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an
* interrupt on falling edge.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DETECT_FALLING(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IEV) &= ~(PIN_MASK); } while(0)
/** \brief Enable interrupt triggering for pins with PIN_MASK of port with
* PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IE) |= (PIN_MASK); } while(0)
/** \brief Disable interrupt triggering for pins with PIN_MASK of port with
* PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IE) &= ~(PIN_MASK); } while(0)
/** \brief Get raw interrupt status of port with PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \return Bit-mask reflecting the raw interrupt status of all the port pins
*
* The bits set in the returned bit-mask reflect the status of the interrupts
* trigger conditions detected (raw, before interrupt masking), indicating that
* all the requirements are met, before they are finally allowed to trigger by
* the interrupt mask. The bits cleared indicate that corresponding input pins
* have not initiated an interrupt.
*/
#define GPIO_GET_RAW_INT_STATUS(PORT_BASE) \
REG((PORT_BASE) + GPIO_RIS)
/** \brief Get masked interrupt status of port with PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \return Bit-mask reflecting the masked interrupt status of all the port pins
*
* The bits set in the returned bit-mask reflect the status of input lines
* triggering an interrupt. The bits cleared indicate that either no interrupt
* has been generated, or the interrupt is masked. This is the state of the
* interrupt after interrupt masking.
*/
#define GPIO_GET_MASKED_INT_STATUS(PORT_BASE) \
REG((PORT_BASE) + GPIO_MIS)
/** \brief Clear interrupt triggering for pins with PIN_MASK of port with
* PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_CLEAR_INTERRUPT(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_IC) = (PIN_MASK); } while(0)
/** \brief Configure the pin to be under peripheral control with PIN_MASK of
* port with PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_PERIPHERAL_CONTROL(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_AFSEL) |= (PIN_MASK); } while(0)
/** \brief Configure the pin to be software controlled with PIN_MASK of port
* with PORT_BASE.
* \param PORT_BASE GPIO Port register offset
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK) \
do { REG((PORT_BASE) + GPIO_AFSEL) &= ~(PIN_MASK); } while(0)
/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt
* on rising edge.
* \param PORT GPIO Port (not port base address)
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_POWER_UP_ON_RISING(PORT, PIN_MASK) \
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) &= \
~((PIN_MASK) << ((PORT) << 3)); } while(0)
/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt
* on falling edge.
* \param PORT GPIO Port (not port base address)
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_POWER_UP_ON_FALLING(PORT, PIN_MASK) \
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) |= \
(PIN_MASK) << ((PORT) << 3); } while(0)
/** \brief Enable power-up interrupt triggering for pins with PIN_MASK of port
* PORT.
* \param PORT GPIO Port (not port base address)
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_ENABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) |= \
(PIN_MASK) << ((PORT) << 3); } while(0)
/** \brief Disable power-up interrupt triggering for pins with PIN_MASK of port
* PORT.
* \param PORT GPIO Port (not port base address)
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_DISABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) &= \
~((PIN_MASK) << ((PORT) << 3)); } while(0)
/** \brief Get power-up interrupt status of port PORT.
* \param PORT GPIO Port (not port base address)
* \return Bit-mask reflecting the power-up interrupt status of all the port
* pins
*/
#define GPIO_GET_POWER_UP_INT_STATUS(PORT) \
((REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) >> ((PORT) << 3)) & 0xFF)
/** \brief Clear power-up interrupt triggering for pins with PIN_MASK of port
* PORT.
* \param PORT GPIO Port (not port base address)
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
*/
#define GPIO_CLEAR_POWER_UP_INTERRUPT(PORT, PIN_MASK) \
do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) = \
(PIN_MASK) << ((PORT) << 3); } while(0)
/**
* \brief Converts a pin number to a pin mask
* \param PIN The pin number in the range [0..7]
* \return A pin mask which can be used as the PIN_MASK argument of the macros
* in this category
*/
#define GPIO_PIN_MASK(PIN) (1 << (PIN))
/**
* \brief Converts a port number to the port base address
* \param PORT The port number in the range 0 - 3. Likely GPIO_X_NUM.
* \return The base address for the registers corresponding to that port
* number.
*/
#define GPIO_PORT_TO_BASE(PORT) (GPIO_A_BASE + ((PORT) << 12))
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO Register offset declarations
* @{
*/
#define GPIO_DATA 0x00000000 /**< Data register */
#define GPIO_DIR 0x00000400 /**< Data direction register */
#define GPIO_IS 0x00000404 /**< Interrupt sense */
#define GPIO_IBE 0x00000408 /**< Interrupt both edges */
#define GPIO_IEV 0x0000040C /**< Interrupt event */
#define GPIO_IE 0x00000410 /**< Interrupt mask */
#define GPIO_RIS 0x00000414 /**< Interrupt status - raw */
#define GPIO_MIS 0x00000418 /**< Interrupt status - masked */
#define GPIO_IC 0x0000041C /**< Interrupt clear */
#define GPIO_AFSEL 0x00000420 /**< Mode control select */
#define GPIO_GPIOLOCK 0x00000520 /**< GPIO commit unlock */
#define GPIO_GPIOCR 0x00000524 /**< GPIO commit */
#define GPIO_PMUX 0x00000700 /**< PMUX register */
#define GPIO_P_EDGE_CTRL 0x00000704 /**< Port edge control */
#define GPIO_USB_CTRL 0x00000708 /**< USB input power-up edge ctrl */
#define GPIO_PI_IEN 0x00000710 /**< Power-up interrupt enable */
#define GPIO_IRQ_DETECT_ACK 0x00000718 /**< IRQ detect ACK - I/O ports */
#define GPIO_USB_IRQ_ACK 0x0000071C /**< IRQ detect ACK - USB */
#define GPIO_IRQ_DETECT_UNMASK 0x00000720 /**< IRQ detect ACK - masked */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_DATA register bit masks
* @{
*/
#define GPIO_DATA_DATA 0x000000FF /**< Input and output data */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_DIR register bit masks
* @{
*/
#define GPIO_DIR_DIR 0x000000FF /**< Pin Input (0) / Output (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IS register bit masks
* @{
*/
#define GPIO_IS_IS 0x000000FF /**< Detect Edge (0) / Level (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IBE register bit masks
* @{
*/
#define GPIO_IBE_IBE 0x000000FF /**< Both Edges (1) / Single (0) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IEV register bit masks
* @{
*/
#define GPIO_IEV_IEV 0x000000FF /**< Rising (1) / Falling (0) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IE register bit masks
* @{
*/
#define GPIO_IE_IE 0x000000FF /**< Masked (0) / Not Masked (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_RIS register bit masks
* @{
*/
#define GPIO_RIS_RIS 0x000000FF /**< Raw interrupt status */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_MIS register bit masks
* @{
*/
#define GPIO_MIS_MIS 0x000000FF /**< Masked interrupt status */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IC register bit masks
* @{
*/
#define GPIO_IC_IC 0x000000FF /**< Clear edge detection (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_AFSEL register bit masks
* @{
*/
#define GPIO_AFSEL_AFSEL 0x000000FF /**< Software (0) / Peripheral (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_GPIOLOCK register bit masks
* @{
*/
#define GPIO_GPIOLOCK_LOCK 0xFFFFFFFF /**< Locked (1) / Unlocked (0) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_GPIOCR register bit masks
* @{
*/
#define GPIO_GPIOCR_CR 0x000000FF /**< Allow alternate function (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_PMUX register bit masks
* @{
*/
#define GPIO_PMUX_CKOEN 0x00000080 /**< Clock out enable */
#define GPIO_PMUX_CKOPIN 0x00000010 /**< Decouple control pin select */
#define GPIO_PMUX_DCEN 0x00000008 /**< Decouple control enable */
#define GPIO_PMUX_DCPIN 0x00000001 /**< Decouple control pin select */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_P_EDGE_CTRL register bit masks.
* \brief Rising (0) / Falling (1)
* @{
*/
#define GPIO_P_EDGE_CTRL_PDIRC7 0x80000000 /**< Port D bit 7 */
#define GPIO_P_EDGE_CTRL_PDIRC6 0x40000000 /**< Port D bit 6 */
#define GPIO_P_EDGE_CTRL_PDIRC5 0x20000000 /**< Port D bit 5 */
#define GPIO_P_EDGE_CTRL_PDIRC4 0x10000000 /**< Port D bit 4 */
#define GPIO_P_EDGE_CTRL_PDIRC3 0x08000000 /**< Port D bit 3 */
#define GPIO_P_EDGE_CTRL_PDIRC2 0x04000000 /**< Port D bit 2 */
#define GPIO_P_EDGE_CTRL_PDIRC1 0x02000000 /**< Port D bit 1 */
#define GPIO_P_EDGE_CTRL_PDIRC0 0x01000000 /**< Port D bit 0 */
#define GPIO_P_EDGE_CTRL_PCIRC7 0x00800000 /**< Port C bit 7 */
#define GPIO_P_EDGE_CTRL_PCIRC6 0x00400000 /**< Port C bit 6 */
#define GPIO_P_EDGE_CTRL_PCIRC5 0x00200000 /**< Port C bit 5 */
#define GPIO_P_EDGE_CTRL_PCIRC4 0x00100000 /**< Port C bit 4 */
#define GPIO_P_EDGE_CTRL_PCIRC3 0x00080000 /**< Port C bit 3 */
#define GPIO_P_EDGE_CTRL_PCIRC2 0x00040000 /**< Port C bit 2 */
#define GPIO_P_EDGE_CTRL_PCIRC1 0x00020000 /**< Port C bit 1 */
#define GPIO_P_EDGE_CTRL_PCIRC0 0x00010000 /**< Port C bit 0 */
#define GPIO_P_EDGE_CTRL_PBIRC7 0x00008000 /**< Port B bit 7 */
#define GPIO_P_EDGE_CTRL_PBIRC6 0x00004000 /**< Port B bit 6 */
#define GPIO_P_EDGE_CTRL_PBIRC5 0x00002000 /**< Port B bit 5 */
#define GPIO_P_EDGE_CTRL_PBIRC4 0x00001000 /**< Port B bit 4 */
#define GPIO_P_EDGE_CTRL_PBIRC3 0x00000800 /**< Port B bit 3 */
#define GPIO_P_EDGE_CTRL_PBIRC2 0x00000400 /**< Port B bit 2 */
#define GPIO_P_EDGE_CTRL_PBIRC1 0x00000200 /**< Port B bit 1 */
#define GPIO_P_EDGE_CTRL_PBIRC0 0x00000100 /**< Port B bit 0 */
#define GPIO_P_EDGE_CTRL_PAIRC7 0x00000080 /**< Port A bit 7 */
#define GPIO_P_EDGE_CTRL_PAIRC6 0x00000040 /**< Port A bit 6 */
#define GPIO_P_EDGE_CTRL_PAIRC5 0x00000020 /**< Port A bit 5 */
#define GPIO_P_EDGE_CTRL_PAIRC4 0x00000010 /**< Port A bit 4 */
#define GPIO_P_EDGE_CTRL_PAIRC3 0x00000008 /**< Port A bit 3 */
#define GPIO_P_EDGE_CTRL_PAIRC2 0x00000004 /**< Port A bit 2 */
#define GPIO_P_EDGE_CTRL_PAIRC1 0x00000002 /**< Port A bit 1 */
#define GPIO_P_EDGE_CTRL_PAIRC0 0x00000001 /**< Port A bit 0 */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_USB_CTRL register bit masks
* @{
*/
#define GPIO_USB_CTRL_USB_EDGE_CTL 0x00000001 /**< Rising (0) / Falling (1) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_PI_IEN register bit masks.
* \brief Enabled (1) / Disabled (0)
* @{
*/
#define GPIO_PI_IEN_PDIEN7 0x80000000 /**< Port D bit 7 */
#define GPIO_PI_IEN_PDIEN6 0x40000000 /**< Port D bit 6 */
#define GPIO_PI_IEN_PDIEN5 0x20000000 /**< Port D bit 5 */
#define GPIO_PI_IEN_PDIEN4 0x10000000 /**< Port D bit 4 */
#define GPIO_PI_IEN_PDIEN3 0x08000000 /**< Port D bit 3 */
#define GPIO_PI_IEN_PDIEN2 0x04000000 /**< Port D bit 2 */
#define GPIO_PI_IEN_PDIEN1 0x02000000 /**< Port D bit 1 */
#define GPIO_PI_IEN_PDIEN0 0x01000000 /**< Port D bit 0 */
#define GPIO_PI_IEN_PCIEN7 0x00800000 /**< Port C bit 7 */
#define GPIO_PI_IEN_PCIEN6 0x00400000 /**< Port C bit 6 */
#define GPIO_PI_IEN_PCIEN5 0x00200000 /**< Port C bit 5 */
#define GPIO_PI_IEN_PCIEN4 0x00100000 /**< Port C bit 4 */
#define GPIO_PI_IEN_PCIEN3 0x00080000 /**< Port C bit 3 */
#define GPIO_PI_IEN_PCIEN2 0x00040000 /**< Port C bit 2 */
#define GPIO_PI_IEN_PCIEN1 0x00020000 /**< Port C bit 1 */
#define GPIO_PI_IEN_PCIEN0 0x00010000 /**< Port C bit 0 */
#define GPIO_PI_IEN_PBIEN7 0x00008000 /**< Port B bit 7 */
#define GPIO_PI_IEN_PBIEN6 0x00004000 /**< Port B bit 6 */
#define GPIO_PI_IEN_PBIEN5 0x00002000 /**< Port B bit 5 */
#define GPIO_PI_IEN_PBIEN4 0x00001000 /**< Port B bit 4 */
#define GPIO_PI_IEN_PBIEN3 0x00000800 /**< Port B bit 3 */
#define GPIO_PI_IEN_PBIEN2 0x00000400 /**< Port B bit 2 */
#define GPIO_PI_IEN_PBIEN1 0x00000200 /**< Port B bit 1 */
#define GPIO_PI_IEN_PBIEN0 0x00000100 /**< Port B bit 0 */
#define GPIO_PI_IEN_PAIEN7 0x00000080 /**< Port A bit 7 */
#define GPIO_PI_IEN_PAIEN6 0x00000040 /**< Port A bit 6 */
#define GPIO_PI_IEN_PAIEN5 0x00000020 /**< Port A bit 5 */
#define GPIO_PI_IEN_PAIEN4 0x00000010 /**< Port A bit 4 */
#define GPIO_PI_IEN_PAIEN3 0x00000008 /**< Port A bit 3 */
#define GPIO_PI_IEN_PAIEN2 0x00000004 /**< Port A bit 2 */
#define GPIO_PI_IEN_PAIEN1 0x00000002 /**< Port A bit 1 */
#define GPIO_PI_IEN_PAIEN0 0x00000001 /**< Port A bit 0 */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IRQ_DETECT_ACK register bit masks
* \brief Detected (1) / Undetected (0)
* @{
*/
#define GPIO_IRQ_DETECT_ACK_PDIACK7 0x80000000 /**< Port D bit 7 */
#define GPIO_IRQ_DETECT_ACK_PDIACK6 0x40000000 /**< Port D bit 6 */
#define GPIO_IRQ_DETECT_ACK_PDIACK5 0x20000000 /**< Port D bit 5 */
#define GPIO_IRQ_DETECT_ACK_PDIACK4 0x10000000 /**< Port D bit 4 */
#define GPIO_IRQ_DETECT_ACK_PDIACK3 0x08000000 /**< Port D bit 3 */
#define GPIO_IRQ_DETECT_ACK_PDIACK2 0x04000000 /**< Port D bit 2 */
#define GPIO_IRQ_DETECT_ACK_PDIACK1 0x02000000 /**< Port D bit 1 */
#define GPIO_IRQ_DETECT_ACK_PDIACK0 0x01000000 /**< Port D bit 0 */
#define GPIO_IRQ_DETECT_ACK_PCIACK7 0x00800000 /**< Port C bit 7 */
#define GPIO_IRQ_DETECT_ACK_PCIACK6 0x00400000 /**< Port C bit 6 */
#define GPIO_IRQ_DETECT_ACK_PCIACK5 0x00200000 /**< Port C bit 5 */
#define GPIO_IRQ_DETECT_ACK_PCIACK4 0x00100000 /**< Port C bit 4 */
#define GPIO_IRQ_DETECT_ACK_PCIACK3 0x00080000 /**< Port C bit 3 */
#define GPIO_IRQ_DETECT_ACK_PCIACK2 0x00040000 /**< Port C bit 2 */
#define GPIO_IRQ_DETECT_ACK_PCIACK1 0x00020000 /**< Port C bit 1 */
#define GPIO_IRQ_DETECT_ACK_PCIACK0 0x00010000 /**< Port C bit 0 */
#define GPIO_IRQ_DETECT_ACK_PBIACK7 0x00008000 /**< Port B bit 7 */
#define GPIO_IRQ_DETECT_ACK_PBIACK6 0x00004000 /**< Port B bit 6 */
#define GPIO_IRQ_DETECT_ACK_PBIACK5 0x00002000 /**< Port B bit 5 */
#define GPIO_IRQ_DETECT_ACK_PBIACK4 0x00001000 /**< Port B bit 4 */
#define GPIO_IRQ_DETECT_ACK_PBIACK3 0x00000800 /**< Port B bit 3 */
#define GPIO_IRQ_DETECT_ACK_PBIACK2 0x00000400 /**< Port B bit 2 */
#define GPIO_IRQ_DETECT_ACK_PBIACK1 0x00000200 /**< Port B bit 1 */
#define GPIO_IRQ_DETECT_ACK_PBIACK0 0x00000100 /**< Port B bit 0 */
#define GPIO_IRQ_DETECT_ACK_PAIACK7 0x00000080 /**< Port A bit 7 */
#define GPIO_IRQ_DETECT_ACK_PAIACK6 0x00000040 /**< Port A bit 6 */
#define GPIO_IRQ_DETECT_ACK_PAIACK5 0x00000020 /**< Port A bit 5 */
#define GPIO_IRQ_DETECT_ACK_PAIACK4 0x00000010 /**< Port A bit 4 */
#define GPIO_IRQ_DETECT_ACK_PAIACK3 0x00000008 /**< Port A bit 3 */
#define GPIO_IRQ_DETECT_ACK_PAIACK2 0x00000004 /**< Port A bit 2 */
#define GPIO_IRQ_DETECT_ACK_PAIACK1 0x00000002 /**< Port A bit 1 */
#define GPIO_IRQ_DETECT_ACK_PAIACK0 0x00000001 /**< Port A bit 0 */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_USB_IRQ_ACK register bit masks
* @{
*/
#define GPIO_USB_IRQ_ACK_USBACK 0x00000001 /**< Detected (1) / Not detected (0) */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name GPIO_IRQ_DETECT_UNMASK register bit masks.
* \brief Detected (1) / Not detected (0)
* @{
*/
#define GPIO_IRQ_DETECT_UNMASK_PDIACK7 0x80000000 /**< Port D bit 7 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK6 0x40000000 /**< Port D bit 6 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK5 0x20000000 /**< Port D bit 5 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK4 0x10000000 /**< Port D bit 4 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK3 0x08000000 /**< Port D bit 3 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK2 0x04000000 /**< Port D bit 2 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK1 0x02000000 /**< Port D bit 1 */
#define GPIO_IRQ_DETECT_UNMASK_PDIACK0 0x01000000 /**< Port D bit 0 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK7 0x00800000 /**< Port C bit 7 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK6 0x00400000 /**< Port C bit 6 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK5 0x00200000 /**< Port C bit 5 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK4 0x00100000 /**< Port C bit 4 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK3 0x00080000 /**< Port C bit 3 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK2 0x00040000 /**< Port C bit 2 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK1 0x00020000 /**< Port C bit 1 */
#define GPIO_IRQ_DETECT_UNMASK_PCIACK0 0x00010000 /**< Port C bit 0 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK7 0x00008000 /**< Port B bit 7 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK6 0x00004000 /**< Port B bit 6 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK5 0x00002000 /**< Port B bit 5 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK4 0x00001000 /**< Port B bit 4 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK3 0x00000800 /**< Port B bit 3 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK2 0x00000400 /**< Port B bit 2 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK1 0x00000200 /**< Port B bit 1 */
#define GPIO_IRQ_DETECT_UNMASK_PBIACK0 0x00000100 /**< Port B bit 0 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK7 0x00000080 /**< Port A bit 7 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK6 0x00000040 /**< Port A bit 6 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK5 0x00000020 /**< Port A bit 5 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK4 0x00000010 /**< Port A bit 4 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK3 0x00000008 /**< Port A bit 3 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK2 0x00000004 /**< Port A bit 2 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK1 0x00000002 /**< Port A bit 1 */
#define GPIO_IRQ_DETECT_UNMASK_PAIACK0 0x00000001 /**< Port A bit 0 */
/** @} */
/*---------------------------------------------------------------------------*/
/** \brief Initialise the GPIO module */
void gpio_init();
/**
* \brief Register GPIO callback
* \param f Pointer to a function to be called when \a pin of \a port
* generates an interrupt
* \param port Associate \a f with this port. \e port must be specified with
* its numeric representation (Port A:0, B:1 etc). Defines for these
* numeric representations are GPIO_x_NUM
* \param pin Associate \a f with this pin, which is specified by number
* (0, 1, ..., 7)
*/
void gpio_register_callback(gpio_callback_t f, uint8_t port, uint8_t pin);
#endif /* GPIO_H_ */
/**
* @}
* @}
*/