| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program 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 Phytium Public License for more details.
- *
- *
- * FilePath: fgpio.c
- * Date: 2022-02-10 14:53:42
- * LastEditTime: 2022-02-18 08:25:29
- * Description: This files is for GPIO user API implmentation
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- * 1.0 zhugengyu 2022-3-1 init commit
- */
- /***************************** Include Files *********************************/
- #include "fdebug.h"
- #include "fparameters.h"
- #include "fgpio_hw.h"
- #include "fgpio.h"
- /************************** Constant Definitions *****************************/
- /**************************** Type Definitions *******************************/
- /***************** Macros (Inline Functions) Definitions *********************/
- #define FGPIO_DEBUG_TAG "FGPIO"
- #define FGPIO_ERROR(format, ...) FT_DEBUG_PRINT_E(FGPIO_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FGPIO_WARN(format, ...) FT_DEBUG_PRINT_W(FGPIO_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FGPIO_INFO(format, ...) FT_DEBUG_PRINT_I(FGPIO_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FGPIO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FGPIO_DEBUG_TAG, format, ##__VA_ARGS__)
- /************************** Function Prototypes ******************************/
- /************************** Variable Definitions *****************************/
- /*****************************************************************************/
- /**
- * @name: FGpioCfgInitialize
- * @msg: 初始化GPIO控制器实例
- * @return {FError} FGPIO_SUCCESS 表示初始化成功
- * @param {FGpio} *instance, GPIO控制器实例
- * @param {FGpioConfig} *config, GPIO控制器配置
- */
- FError FGpioCfgInitialize(FGpio *const instance, const FGpioConfig *const config)
- {
- FASSERT(instance && config);
- if (0 == config->base_addr)
- {
- FGPIO_ERROR("invalid base address !!!");
- return FGPIO_ERR_INVALID_PARA;
- }
- if (config != &instance->config)
- {
- instance->config = *config;
- }
- instance->is_ready = FT_COMPONENT_IS_READY;
- return FGPIO_SUCCESS;
- }
- /**
- * @name: FGpioDeInitialize
- * @msg: 去初始化GPIO控制器实例
- * @return {*}
- * @param {FGpio} *instance, GPIO控制器实例
- */
- void FGpioDeInitialize(FGpio *const instance)
- {
- FASSERT(instance);
- u32 port_id;
- u32 pin_id;
- FGpioPin *pin = NULL;
- for (port_id = FGPIO_PORT_A; port_id < FGPIO_PORT_NUM; port_id++)
- {
- for (pin_id = FGPIO_PIN_0; pin_id < FGPIO_PIN_NUM; pin_id++)
- {
- pin = instance->pins[port_id][pin_id];
- if (NULL != pin)
- {
- FGpioPinDeInitialize(pin);
- }
- }
- }
- instance->is_ready = 0;
- return;
- }
- /**
- * @name: FGpioPinInitialize
- * @msg: 初始化GPIO引脚实例
- * @return {FError} FGPIO_SUCCESS 表示初始化成功
- * @param {FGpio} *instance, GPIO控制器实例
- * @param {FGpioPin} *pin_instance, GPIO引脚实例
- * @param {FGpioPinId} index, GPIO引脚索引
- */
- FError FGpioPinInitialize(FGpio *const instance, FGpioPin *const pin_instance,
- const FGpioPinId index)
- {
- FASSERT(instance && pin_instance);
- FASSERT_MSG(index.port < FGPIO_PORT_NUM, "invalid gpio port %d", index);
- FASSERT_MSG(index.pin < FGPIO_PIN_NUM, "invalid gpio pin %d", index);
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FGPIO_ERROR("gpio instance not yet init !!!");
- return FGPIO_ERR_NOT_INIT;
- }
- if (FT_COMPONENT_IS_READY == pin_instance->is_ready)
- {
- FGPIO_ERROR("gpio pin already inited !!!");
- return FGPIO_ERR_ALREADY_INIT;
- }
- pin_instance->index = index;
- instance->pins[index.port][index.pin] = pin_instance;
- pin_instance->instance = instance;
- pin_instance->irq_cb = NULL;
- pin_instance->irq_cb_params = NULL;
- pin_instance->irq_one_time = FALSE;
- pin_instance->is_ready = FT_COMPONENT_IS_READY;
- return FGPIO_SUCCESS;
- }
- /**
- * @name: FGpioPinDeInitialize
- * @msg: 去初始化GPIO引脚实例
- * @return {NONE}
- * @param {FGpioPin} *pin, GPIO引脚实例
- */
- void FGpioPinDeInitialize(FGpioPin *const pin)
- {
- FASSERT(pin);
- FGpio *const instance = pin->instance;
- if ((NULL == instance) || (FT_COMPONENT_IS_READY != instance->is_ready) ||
- (FT_COMPONENT_IS_READY != pin->is_ready))
- {
- FGPIO_ERROR("gpio instance not yet init !!!");
- return;
- }
- if (FGPIO_DIR_INPUT == FGpioGetDirection(pin))
- FGpioSetInterruptMask(pin, FALSE); /* 关闭引脚中断 */
- FGpioPinId index = pin->index;
- FASSERT_MSG(instance->pins[index.port][index.pin] == pin, "invalid pin instance");
- instance->pins[index.port][index.pin] = NULL;
- pin->instance = NULL;
- pin->is_ready = 0U;
- return;
- }
- /**
- * @name: FGpioGetPinIrqSourceType
- * @msg: 获取引脚中断的上报方式
- * @return {FGpioIrqSourceType} 引脚中断的上报方式
- * @param {FGpioPin} *pin, GPIO引脚实例
- */
- FGpioIrqSourceType FGpioGetPinIrqSourceType(FGpioPinId pin_id)
- {
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- if (FGPIO_PORT_B == pin_id.port)
- {
- return FGPIO_IRQ_NOT_SUPPORT;
- }
- #endif
- if (FGPIO_PORT_A == pin_id.port)
- {
- #if defined(FGPIO_VERSION_2) /* E2000 GPIO 0 ~ 5 */
- if (pin_id.ctrl <= FGPIO_WITH_PIN_IRQ) /* 0 ~ 2 中断单独上报 */
- {
- return FGPIO_IRQ_BY_PIN;
- }
- #endif
- return FGPIO_IRQ_BY_CONTROLLER;
- }
- return FGPIO_IRQ_NOT_SUPPORT;
- }
- /**
- * @name: FGpioReadRegDir
- * @msg: 从寄存器读取GPIO组的输入输出方向
- * @return {u32} GPIO组的输入输出方向, bit[8:0]有效
- * @param {uintptr} base_addr, GPIO控制器基地址
- * @param {FGpioPortIndex} port, GPIO组, A/B
- */
- static u32 FGpioReadRegDir(uintptr base_addr, const FGpioPortIndex port)
- {
- u32 reg_val = 0;
- if (FGPIO_PORT_A == port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_SWPORTA_DDR_OFFSET);
- }
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- else if (FGPIO_PORT_B == port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_SWPORTB_DDR_OFFSET);
- }
- #endif
- else
- {
- FASSERT(0);
- }
- return reg_val;
- }
- /**
- * @name: FGpioWriteRegDir
- * @msg: 向寄存器写入GPIO组的输入输出方向
- * @return {*}
- * @param {uintptr} base_addr, GPIO控制器基地址
- * @param {FGpioPortIndex} port, GPIO组, A/B
- * @param {u32} reg_val, GPIO组的输入输出方向, bit[8:0]有效
- */
- static void FGpioWriteRegDir(uintptr base_addr, const FGpioPortIndex port, const u32 reg_val)
- {
- if (FGPIO_PORT_A == port)
- {
- FGpioWriteReg32(base_addr, FGPIO_SWPORTA_DDR_OFFSET, reg_val);
- }
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- else if (FGPIO_PORT_B == port)
- {
- FGpioWriteReg32(base_addr, FGPIO_SWPORTB_DDR_OFFSET, reg_val);
- }
- #endif
- else
- {
- FASSERT(0);
- }
- return;
- }
- /**
- * @name: FGpioSetDirection
- * @msg: 设置GPIO引脚的输入输出方向
- * @return {*}
- * @param {FGpioPin} *instance, GPIO控制器实例
- * @param {FGpioDirection} dir, 待设置的GPIO的方向
- * @note 初始化 GPIO 实例后使用此函数
- */
- void FGpioSetDirection(FGpioPin *const pin, FGpioDirection dir)
- {
- FASSERT(pin);
- FGpio *const instance = pin->instance;
- FASSERT(instance);
- FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not yet init !!!");
- u32 reg_val;
- FGpioPinId index = pin->index;
- uintptr base_addr = instance->config.base_addr;
- reg_val = FGpioReadRegDir(base_addr, index.port);
- if (FGPIO_DIR_INPUT == dir)
- {
- reg_val &= ~BIT(index.pin); /* 0-Input */
- }
- else if (FGPIO_DIR_OUTPUT == dir)
- {
- reg_val |= BIT(index.pin); /* 1-Output */
- }
- else
- {
- FASSERT(0);
- }
- FGpioWriteRegDir(base_addr, index.port, reg_val);
- return;
- }
- /**
- * @name: FGpioGetDirection
- * @msg: 获取GPIO引脚的输入输出方向
- * @return {FGpioDirection} GPIO引脚方向
- * @param {FGpioPin} *pin, GPIO引脚实例
- * @note 初始化 GPIO 实例后使用此函数
- */
- FGpioDirection FGpioGetDirection(FGpioPin *const pin)
- {
- FASSERT(pin);
- FGpio *const instance = pin->instance;
- FASSERT(instance);
- FASSERT(instance->is_ready == FT_COMPONENT_IS_READY);
- FGpioPinId index = pin->index;
- uintptr base_addr = instance->config.base_addr;
- u32 reg_val = FGpioReadRegDir(base_addr, index.port);
- return (BIT(index.pin) & reg_val) ? FGPIO_DIR_OUTPUT : FGPIO_DIR_INPUT;
- }
- /**
- * @name: FGpioReadRegVal
- * @msg: 获取GPIO组的输出寄存器值
- * @return {u32} 输出寄存器值 bit[8:0]有效
- * @param {uintptr} base_addr, GPIO控制器基地址
- * @param {FGpioPortIndex} port, GPIO组
- */
- static u32 FGpioReadRegVal(uintptr base_addr, const FGpioPortIndex port)
- {
- u32 reg_val = 0;
- if (FGPIO_PORT_A == port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_SWPORTA_DR_OFFSET);
- }
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- else if (FGPIO_PORT_B == port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_SWPORTB_DR_OFFSET);
- }
- #endif
- else
- {
- FASSERT(0);
- }
- return reg_val;
- }
- /**
- * @name: FGpioWriteRegVal
- * @msg: 设置GPIO组的输出寄存器值
- * @return {*}
- * @param {uintptr} base_addr, GPIO控制器基地址
- * @param {FGpioPortIndex} port, GPIO组
- * @param {u32} reg_val, 输出寄存器值 bit[8:0]有效
- */
- void FGpioWriteRegVal(uintptr base_addr, const FGpioPortIndex port, const u32 reg_val)
- {
- if (FGPIO_PORT_A == port)
- {
- FGpioWriteReg32(base_addr, FGPIO_SWPORTA_DR_OFFSET, reg_val);
- }
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- else if (FGPIO_PORT_B == port)
- {
- FGpioWriteReg32(base_addr, FGPIO_SWPORTB_DR_OFFSET, reg_val);
- }
- #endif
- else
- {
- FASSERT(0);
- }
- return;
- }
- /**
- * @name: FGpioSetOutputValue
- * @msg: 设置GPIO引脚的输出值
- * @return {FError} FGPIO_SUCCESS 表示设置成功
- * @param {FGpioPin} *pin, GPIO引脚实例
- * @param {FGpioPinVal} output, GPIO引脚的输出值
- * @note 初始化 GPIO 实例后使用此函数,先设置 GPIO 引脚为输出后调用此函数
- */
- FError FGpioSetOutputValue(FGpioPin *const pin, const FGpioPinVal output)
- {
- FASSERT(pin);
- FGpio *const instance = pin->instance;
- FASSERT(instance);
- FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not yet init !!!");
- FGpioPinId index = pin->index;
- u32 base_addr = instance->config.base_addr;
- u32 reg_val;
- if (FGPIO_DIR_OUTPUT != FGpioGetDirection(pin))
- {
- FGPIO_ERROR("need to set GPIO direction as OUTPUT first !!!");
- return FGPIO_ERR_INVALID_STATE;
- }
- FGPIO_INFO("pin-%d at port %d", index.pin, index.port);
- reg_val = FGpioReadRegVal(base_addr, index.port);
- if (FGPIO_PIN_LOW == output)
- {
- reg_val &= ~BIT(index.pin);
- }
- else if (FGPIO_PIN_HIGH == output)
- {
- reg_val |= BIT(index.pin);
- }
- else
- {
- FASSERT(0);
- }
- FGPIO_INFO("output val 0x%x", reg_val);
- FGpioWriteRegVal(base_addr, index.port, reg_val);
- FGPIO_INFO("output val 0x%x", FGpioReadRegVal(base_addr, index.port));
- return FGPIO_SUCCESS;
- }
- /**
- * @name: FGpioGetInputValue
- * @msg: 获取GPIO引脚的输入值
- * @return {FGpioPinVal} 获取的输入值,高电平/低电平
- * @param {FGpioPin} *instance, GPIO引脚实例
- * @note 初始化 GPIO 实例后使用此函数,先设置 GPIO 引脚为输入后调用此函数
- */
- FGpioPinVal FGpioGetInputValue(FGpioPin *const pin)
- {
- FASSERT(pin);
- FGpio *const instance = pin->instance;
- FASSERT(instance);
- FASSERT(instance->is_ready == FT_COMPONENT_IS_READY);
- FGpioPinId index = pin->index;
- uintptr base_addr = instance->config.base_addr;
- u32 reg_val;
- if (FGPIO_DIR_INPUT != FGpioGetDirection(pin))
- {
- FGPIO_ERROR("need to set GPIO direction as INPUT first !!!");
- return FGPIO_PIN_LOW;
- }
- if (FGPIO_PORT_A == index.port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_EXT_PORTA_OFFSET);
- }
- #if defined(FGPIO_VERSION_1) /* FT2000-4, D2000 */
- else if (FGPIO_PORT_B == index.port)
- {
- reg_val = FGpioReadReg32(base_addr, FGPIO_EXT_PORTB_OFFSET);
- }
- #endif
- else
- {
- FASSERT(0);
- }
- FGPIO_INFO("input val: 0x%x", reg_val);
- return (BIT(index.pin) & reg_val) ? FGPIO_PIN_HIGH : FGPIO_PIN_LOW;
- }
|