mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu, cc2538: refine gpio handling
- hide (more) internal functions - optimize gpio_init_af - remove obsolete code
This commit is contained in:
parent
e01c23ef35
commit
8fb71afa79
@ -55,7 +55,7 @@ enum {
|
||||
*
|
||||
* @return A bit mask in which bit n is high.
|
||||
*/
|
||||
#define GPIO_PIN_MASK(n) ( 1 << (n) )
|
||||
#define PIN_MASK(n) ( 1 << (n) )
|
||||
|
||||
/**
|
||||
* @brief Extract the GPIO port number (0-3) from a GPIO number (0-31)
|
||||
@ -99,28 +99,28 @@ enum {
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define gpio_hardware_control(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->AFSEL |= GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
#define gpio_hardware_control(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->AFSEL |= PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Enable software control for a given GPIO pin number
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define gpio_software_control(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->AFSEL &= ~GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
#define gpio_software_control(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->AFSEL &= ~PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Configure the given GPIO as an output
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define gpio_dir_output(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DIR |= GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
#define gpio_dir_output(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DIR |= PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Configure the given GPIO as an input
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define gpio_dir_input(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DIR &= ~GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
#define gpio_dir_input(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DIR &= ~PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Read the value of the given pin
|
||||
@ -129,28 +129,17 @@ enum {
|
||||
*/
|
||||
#define cc2538_gpio_read(gpio_num) ( (GPIO_NUM_TO_DEV(gpio_num)->DATA >> GPIO_BIT_NUM(gpio_num)) & 1 )
|
||||
|
||||
/**
|
||||
* @brief Set a specific GPIO output pin high
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define cc2538_gpio_set(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DATA |= GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Set a specific GPIO output pin low
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define cc2538_gpio_clear(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DATA &= ~GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
#define cc2538_gpio_clear(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DATA &= ~PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/**
|
||||
* @brief Toggle the output state of a specific GPIO pin
|
||||
*
|
||||
* @param[in] gpio_num GPIO number (0-31)
|
||||
*/
|
||||
#define cc2538_gpio_toggle(gpio_num) ( GPIO_NUM_TO_DEV(gpio_num)->DATA ^= GPIO_PIN_MASK(GPIO_BIT_NUM(gpio_num)) )
|
||||
|
||||
/** @name Unique names for each GPIO port/pin combination
|
||||
* @name Unique names for each GPIO port/pin combination
|
||||
* @deprecated will be removed after adaption of periph drivers,
|
||||
* use GPIO_PIN macro instead
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
@ -220,42 +209,113 @@ typedef struct {
|
||||
} cc2538_gpio_t;
|
||||
|
||||
/**
|
||||
* @brief IOC port component registers
|
||||
* @brief GPIO port instance base address
|
||||
*/
|
||||
typedef struct {
|
||||
cc2538_reg_t SEL[32]; /**< Port A to D SEL registers */
|
||||
cc2538_reg_t OVER[32]; /**< Port A OVER register */
|
||||
} cc2538_ioc_t;
|
||||
#define GPIO_BASE (0x400d9000)
|
||||
|
||||
/**
|
||||
* @name Values for IOC_PXX_SEL
|
||||
* @name GPIO shift and masking
|
||||
* @{
|
||||
*/
|
||||
#define IOC_SEL_UART0_TXD (0) /**< UART0 TXD */
|
||||
#define IOC_SEL_UART1_RTS (1) /**< UART1 RTS */
|
||||
#define IOC_SEL_UART1_TXD (2) /**< UART1 TXD */
|
||||
#define IOC_SEL_SSI0_TXD (3) /**< SSI0 TXD */
|
||||
#define IOC_SEL_SSI0_CLKOUT (4) /**< SSI0 CLKOUT */
|
||||
#define IOC_SEL_SSI0_FSSOUT (5) /**< SSI0 FSSOUT */
|
||||
#define IOC_SEL_SSI0_STXSER_EN (6) /**< SSI0 STXSER EN */
|
||||
#define IOC_SEL_SSI1_TXD (7) /**< SSI1 TXD */
|
||||
#define IOC_SEL_SSI1_CLKOUT (8) /**< SSI1 CLKOUT */
|
||||
#define IOC_SEL_SSI1_FSSOUT (9) /**< SSI1 FSSOUT */
|
||||
#define IOC_SEL_SSI1_STXSER_EN (10) /**< SSI1 STXSER EN */
|
||||
#define IOC_SEL_I2C_CMSSDA (11) /**< I2C CMSSDA */
|
||||
#define IOC_SEL_I2C_CMSSCL (12) /**< I2C CMSSCL */
|
||||
#define IOC_SEL_GPT0_ICP1 (13) /**< GPT0 ICP1 */
|
||||
#define IOC_SEL_GPT0_ICP2 (14) /**< GPT0 ICP2 */
|
||||
#define IOC_SEL_GPT1_ICP1 (15) /**< GPT1 ICP1 */
|
||||
#define IOC_SEL_GPT1_ICP2 (16) /**< GPT1 ICP2 */
|
||||
#define IOC_SEL_GPT2_ICP1 (17) /**< GPT2 ICP1 */
|
||||
#define IOC_SEL_GPT2_ICP2 (18) /**< GPT2 ICP2 */
|
||||
#define IOC_SEL_GPT3_ICP1 (19) /**< GPT3 ICP1 */
|
||||
#define IOC_SEL_GPT3_ICP2 (20) /**< GPT3 ICP2 */
|
||||
#define GPIO_PORTNUM_SHIFT (12U) /**< bit shift for GPIO port */
|
||||
#define GPIO_PORTNUM_MASK (0x00007000) /**< bit mask for GPIO port [0-3] */
|
||||
#define GPIO_PIN_MASK (0x00000007) /**< bit mask for GPIO pin [0-7] */
|
||||
#define GPIO_PORT_MASK (0xfffff000) /**< bit mask for GPIO port addr */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name GPIO instance definitions
|
||||
* @deprecated will be removed after adaption of periph drivers
|
||||
* @{
|
||||
*/
|
||||
#define GPIO_A ((cc2538_gpio_t *)0x400d9000) /**< GPIO Port A instance */
|
||||
#define GPIO_B ((cc2538_gpio_t *)0x400da000) /**< GPIO Port B instance */
|
||||
#define GPIO_C ((cc2538_gpio_t *)0x400db000) /**< GPIO Port C instance */
|
||||
#define GPIO_D ((cc2538_gpio_t *)0x400dc000) /**< GPIO Port D instance */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief IOC port component registers
|
||||
*/
|
||||
typedef struct {
|
||||
cc2538_reg_t SEL[32]; /**< select special function for output pin*/
|
||||
cc2538_reg_t OVER[32]; /**< override pin mode, enable alternate mode */
|
||||
cc2538_reg_t PINS[21]; /**< select input pin for special functions */
|
||||
} cc2538_ioc_t;
|
||||
|
||||
/**
|
||||
* @name Peripheral Signal Select Values (for IOC_Pxx_SEL registers)
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
UART0_TXD = 0, /**< UART0 TXD */
|
||||
UART1_RTS, /**< UART1 RTS */
|
||||
UART1_TXD, /**< UART1 TXD */
|
||||
SSI0_TXD, /**< SSI0 TXD */
|
||||
SSI0_CLK_OUT, /**< SSI0 CLKOUT */
|
||||
SSI0_FSS_OUT, /**< SSI0 FSSOUT */
|
||||
SSI0_TX_SER, /**< SSI0 STXSER EN */
|
||||
SSI1_TXD, /**< SSI1 TXD */
|
||||
SSI1_CLK_OUT, /**< SSI1 CLKOUT */
|
||||
SSI1_FSS_OUT, /**< SSI1 FSSOUT */
|
||||
SSI1_TX_SER, /**< SSI1 STXSER EN */
|
||||
I2C_SDA_OUT, /**< I2C CMSSDA */
|
||||
I2C_SCL_OUT, /**< I2C CMSSCL */
|
||||
GPT0_ICP1, /**< GPT0 ICP1 */
|
||||
GPT0_ICP2, /**< GPT0 ICP2 */
|
||||
GPT1_ICP1, /**< GPT1 ICP1 */
|
||||
GPT1_ICP2, /**< GPT1 ICP2 */
|
||||
GPT2_ICP1, /**< GPT2 ICP1 */
|
||||
GPT2_ICP2, /**< GPT2 ICP2 */
|
||||
GPT3_ICP1, /**< GPT3 ICP1 */
|
||||
GPT3_ICP2 , /**< GPT3 ICP2 */
|
||||
} cc2538_ioc_sel_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Pin select for periphical functions
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
UART0_RXD = 0, /**< UART0 RXD */
|
||||
UART1_CTS, /**< UART1 CTS */
|
||||
UART1_RXD, /**< UART1 RXD */
|
||||
SSI0_CLK, /**< SSI0 CLK */
|
||||
SSI0_RXD, /**< SSI0 RXD */
|
||||
SSI0_FSS_IN, /**< SSI0 FSS IN */
|
||||
SSI0_CLK_IN, /**< SSI0 CLK IN */
|
||||
SSI1_CLK, /**< SSI1 CLK */
|
||||
SSI1_RXD, /**< SSI1 RXD */
|
||||
SSI1_FSS_IN, /**< SSI1 FSS IN */
|
||||
SSI1_CLK_IN, /**< SSI1 CLK IN */
|
||||
I2C_SDA_IN, /**< I2C SDA IN */
|
||||
I2C_SCL_IN, /**< I2C SCL IN */
|
||||
GPT0_OCP1, /**< GPT0 OCP1 */
|
||||
GPT0_OCP2, /**< GPT0 OCP2 */
|
||||
GPT1_OCP1, /**< GPT1 OCP1 */
|
||||
GPT1_OCP2, /**< GPT1 OCP2 */
|
||||
GPT2_OCP1, /**< GPT2 OCP1 */
|
||||
GPT2_OCP2, /**< GPT2 OCP2 */
|
||||
GPT3_OCP1, /**< GPT3 OCP1 */
|
||||
GPT3_OCP2, /**< GPT3 OCP2 */
|
||||
} cc2538_ioc_pin_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Values to override pin configuration
|
||||
*/
|
||||
typedef enum {
|
||||
OVERRIDE_DISABLE = 0x0,
|
||||
OVERRIDE_ANALOG = 0x1,
|
||||
OVERRIDE_PULLDOWN = 0x2,
|
||||
OVERRIDE_PULLUP = 0x4,
|
||||
OVERRIDE_ENABLE = 0x8,
|
||||
} cc2538_ioc_over_t;
|
||||
|
||||
/**
|
||||
* @name Values for IOC_PXX_OVER
|
||||
* @deprecated will be removed after adaption of periph drivers,
|
||||
* use cc2538_ioc_over_t instead
|
||||
* @{
|
||||
*/
|
||||
#define IOC_OVERRIDE_OE 0x00000008 /**< Output Enable */
|
||||
@ -266,20 +326,18 @@ typedef struct {
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name GPIO instance definitions
|
||||
* @{
|
||||
* @brief IOC instance definition
|
||||
*/
|
||||
#define GPIO_A ((cc2538_gpio_t *)0x400d9000) /**< GPIO Port A instance */
|
||||
#define GPIO_B ((cc2538_gpio_t *)0x400da000) /**< GPIO Port B instance */
|
||||
#define GPIO_C ((cc2538_gpio_t *)0x400db000) /**< GPIO Port C instance */
|
||||
#define GPIO_D ((cc2538_gpio_t *)0x400dc000) /**< GPIO Port D instance */
|
||||
/** @} */
|
||||
#define IOC ((cc2538_ioc_t *)0x400d4000)
|
||||
|
||||
/**
|
||||
* @name IOC instance definition
|
||||
* @name Port control register addresses
|
||||
* @deprecated will be removed after adaption of periph drivers,
|
||||
* use IOC->OVER and IOC->SEL instead
|
||||
* @{
|
||||
*/
|
||||
#define IOC ((cc2538_ioc_t *)0x400d4000) /**< IOC instance */
|
||||
#define IOC_PXX_OVER (IOC->OVER)
|
||||
#define IOC_PXX_SEL (IOC->SEL)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Loci Controls Inc.
|
||||
*
|
||||
* 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 cpu_cc2538_ioc CC2538 I/O Control
|
||||
* @ingroup cpu_cc2538_regs
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CC2538 I/O Control driver
|
||||
*
|
||||
* Header file with declarations for the I/O Control module
|
||||
*
|
||||
* @author Ian Martin <ian@locicontrols.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CC2538_IOC_H
|
||||
#define CC2538_IOC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cc2538.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Port control register addresses
|
||||
* @{
|
||||
*/
|
||||
#define IOC_PXX_SEL ( (cc2538_reg_t*)0x400d4000 )
|
||||
#define IOC_PXX_OVER ( (cc2538_reg_t*)0x400d4080 )
|
||||
/** @} */
|
||||
|
||||
/** @name Peripheral Signal Select Values (for IOC_Pxx_SEL registers)
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
UART0_TXD = 0, /**< UART0 TXD */
|
||||
UART1_RTS = 1, /**< UART1 RTS */
|
||||
UART1_TXD = 2, /**< UART1 TXD */
|
||||
SSI0_TXD = 3, /**< SSI0 TXD */
|
||||
SSI0_CLKOUT = 4, /**< SSI0 CLKOUT */
|
||||
SSI0_FSSOUT = 5, /**< SSI0 FSSOUT */
|
||||
SSI0_STXSER_EN = 6, /**< SSI0 STXSER EN */
|
||||
SSI1_TXD = 7, /**< SSI1 TXD */
|
||||
SSI1_CLKOUT = 8, /**< SSI1 CLKOUT */
|
||||
SSI1_FSSOUT = 9, /**< SSI1 FSSOUT */
|
||||
SSI1_STXSER_EN = 10, /**< SSI1 STXSER EN */
|
||||
I2C_CMSSDA = 11, /**< I2C CMSSDA */
|
||||
I2C_CMSSCL = 12, /**< I2C CMSSCL */
|
||||
GPT0_ICP1 = 13, /**< GPT0 ICP1 */
|
||||
GPT0_ICP2 = 14, /**< GPT0 ICP2 */
|
||||
GPT1_ICP1 = 15, /**< GPT1 ICP1 */
|
||||
GPT1_ICP2 = 16, /**< GPT1 ICP2 */
|
||||
GPT2_ICP1 = 17, /**< GPT2 ICP1 */
|
||||
GPT2_ICP2 = 18, /**< GPT2 ICP2 */
|
||||
GPT3_ICP1 = 19, /**< GPT3 ICP1 */
|
||||
GPT3_ICP2 = 20, /**< GPT3 ICP2 */
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Values for IOC_PXX_OVER
|
||||
* @{
|
||||
*/
|
||||
#define IOC_OVERRIDE_OE 0x00000008 /**< Output Enable */
|
||||
#define IOC_OVERRIDE_PUE 0x00000004 /**< Pull Up Enable */
|
||||
#define IOC_OVERRIDE_PDE 0x00000002 /**< Pull Down Enable */
|
||||
#define IOC_OVERRIDE_ANA 0x00000001 /**< Analog Enable */
|
||||
#define IOC_OVERRIDE_DIS 0x00000000 /**< Override Disabled */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* CC2538_IOC_H */
|
||||
/** @} */
|
@ -24,7 +24,6 @@
|
||||
#include "cc2538_gpio.h"
|
||||
#include "cc2538_uart.h"
|
||||
#include "cc2538_gptimer.h"
|
||||
#include "cc2538_ioc.h"
|
||||
#include "cc2538_soc_adc.h"
|
||||
#include "cc2538_ssi.h"
|
||||
#include "cc2538_rfcore.h"
|
||||
|
@ -34,13 +34,14 @@ extern "C" {
|
||||
* @brief Starting offset of CPU_ID
|
||||
*/
|
||||
#define CPUID_ADDR (&IEEE_ADDR_MSWORD)
|
||||
|
||||
/**
|
||||
* @brief Length of the CPU_ID in octets
|
||||
*/
|
||||
#define CPUID_LEN (8U)
|
||||
|
||||
/**
|
||||
* @brief Define a custom type for GPIO pins
|
||||
* @name Define a custom type for GPIO pins
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_T
|
||||
@ -55,14 +56,9 @@ typedef uint32_t gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Internal GPIO shift and masking
|
||||
* @{
|
||||
* @brief Define custom value to speficy undefined or unused GPIOs
|
||||
*/
|
||||
#define PORTNUM_MASK (0x00007000) /**< bit mask for GPIO port [0-3] */
|
||||
#define PORTNUM_SHIFT (12U) /**< bit shift for GPIO port */
|
||||
#define PIN_MASK (0x00000007) /**< bit mask for GPIO pin [0-7] */
|
||||
#define GPIO_MASK (0xfffff000) /**< bit mask for GPIO port addr */
|
||||
/** @} */
|
||||
#define GPIO_UNDEF (0xffffffff)
|
||||
|
||||
/**
|
||||
* @brief Define a custom GPIO_PIN macro
|
||||
@ -70,82 +66,17 @@ typedef uint32_t gpio_t;
|
||||
* For the CC2538, we use OR the gpio ports base register address with the
|
||||
* actual pin number.
|
||||
*/
|
||||
#define GPIO_PIN(port, pin) (gpio_t)(((uint32_t)GPIO_A + \
|
||||
(port << PORTNUM_SHIFT)) | pin)
|
||||
|
||||
/**
|
||||
* @brief Access GPIO low-level device
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return pointer to gpio low level device address
|
||||
*/
|
||||
static inline cc2538_gpio_t *gpio(gpio_t pin)
|
||||
{
|
||||
return (cc2538_gpio_t *)(pin & GPIO_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get port number for gpio pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return port number of gpio pin, [0=A - 3=D]
|
||||
*/
|
||||
static inline uint8_t gpio_port_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)((pin & PORTNUM_MASK) >> PORTNUM_SHIFT) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get pin number for gpio pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return pin number of gpio pin, [0 - 7]
|
||||
*/
|
||||
static inline uint8_t gpio_pin_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)(pin & PIN_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get bit mask for gpio pin number
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return bit mask for gpio pin number, 2^[0 - 7]
|
||||
*/
|
||||
static inline uint32_t gpio_pin_mask(gpio_t pin)
|
||||
{
|
||||
return (1 << (pin & PIN_MASK));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get CC2538 gpio number from port and pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return number of gpio pin, [0 - 31]
|
||||
*/
|
||||
static inline uint8_t gpio_pp_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)((gpio_port_num(pin) * 8) + gpio_pin_num(pin));
|
||||
}
|
||||
#define GPIO_PIN(port, pin) (gpio_t)(((uint32_t)GPIO_BASE + \
|
||||
(port << GPIO_PORTNUM_SHIFT)) | pin)
|
||||
|
||||
/**
|
||||
* @brief Configure an alternate function for the given pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
* @param[in] sel Setting for IOC select register, (-1) to ignore
|
||||
* @param[in] over Setting for IOC override register, (-1) to ignore
|
||||
* @param[in] sel Select pin peripheral function
|
||||
* @param[in] over Override pin configuration
|
||||
*/
|
||||
void gpio_init_af(gpio_t pin, int sel, int over);
|
||||
|
||||
/**
|
||||
* @brief Define a custom GPIO_UNDEF value
|
||||
*/
|
||||
#define GPIO_UNDEF 99
|
||||
void gpio_init_af(gpio_t pin, uint8_t sel, uint8_t over);
|
||||
|
||||
/**
|
||||
* @brief I2C configuration options
|
||||
@ -171,12 +102,13 @@ typedef struct {
|
||||
*/
|
||||
#define HAVE_GPIO_MODE_T
|
||||
typedef enum {
|
||||
GPIO_IN = ((uint8_t)0x00), /**< input, no pull */
|
||||
GPIO_IN_PD = ((uint8_t)IOC_OVERRIDE_PDE), /**< input, pull-down */
|
||||
GPIO_IN_PU = ((uint8_t)IOC_OVERRIDE_PUE), /**< input, pull-up */
|
||||
GPIO_OUT = ((uint8_t)IOC_OVERRIDE_OE), /**< output */
|
||||
GPIO_OD = (0xff), /**< not supported */
|
||||
GPIO_OD_PU = (0xff) /**< not supported */
|
||||
GPIO_IN = ((uint8_t)OVERRIDE_DISABLE), /**< input, no pull */
|
||||
GPIO_IN_ANALOG = ((uint8_t)OVERRIDE_ANALOG), /**< input, analog */
|
||||
GPIO_IN_PD = ((uint8_t)OVERRIDE_PULLDOWN), /**< input, pull-down */
|
||||
GPIO_IN_PU = ((uint8_t)OVERRIDE_PULLUP), /**< input, pull-up */
|
||||
GPIO_OUT = ((uint8_t)OVERRIDE_ENABLE), /**< output */
|
||||
GPIO_OD = (0xff), /**< not supported */
|
||||
GPIO_OD_PU = (0xff) /**< not supported */
|
||||
} gpio_mode_t;
|
||||
/** @} */
|
||||
|
||||
|
@ -33,6 +33,66 @@
|
||||
|
||||
static gpio_isr_ctx_t isr_ctx[4][8];
|
||||
|
||||
/**
|
||||
* @brief Access GPIO low-level device
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return pointer to gpio low level device address
|
||||
*/
|
||||
static inline cc2538_gpio_t *gpio(gpio_t pin)
|
||||
{
|
||||
return (cc2538_gpio_t *)(pin & GPIO_PORT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get port number for gpio pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return port number of gpio pin, [0=A - 3=D]
|
||||
*/
|
||||
static inline uint8_t _port_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)((pin & GPIO_PORTNUM_MASK) >> GPIO_PORTNUM_SHIFT) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get pin number for gpio pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return pin number of gpio pin, [0 - 7]
|
||||
*/
|
||||
static inline uint8_t _pin_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)(pin & GPIO_PIN_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get bit mask for gpio pin number
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return bit mask for gpio pin number, 2^[0 - 7]
|
||||
*/
|
||||
static inline uint32_t _pin_mask(gpio_t pin)
|
||||
{
|
||||
return (1 << (pin & GPIO_PIN_MASK));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get CC2538 gpio number from port and pin
|
||||
*
|
||||
* @param[in] pin gpio pin
|
||||
*
|
||||
* @return number of gpio pin, [0 - 31]
|
||||
*/
|
||||
static inline uint8_t _pp_num(gpio_t pin)
|
||||
{
|
||||
return (uint8_t)((_port_num(pin) * GPIO_BITS_PER_PORT) + _pin_num(pin));
|
||||
}
|
||||
|
||||
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
{
|
||||
/* check if mode is valid */
|
||||
@ -40,20 +100,19 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG("GPIO %"PRIu32", PORT: %u, PIN: %u\n", (uint32_t)pin, gpio_port_num(pin), gpio_pin_num(pin));
|
||||
DEBUG("GPIO %"PRIu32", PORT: %u, PIN: %u\n", (uint32_t)pin, _port_num(pin), _pin_num(pin));
|
||||
|
||||
/* disable any alternate function and any eventual interrupts */
|
||||
gpio(pin)->IE &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->AFSEL &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->IE &= ~_pin_mask(pin);
|
||||
gpio(pin)->AFSEL &= ~_pin_mask(pin);
|
||||
/* configure pull configuration */
|
||||
IOC_PXX_OVER[gpio_pp_num(pin)] = mode;
|
||||
|
||||
IOC->OVER[_pp_num(pin)] = mode;
|
||||
/* set pin direction */
|
||||
if (mode == IOC_OVERRIDE_OE) {
|
||||
gpio(pin)->DIR |= gpio_pin_mask(pin);
|
||||
if (mode == GPIO_OUT) {
|
||||
gpio(pin)->DIR |= _pin_mask(pin);
|
||||
}
|
||||
else {
|
||||
gpio(pin)->DIR &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->DIR &= ~_pin_mask(pin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -67,88 +126,89 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
}
|
||||
|
||||
/* store the callback information for later: */
|
||||
isr_ctx[gpio_port_num(pin)][gpio_pin_num(pin)].cb = cb;
|
||||
isr_ctx[gpio_port_num(pin)][gpio_pin_num(pin)].arg = arg;
|
||||
isr_ctx[_port_num(pin)][_pin_num(pin)].cb = cb;
|
||||
isr_ctx[_port_num(pin)][_pin_num(pin)].arg = arg;
|
||||
|
||||
/* enable power-up interrupts for this GPIO port: */
|
||||
SYS_CTRL->IWE |= (1 << gpio_port_num(pin));
|
||||
SYS_CTRL->IWE |= (1 << _port_num(pin));
|
||||
|
||||
/* configure the active flank(s) */
|
||||
gpio(pin)->IS &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->IS &= ~_pin_mask(pin);
|
||||
switch(flank) {
|
||||
case GPIO_FALLING:
|
||||
gpio(pin)->IBE &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->IEV &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->P_EDGE_CTRL |= (1 << gpio_pp_num(pin));
|
||||
gpio(pin)->IBE &= ~_pin_mask(pin);
|
||||
gpio(pin)->IEV &= ~_pin_mask(pin);
|
||||
gpio(pin)->P_EDGE_CTRL |= (1 << _pp_num(pin));
|
||||
break;
|
||||
case GPIO_RISING:
|
||||
gpio(pin)->IBE &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->IEV |= gpio_pin_mask(pin);
|
||||
gpio(pin)->P_EDGE_CTRL &= ~(1 << gpio_pp_num(pin));
|
||||
gpio(pin)->IBE &= ~_pin_mask(pin);
|
||||
gpio(pin)->IEV |= _pin_mask(pin);
|
||||
gpio(pin)->P_EDGE_CTRL &= ~(1 << _pp_num(pin));
|
||||
break;
|
||||
case GPIO_BOTH:
|
||||
gpio(pin)->IBE |= gpio_pin_mask(pin);
|
||||
gpio(pin)->IBE |= _pin_mask(pin);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset interrupt status */
|
||||
gpio(pin)->IC = gpio_pin_mask(pin);
|
||||
gpio(pin)->PI_IEN |= (1 << gpio_pp_num(pin));
|
||||
gpio(pin)->IC = _pin_mask(pin);
|
||||
gpio(pin)->PI_IEN |= (1 << _pp_num(pin));
|
||||
/* enable global interrupt for the selected GPIO port */
|
||||
NVIC_EnableIRQ(GPIO_PORT_A_IRQn + gpio_port_num(pin));
|
||||
NVIC_EnableIRQ(GPIO_PORT_A_IRQn + _port_num(pin));
|
||||
/* unmask pin interrupt */
|
||||
gpio(pin)->IE |= gpio_pin_mask(pin);
|
||||
gpio(pin)->IE |= _pin_mask(pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_t pin)
|
||||
{
|
||||
gpio(pin)->IE |= gpio_pin_mask(pin);
|
||||
gpio(pin)->IE |= _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_t pin)
|
||||
{
|
||||
gpio(pin)->IE &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->IE &= ~_pin_mask(pin);
|
||||
}
|
||||
|
||||
int gpio_read(gpio_t pin)
|
||||
{
|
||||
return (int)(gpio(pin)->DATA & gpio_pin_mask(pin));
|
||||
return (int)(gpio(pin)->DATA & _pin_mask(pin));
|
||||
}
|
||||
|
||||
void gpio_set(gpio_t pin)
|
||||
{
|
||||
gpio(pin)->DATA |= gpio_pin_mask(pin);
|
||||
gpio(pin)->DATA |= _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_clear(gpio_t pin)
|
||||
{
|
||||
gpio(pin)->DATA &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->DATA &= ~_pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_toggle(gpio_t pin)
|
||||
{
|
||||
gpio(pin)->DATA ^= gpio_pin_mask(pin);
|
||||
gpio(pin)->DATA ^= _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t pin, int value)
|
||||
{
|
||||
if (value) {
|
||||
gpio(pin)->DATA |= gpio_pin_mask(pin);
|
||||
gpio(pin)->DATA |= _pin_mask(pin);
|
||||
}
|
||||
else {
|
||||
gpio(pin)->DATA &= ~gpio_pin_mask(pin);
|
||||
gpio(pin)->DATA &= ~_pin_mask(pin);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void handle_isr(cc2538_gpio_t *gpio, int port_num)
|
||||
static inline void handle_isr(uint8_t port_num)
|
||||
{
|
||||
uint32_t state = gpio->MIS;
|
||||
gpio->IC = 0x000000ff;
|
||||
gpio->IRQ_DETECT_ACK = (0xff << (port_num * GPIO_BITS_PER_PORT));
|
||||
cc2538_gpio_t *port = ((cc2538_gpio_t *)GPIO_BASE) + port_num;
|
||||
uint32_t state = port->MIS;
|
||||
port->IC = 0x000000ff;
|
||||
port->IRQ_DETECT_ACK = (0xff << (port_num * GPIO_BITS_PER_PORT));
|
||||
|
||||
for (int i = 0; i < GPIO_BITS_PER_PORT; i++) {
|
||||
if (state & (1 << i)) {
|
||||
@ -162,39 +222,40 @@ static inline void handle_isr(cc2538_gpio_t *gpio, int port_num)
|
||||
/** @brief Interrupt service routine for Port A */
|
||||
void isr_gpioa(void)
|
||||
{
|
||||
handle_isr(GPIO_A, 0);
|
||||
handle_isr(0);
|
||||
}
|
||||
|
||||
/** @brief Interrupt service routine for Port B */
|
||||
void isr_gpiob(void)
|
||||
{
|
||||
handle_isr(GPIO_B, 1);
|
||||
handle_isr(1);
|
||||
}
|
||||
|
||||
/** @brief Interrupt service routine for Port C */
|
||||
void isr_gpioc(void)
|
||||
{
|
||||
handle_isr(GPIO_C, 2);
|
||||
handle_isr(2);
|
||||
}
|
||||
|
||||
/** @brief Interrupt service routine for Port D */
|
||||
void isr_gpiod(void)
|
||||
{
|
||||
handle_isr(GPIO_D, 3);
|
||||
handle_isr(3);
|
||||
}
|
||||
|
||||
/* CC2538 specific add-on GPIO functions */
|
||||
|
||||
void gpio_init_af(gpio_t pin, int sel, int over)
|
||||
void gpio_init_af(gpio_t pin, uint8_t sel, uint8_t over)
|
||||
{
|
||||
assert(pin != GPIO_UNDEF);
|
||||
|
||||
if (over >= 0) {
|
||||
IOC_PXX_OVER[gpio_pp_num(pin)] = over;
|
||||
IOC->OVER[_pp_num(pin)] = over;
|
||||
if (over != GPIO_OUT) {
|
||||
IOC->PINS[sel] = _pp_num(pin);
|
||||
}
|
||||
if(sel >= 0) {
|
||||
IOC_PXX_SEL[gpio_pp_num(pin)] = sel;
|
||||
else {
|
||||
IOC->SEL[_pp_num(pin)] = sel;
|
||||
}
|
||||
/* enable alternative function mode */
|
||||
gpio(pin)->AFSEL |= gpio_pin_mask(pin);
|
||||
gpio(pin)->AFSEL |= _pin_mask(pin);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user