2022-11-10 22:22:48 +08:00
|
|
|
|
/*
|
|
|
|
|
* 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
|
|
|
|
|
* ----- ------ -------- --------------------------------------
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* 1.0 zhugengyu 2022/3/1 init commit
|
|
|
|
|
* 2.0 zhugengyu 2022/7/1 support e2000
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************** 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)
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_ERROR("Invalid base address !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
return FGPIO_ERR_INVALID_PARA;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (config != &instance->config)
|
|
|
|
|
{
|
|
|
|
|
instance->config = *config;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
/* mask interrupt for all pins */
|
|
|
|
|
FGpioWriteReg32(instance->config.base_addr, FGPIO_INTMASK_OFFSET, FGPIO_INTR_PORTA_MASKALL);
|
|
|
|
|
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FASSERT_MSG(index.port < FGPIO_PORT_NUM, "Invalid gpio port %d", index);
|
|
|
|
|
FASSERT_MSG(index.pin < FGPIO_PIN_NUM, "Invalid gpio pin %d", index);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
if (FT_COMPONENT_IS_READY != instance->is_ready)
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_ERROR("gpio instance is not yet inited !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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) ||
|
2023-05-11 10:25:21 +08:00
|
|
|
|
(FT_COMPONENT_IS_READY != pin->is_ready))
|
2022-11-10 22:22:48 +08:00
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_ERROR("gpio instance is not yet inited !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FGPIO_DIR_INPUT == FGpioGetDirection(pin))
|
2023-05-11 10:25:21 +08:00
|
|
|
|
{
|
|
|
|
|
FGpioSetInterruptMask(pin, FALSE); /* 关闭引脚中断 */
|
|
|
|
|
}
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
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);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance not is yet inited !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FASSERT_MSG(instance->is_ready == FT_COMPONENT_IS_READY, "gpio instance is not yet inited !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
FGpioPinId index = pin->index;
|
2023-08-02 13:27:09 +08:00
|
|
|
|
uintptr base_addr = instance->config.base_addr;
|
2022-11-10 22:22:48 +08:00
|
|
|
|
u32 reg_val;
|
|
|
|
|
|
|
|
|
|
if (FGPIO_DIR_OUTPUT != FGpioGetDirection(pin))
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_ERROR("Need to set GPIO direction as OUTPUT first !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_INFO("Output val 0x%x", reg_val);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
FGpioWriteRegVal(base_addr, index.port, reg_val);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_INFO("Output val 0x%x", FGpioReadRegVal(base_addr, index.port));
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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))
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_ERROR("Need to set GPIO direction as INPUT first !!!");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FGPIO_INFO("Input val: 0x%x.", reg_val);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
return (BIT(index.pin) & reg_val) ? FGPIO_PIN_HIGH : FGPIO_PIN_LOW;
|
|
|
|
|
}
|