目的:应用层快捷、方便的配置gpio
1 gpio工作方式-通用输入输出
gpio获取步骤:
1 管脚复用
2 获取gpio方向和值
gpio配置步骤:
1 管脚复用
2 配置gpio方向
3 如果是输出方向,可以配置gpio值
2 接口设计
typedef struct _tagPINMUX_REG_S
{
HI_U32 u32Reg;
HI_U32 u32Val;
}PINMUX_REG_S;
HI_S32 HI_GPIOMNG_Init(PINMUX_REG_S *paPinmuxReg, HI_U8 u8PinmuxRegSize);
HI_S32 HI_GPIOMNG_Denit();
HI_S32 HI_GPIOMNG_SetDir(HI_U8 u8Gpio, HI_U8 u8Dir);
HI_S32 HI_GPIOMNG_GetDir(HI_U8 u8Gpio);
HI_S32 HI_GPIOMNG_SetVal(HI_U8 u8Gpio, HI_U8 u8Val);
HI_S32 HI_GPIOMNG_GetVal(HI_U8 u8Gpio);
HI_GPIOMNG_Init:管脚复用和gpio寄存器地址映射到应用层
HI_GPIOMNG_Denit:关闭gpio寄存器地址映
HI_GPIOMNG_SetDir:配置gpio方向(0输入,1输出)
HI_GPIOMNG_GetDir:获取gpio方向(0输入,1输出)
HI_GPIOMNG_SetVal:配置gpio值(0 低,1 高)
HI_GPIOMNG_GetVal:获取gpio值(0 低,1 高)
u8Gpio:海思gpio号计算公式:u8Gpio=GpioGroup*8+GpioBit
3 接口实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "hi_type.h"
#include "hi_gpiomng.h"
#define GPIO_BASE_ADDR (0x120D0000)
#define GPIO_GRP(group_id) (g_pGpioBaseAddr+0x1000*group_id)
#define GPIO_DATA(group_reg_base, gpio_offset) (((group_reg_base) + 0x000) + (1 << ((gpio_offset) + 2)))
#define GPIO_DIR(group_reg_base) ((group_reg_base) + 0x400)
#define GPIO_IS(group_reg_base) ((group_reg_base) + 0x404)
#define GPIO_IBE(group_reg_base) ((group_reg_base) + 0x408)
#define GPIO_IEV(group_reg_base) ((group_reg_base) + 0x40C)
#define GPIO_IE(group_reg_base) ((group_reg_base) + 0x410)
#define GPIO_RIS(group_reg_base) ((group_reg_base) + 0x414)
#define GPIO_MIS(group_reg_base) ((group_reg_base) + 0x418)
#define GPIO_IC(group_reg_base) ((group_reg_base) + 0x41C)
#define PAGE_SIZE_MASK (~(0xfff))
#define PAGE_SIZE 0x1000
#define GPIO_MAP_MEM_SIZE 0xC000
static const char dev[]="/dev/mem";
static HI_VOID *g_pGpioBaseAddr = NULL;
static HI_BOOL g_bGpioInit = HI_FALSE;
HI_VOID * COMM_MMAP(HI_U32 u32RetAddr, HI_U32 u32MapMemSize)
{
HI_S32 fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return NULL;
}
/* addr align in page_size(4K) */
unsigned long phy_addr_in_page;
unsigned long page_diff;
phy_addr_in_page = u32RetAddr & PAGE_SIZE_MASK;
page_diff = u32RetAddr - phy_addr_in_page;
/* size in page_size */
unsigned long size_in_page;
unsigned long size = u32MapMemSize;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
void *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page);
if (addr == MAP_FAILED)
{
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return NULL;
}
close(fd);
return addr+page_diff;
}
HI_VOID COMM_MUNMAP(HI_VOID *pRegAddr, HI_U32 u32MapMemSize)
{
munmap(pRegAddr, u32MapMemSize);
}
HI_S32