/*********************************************************************** | |
* Copyright (C) 2016, ZIXC Corporation. | |
* | |
* File Name: hal_gpio.c | |
* File Mark: | |
* Description: | |
* Others: | |
* Version: v1.0 | |
* Author: zhangdongdong | |
* Date: 2015-07-31 | |
* | |
* History 1: | |
* Date: | |
* Version: | |
* Author: | |
* Modification: | |
* | |
* History 2: | |
**********************************************************************/ | |
/************************************************************************* | |
* Include files * | |
*************************************************************************/ | |
#include <config.h> | |
#include "hal_gpio_v3.h" | |
#include <drvs_gpio.h> | |
/*GPIO*/ | |
#define GPIO0_REG_BASE 0x0013D000 | |
#define GPIO1_REG_BASE 0x0013E000 | |
#define PINMUX_REG_BASE 0x01303000 | |
#define PADCTRL_REG_BASE 0x0013c000 | |
#define IO_CFG_REG_BASE (PADCTRL_REG_BASE+0x800) | |
#define EX_GPIO_INT_TOP_AP_CLEAR_REG (0x13a000+0x128) | |
#define EX_GPIO_INT_TOP_CP_CLEAR_REG (0x13a000+0x118) | |
#define EX_8INT1_CLEAR_REG (0x13a000+0x064) | |
/************************************************************************* | |
* Macro * | |
*************************************************************************/ | |
#define GPIO0_MODULE_NUM 128 | |
#define GPIO1_MODULE_NUM 28 | |
#define GPIOPDD_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16) * 4) | |
#define RECV_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 5) * 4) | |
#define SET1_SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 6) * 4) | |
#define SET0_SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 7) * 4) | |
#define SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 8) * 4) | |
#define GPIOPDD_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16) * 4) | |
#define RECV_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 5) * 4) | |
#define SET1_SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 6) * 4) | |
#define SET0_SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 7) * 4) | |
#define SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 8) * 4) | |
#define TOP_SEL_AON 0 | |
#define TOP_SEL_PD 1 | |
/************************************************************************** | |
* Types * | |
**************************************************************************/ | |
/************************************************************************** | |
* Global Variable * | |
**************************************************************************/ | |
extern UINT32 gGpioNumMax; | |
extern T_Gpio gGpioInfoTable[]; | |
/************************************************************************** | |
* Function Prototypes * | |
**************************************************************************/ | |
/************************************************************************** | |
* Function Defines * | |
**************************************************************************/ | |
/************************************************************************** | |
* Functin: zDrvGpio_SetFunc | |
* Description: set the pin use ,used as GPIO or other module,when use for GPIO | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* func_sel: sel pd or aon func | |
* val: pd or aon func val | |
* Output: | |
* NONE | |
* Returns: | |
* success or parameter fault | |
* Others: | |
* None. | |
**************************************************************************/ | |
SINT32 zDrvGpio_SetFunc(UINT32 gpio_id, T_ZDrvGpio_FuncSel func_sel) | |
{ | |
#if 1//ndef _FPGA_TEST | |
UINT32 i = 0; | |
UINT32 topFunc = (func_sel>>12)&0x1; | |
UINT32 l2Func = func_sel&0x3ff; | |
if((gpio_id != (func_sel>>24))||(MAX_GPIO_NUM < gpio_id)){ | |
return -1; | |
} | |
for(i=0; i<gGpioNumMax; i++) | |
{ | |
if(gpio_id == gGpioInfoTable[i].gpio) | |
break; | |
} | |
if(INVLID_ADDR != gGpioInfoTable[i].topFuncSel.regBase) | |
{ | |
set_reg_bits(gGpioInfoTable[i].topFuncSel.regBase, | |
gGpioInfoTable[i].topFuncSel.offset, | |
gGpioInfoTable[i].topFuncSel.size, | |
topFunc); | |
} | |
if(TOP_SEL_AON == topFunc) | |
{ | |
if(INVLID_ADDR != gGpioInfoTable[i].aonFuncSel.regBase) | |
{ | |
set_reg_bits(gGpioInfoTable[i].aonFuncSel.regBase, | |
gGpioInfoTable[i].aonFuncSel.offset, | |
gGpioInfoTable[i].aonFuncSel.size, | |
l2Func); | |
} | |
} | |
else | |
{ | |
if(INVLID_ADDR != gGpioInfoTable[i].pdFuncSel.regBase) | |
{ | |
set_reg_bits(gGpioInfoTable[i].pdFuncSel.regBase, | |
gGpioInfoTable[i].pdFuncSel.offset, | |
gGpioInfoTable[i].pdFuncSel.size, | |
l2Func); | |
} | |
} | |
#endif | |
return 0; | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_PullUpDown | |
* Description: internal pull up or pull down | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* value: pull up or down val | |
* Output: | |
* NONE | |
* Returns: | |
* success or parameter fault | |
* Others: | |
* None. | |
**************************************************************************/ | |
SINT32 zDrvGpio_PullUpDown(UINT32 gpio_id, UINT32 val) | |
{ | |
UINT32 i = 0; | |
if(MAX_GPIO_NUM < gpio_id){ | |
return -1; | |
} | |
for(i=0; i<gGpioNumMax; i++) | |
{ | |
if(gpio_id == gGpioInfoTable[i].gpio) | |
break; | |
} | |
if(INVLID_ADDR != gGpioInfoTable[i].ioCfg.regBase) | |
{ | |
set_reg_bits(gGpioInfoTable[i].ioCfg.regBase, | |
gGpioInfoTable[i].ioCfg.offset, | |
gGpioInfoTable[i].ioCfg.size, | |
val); | |
} | |
else | |
return -1; | |
return 0; | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_SetDirection | |
* Description: set direction of gpio, in or out | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* value: in or out. | |
* Output: | |
* NONE | |
* Returns: | |
* NONE | |
* Others: | |
* None. | |
**************************************************************************/ | |
void zDrvGpio_SetDirection(UINT32 gpio_id, T_ZDrvGpio_IoDirection value) | |
{ | |
UINT32 gpio_addr = 0; | |
UINT32 tmp = 0; | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = GPIOPDD_REG0(gpio_id); | |
else | |
gpio_addr = GPIOPDD_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = get_reg_val(gpio_addr); | |
if(GPIO_IN == value) | |
tmp &= ~(0x1<<(gpio_id % 16)); | |
else | |
tmp |= (0x1<<(gpio_id % 16)); | |
set_reg_val(gpio_addr, tmp); | |
; | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_GetDirection | |
* Description: get direction | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* Output: | |
* gpio input or output | |
* Returns: | |
* | |
* Others: | |
* None. | |
**************************************************************************/ | |
T_ZDrvGpio_IoDirection zDrvGpio_GetDirection(UINT32 gpio_id) | |
{ | |
UINT32 gpio_addr = 0; | |
UINT32 tmp = 0; | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = GPIOPDD_REG0(gpio_id); | |
else | |
gpio_addr = GPIOPDD_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = get_reg_val(gpio_addr); | |
if((tmp >> (gpio_id % 16)) & 0x1) | |
return GPIO_OUT; | |
else | |
return GPIO_IN; | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_SetOutputValue | |
* Description: set output value | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* value: high or low. | |
* Output: | |
* NONE | |
* Returns: | |
* success or parameter fault | |
* Others: | |
* None. | |
**************************************************************************/ | |
void zDrvGpio_SetOutputValue(UINT32 gpio_id, T_ZDrvGpio_IoVal value) | |
{ | |
UINT32 gpio_addr = 0; | |
UINT32 tmp = 0; | |
if(GPIO_LOW == value) | |
{ | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = SET0_SEND_REG0(gpio_id); | |
else | |
gpio_addr = SET0_SEND_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = (0x1<<(gpio_id % 16)); | |
set_reg_val(gpio_addr, tmp); | |
} | |
if(GPIO_HIGH == value) | |
{ | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = SET1_SEND_REG0(gpio_id); | |
else | |
gpio_addr = SET1_SEND_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = (0x1<<(gpio_id % 16)); | |
set_reg_val(gpio_addr, tmp); | |
} | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_GetOutputValue | |
* Description: get output value | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* Output: | |
* output high or low | |
* Returns: | |
* NONE | |
* Others: | |
* None. | |
**************************************************************************/ | |
T_ZDrvGpio_IoVal zDrvGpio_GetOutputValue(UINT32 gpio_id) | |
{ | |
UINT32 gpio_addr = 0; | |
UINT32 tmp = 0; | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = SEND_REG0(gpio_id); | |
else | |
gpio_addr = SEND_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = get_reg_val(gpio_addr); | |
if((tmp >> (gpio_id % 16)) & 0x1) | |
return GPIO_HIGH; | |
else | |
return GPIO_LOW; | |
} | |
/************************************************************************** | |
* Functin: zDrvGpio_GetInputValue | |
* Description: get input value | |
* Parameters: | |
* Input: | |
* gpio_id: gpio id | |
* Output: | |
* input high or low | |
* Returns: | |
* NONE | |
* Others: | |
* None. | |
**************************************************************************/ | |
T_ZDrvGpio_IoVal zDrvGpio_GetInputValue(UINT32 gpio_id) | |
{ | |
UINT32 gpio_addr = 0; | |
UINT32 tmp = 0; | |
if(GPIO0_MODULE_NUM > gpio_id) | |
gpio_addr = RECV_REG0(gpio_id); | |
else | |
gpio_addr = RECV_REG1(gpio_id-GPIO0_MODULE_NUM); | |
tmp = get_reg_val(gpio_addr); | |
if((tmp >> (gpio_id % 16)) & 0x1) | |
return GPIO_HIGH; | |
else | |
return GPIO_LOW; | |
} | |
void gpio_reset(void) | |
{ | |
unsigned int i=0; | |
//gpio0~1 | |
for(i=0;i<8;i++) | |
{ | |
if(i == 1) { //v3 pshold1: gpio24 | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x00) &=0x0100; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x18) &=0x0100; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x1c) &=0x0100; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x20) &=0x0100; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x24) &=0x0100; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x00)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x18)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x1c)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x20)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x24)=0; | |
} | |
else { | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x00)=0; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x18)=0; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x1c)=0; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x20)=0; | |
reg32(GPIO0_REG_BASE + 0x40 *i + 0x24)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x00)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x18)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x1c)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x20)=0; | |
reg32(GPIO1_REG_BASE + 0x40 *i + 0x24)=0; | |
} | |
} | |
} | |
void pinmux_reset(void) | |
{ | |
unsigned int i=0; | |
unsigned int tmp=0; | |
//pinmux | |
reg32(PINMUX_REG_BASE + 0x00)=0; | |
reg32(PINMUX_REG_BASE + 0x04)=0; | |
reg32(PINMUX_REG_BASE + 0x08)=0; | |
reg32(PINMUX_REG_BASE + 0x0c)=0x7ff; | |
for(i=4;i<14;i++) { | |
reg32(PINMUX_REG_BASE + 0x4* i)=0; | |
} | |
//padctrl fun_sel | |
reg32(PADCTRL_REG_BASE + 0x00)=0x00000500; | |
reg32(PADCTRL_REG_BASE + 0x04)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x08)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x0c)=0x00015400; | |
reg32(PADCTRL_REG_BASE + 0x10)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x14)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x18)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x1c)=0x00007fff; | |
reg32(PADCTRL_REG_BASE + 0x20)=0x0000c030; | |
reg32(PADCTRL_REG_BASE + 0x24)=0x000003ff; | |
reg32(PADCTRL_REG_BASE + 0x28)=0x00007fc0; | |
reg32(PADCTRL_REG_BASE + 0x2c)=0x00000000; | |
reg32(PADCTRL_REG_BASE + 0x30)=0x00000000; | |
//padctrl io_cfg | |
tmp=reg32(IO_CFG_REG_BASE + 0x04); //pshold1-gpio24:bit[29:28] | |
tmp &= 0x30000000; | |
tmp |= 0x00d40000; | |
reg32(IO_CFG_REG_BASE + 0x04)=tmp; | |
reg32(IO_CFG_REG_BASE + 0x00)=0x00fffd4f; | |
//reg32(IO_CFG_REG_BASE+0x04)=0x10d40000; | |
reg32(IO_CFG_REG_BASE + 0x08)=0x557fff57; | |
reg32(IO_CFG_REG_BASE + 0x0c)=0x15554015; | |
reg32(IO_CFG_REG_BASE + 0x10)=0x38383858; | |
reg32(IO_CFG_REG_BASE + 0x14)=0x38583838; | |
reg32(IO_CFG_REG_BASE + 0x18)=0x38383838; | |
reg32(IO_CFG_REG_BASE + 0x1c)=0x155fd5ff; | |
reg32(IO_CFG_REG_BASE + 0x20)=0x00154ff7; | |
reg32(IO_CFG_REG_BASE + 0x24)=0x00555555; | |
reg32(IO_CFG_REG_BASE + 0x28)=0x00003858; | |
reg32(IO_CFG_REG_BASE + 0x2c)=0x05555555; | |
reg32(IO_CFG_REG_BASE + 0x30)=0x000000ad; | |
reg32(IO_CFG_REG_BASE + 0x34)=0x00000048; | |
reg32(IO_CFG_REG_BASE + 0x38)=0x00000001; | |
reg32(IO_CFG_REG_BASE + 0x3c)=0x00000058; | |
reg32(IO_CFG_REG_BASE + 0x40)=0x00585858; | |
} | |
void pcu_clear_8in1_Int(void) | |
{ | |
reg32(EX_8INT1_CLEAR_REG) = 0xff<<8;//clear External_Gpio_Int_Top_Clear_Reg | |
reg32(EX_GPIO_INT_TOP_AP_CLEAR_REG) = 0x1;//clear External_Gpio_Int_Top_Clear_Reg | |
reg32(EX_GPIO_INT_TOP_CP_CLEAR_REG) = 0x1;//clear External_Gpio_Int_Top_Clear_Reg | |
} | |
int gpio_pad_init2rst(void) | |
{ | |
gpio_reset(); | |
pinmux_reset(); | |
pcu_clear_8in1_Int(); | |
return 0; | |
} | |