diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c index b79966c01..eb3c0e93e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c @@ -39,82 +39,110 @@ #include "k210_memorymap.h" #include "k210_gpio.h" #include "k210_fpioa.h" +#include "k210_sysctl.h" + +#define GPIO_MAX_PINNO 8 /**************************************************************************** - * Pre-processor Definitions + * Private Function declaration ****************************************************************************/ - -#define GPIO_INPUT_VAL_OFFSET 0x00 -#define GPIO_INPUT_EN_OFFSET 0x04 -#define GPIO_OUTPUT_EN_OFFSET 0x08 -#define GPIO_OUTPUT_VAL_OFFSET 0x0c -#define GPIO_PULLUP_EN_OFFSET 0x10 -#define GPIO_DRIVE_OFFSET 0x14 - -#define GPIO_INPUT (K210_GPIO_BASE + GPIO_INPUT_VAL_OFFSET) -#define GPIO_INPUT_EN (K210_GPIO_BASE + GPIO_INPUT_EN_OFFSET) -#define GPIO_OUTPUT (K210_GPIO_BASE + GPIO_OUTPUT_VAL_OFFSET) -#define GPIO_OUTPUT_EN (K210_GPIO_BASE + GPIO_OUTPUT_EN_OFFSET) +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value); +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value); +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value); +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset); +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset); /**************************************************************************** - * Public Functions + * Private Data ****************************************************************************/ -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode) +volatile gpio_t *const gpio = (volatile gpio_t *)K210_GPIO_BASE; + +/**************************************************************************** + * Private Function definition + ****************************************************************************/ +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value) { - DEBUGASSERT(io < K210_GPIO_MAX_PINNO); - int io_number = k210_fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + io); - DEBUGASSERT(io_number >= 0); - - fpioa_pull_t pull = FPIOA_PULL_NONE; - uint32_t dir = 0; - - switch (mode) - { - case GPIO_DM_INPUT: - pull = FPIOA_PULL_NONE; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_DOWN: - pull = FPIOA_PULL_DOWN; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_UP: - pull = FPIOA_PULL_UP; - dir = 0; - break; - case GPIO_DM_OUTPUT: - pull = FPIOA_PULL_DOWN; - dir = 1; - break; - default: - DEBUGASSERT(!"GPIO drive mode is not supported."); - break; - } - - fpioa_set_io_pull(io_number, pull); - uint32_t outbit = dir << io; - uint32_t inbit = (!dir) << io; - modifyreg32(GPIO_OUTPUT_EN, inbit, outbit); - modifyreg32(GPIO_INPUT_EN, outbit, inbit); + uint32_t org = (*bits) & ~mask; + *bits = org | (value & mask); } -void k210_gpio_set_value(uint32_t io, bool val) +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value) { - uint32_t setbit = val << io; - uint32_t clrbit = (!val) << io; - modifyreg32(GPIO_OUTPUT, clrbit, setbit); + set_bit(bits, mask << offset, value << offset); } -bool k210_gpio_get_value(uint32_t io) +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value) { - uint32_t reg = getreg32(GPIO_INPUT); + set_bit_offset(bits, 1, offset, value); +} - if (reg & (1 << io)) +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset) +{ + return ((*bits) & (mask << offset)) >> offset; +} + +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset) +{ + return get_bit(bits, 1, offset); +} + + +/**************************************************************************** + * Public Function definition + ****************************************************************************/ +int gpio_init(void) +{ + return sysctl_clock_enable(SYSCTL_CLOCK_GPIO); +} + +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + int io_number = fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + pin); + DEBUGASSERT(io_number >= 0); + + fpioa_pull_t pull; + uint32_t dir; + + switch(mode) { - return true; - } - else - { - return false; + case GPIO_DM_INPUT: + pull = FPIOA_PULL_NONE; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_DOWN: + pull = FPIOA_PULL_DOWN; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_UP: + pull = FPIOA_PULL_UP; + dir = 0; + break; + case GPIO_DM_OUTPUT: + pull = FPIOA_PULL_DOWN; + dir = 1; + break; + default: + break; } + + fpioa_set_io_pull(io_number, pull); + set_gpio_bit(gpio->direction.u32, pin, dir); +} + +gpio_pin_value_t gpio_get_pin(uint8_t pin) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + return get_gpio_bit(reg, pin); +} + +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + DEBUGASSERT(dir == 1); + set_gpio_bit(reg, pin, value); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h index 13d98e04d..1ac4a2ef6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h @@ -38,52 +38,127 @@ #include #include "k210_gpio_common.h" +typedef struct _gpio_bits +{ + uint32_t b0 : 1; + uint32_t b1 : 1; + uint32_t b2 : 1; + uint32_t b3 : 1; + uint32_t b4 : 1; + uint32_t b5 : 1; + uint32_t b6 : 1; + uint32_t b7 : 1; + uint32_t b8 : 1; + uint32_t b9 : 1; + uint32_t b10 : 1; + uint32_t b11 : 1; + uint32_t b12 : 1; + uint32_t b13 : 1; + uint32_t b14 : 1; + uint32_t b15 : 1; + uint32_t b16 : 1; + uint32_t b17 : 1; + uint32_t b18 : 1; + uint32_t b19 : 1; + uint32_t b20 : 1; + uint32_t b21 : 1; + uint32_t b22 : 1; + uint32_t b23 : 1; + uint32_t b24 : 1; + uint32_t b25 : 1; + uint32_t b26 : 1; + uint32_t b27 : 1; + uint32_t b28 : 1; + uint32_t b29 : 1; + uint32_t b30 : 1; + uint32_t b31 : 1; +} __attribute__((packed, aligned(4))) gpio_bits_t; + +/* Structure of templates for accessing GPIO registers */ +typedef union _gpio_access_tp +{ + /* 32x1 bit mode */ + uint32_t u32[1]; + /* 16x2 bit mode */ + uint16_t u16[2]; + /* 8x4 bit mode */ + uint8_t u8[4]; + /* 1 bit mode */ + gpio_bits_t bits; +} __attribute__((packed, aligned(4))) gpio_access_tp_t; + +/* The GPIO address map */ +typedef struct _gpio +{ + /* Offset 0x00: Data (output) registers */ + gpio_access_tp_t data_output; + /* Offset 0x04: Data direction registers */ + gpio_access_tp_t direction; + /* Offset 0x08: Data source registers */ + gpio_access_tp_t source; + /* Offset 0x10 - 0x2f: Unused registers, 9x4 bytes */ + uint32_t unused_0[9]; + /* Offset 0x30: Interrupt enable/disable registers */ + gpio_access_tp_t interrupt_enable; + /* Offset 0x34: Interrupt mask registers */ + gpio_access_tp_t interrupt_mask; + /* Offset 0x38: Interrupt level registers */ + gpio_access_tp_t interrupt_level; + /* Offset 0x3c: Interrupt polarity registers */ + gpio_access_tp_t interrupt_polarity; + /* Offset 0x40: Interrupt status registers */ + gpio_access_tp_t interrupt_status; + /* Offset 0x44: Raw interrupt status registers */ + gpio_access_tp_t interrupt_status_raw; + /* Offset 0x48: Interrupt debounce registers */ + gpio_access_tp_t interrupt_debounce; + /* Offset 0x4c: Registers for clearing interrupts */ + gpio_access_tp_t interrupt_clear; + /* Offset 0x50: External port (data input) registers */ + gpio_access_tp_t data_input; + /* Offset 0x54 - 0x5f: Unused registers, 3x4 bytes */ + uint32_t unused_1[3]; + /* Offset 0x60: Sync level registers */ + gpio_access_tp_t sync_level; + /* Offset 0x64: ID code */ + gpio_access_tp_t id_code; + /* Offset 0x68: Interrupt both edge type */ + gpio_access_tp_t interrupt_bothedge; +} __attribute__((packed, aligned(4))) gpio_t; + +/* Bus GPIO object instance */ +extern volatile gpio_t *const gpio; + /**************************************************************************** * Public Functions Prototypes ****************************************************************************/ +/** + * @brief Gpio initialize + * @return - 0:Success,Other:Fail + */ +int gpio_init(void); -/**************************************************************************** - * Name: k210_gpio_set_direction - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for output, false for input - * - ****************************************************************************/ +/** + * @brief Set Gpio drive mode + * @param[in] pin Gpio pin + * @param[in] mode Gpio pin drive mode + */ +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode); -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode); +/** + * @brief Get Gpio pin value + * @param[in] pin Gpio pin + * @return Pin value + * GPIO_PV_Low Gpio pin low + * GPIO_PV_High Gpio pin high + */ +gpio_pin_value_t gpio_get_pin(uint8_t pin); -/**************************************************************************** - * Name: k210_gpio_set_value - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for high level, false for low level - * - ****************************************************************************/ - -void k210_gpio_set_value(uint32_t io, bool val); - -/**************************************************************************** - * Name: k210_gpio_get_value - * - * Description: - * Get gpiohs level - * - * Input Parameters: - * io - IO number - * - * Returned Value: - * true for high level, false for low level - * - ****************************************************************************/ - -bool k210_gpio_get_value(uint32_t io); +/** + * @brief Set Gpio pin value + * @param[in] pin Gpio pin + * @param[in] value Gpio pin value + */ +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value); #endif /* __ARCH_RISCV_SRC_K210_K210_GPIO_H */