1. 程式人生 > >海思平臺GPIO驅動最簡單實現

海思平臺GPIO驅動最簡單實現

閒來無事,發兩個小程式玩玩

利用HI_MPI_SYS_SetReg、HI_MPI_SYS_GetReg實現GPIO驅動程式

原始碼:

#include <stdio.h>


/*
#define GPIO_IR_CUT          (0x201C0000 + 0x400) //GPIO8_0 0x00
#define GPIO_CDSADC          (0x201B0000 + 0x400) //GPIO7_6 0x40
#define GPIO_INFRARED        (0x201C0000 + 0x400) //GPIO8_1 0x01
#define GPIO_LIGHTBOARD_LED  (0x20180000 + 0x400) //GPIO4_2 0x04
#define GPIO_ONBOARD_LED     (0x20150000 + 0x400) //GPIO1_7 0x80
#define GPIO_RESER           (0x20180000 + 0x400) //GPIO4_6 0x40
#define GPIO_WIFI_EN         (0x20140000 + 0x400) //GPIO0_3 0x08
#define GPIO_SPEAKER         (0x20180000 + 0x400) //GPIO4_0 0x00
*/

#define GPIO_DATA(gpio_group_reg_base, gpio_offset)         IO_ADDRESS(((gpio_group_reg_base) + 0x000) + (1 << ((gpio_offset) + 2)))
#define GPIO_DIR(gpio_group_reg_base)   					IO_ADDRESS((gpio_group_reg_base) + 0x400)

int h_gpio_group_reg_base = {
	0x20140000,  //GPIO0
	0x20150000,  //GPIO1
	0x20160000,  //GPIO2
	0x20170000,  //GPIO3
	0x20180000,  //GPIO4
	0x20190000,  //GPIO5
	0x201A0000,  //GPIO6
	0x201B0000,  //GPIO7
	0x201C0000,  //GPIO8
};
int hal_hi3518ev200_gpio_dir_config(unsigned char gpio_group, unsigned char gpio_offset, unsigned char flag)
{
    unsigned int val = 0;
    unsigned int addr = 0;
    addr = GPIO_DIR(h_gpio_group_reg_base[gpio_group]);
    if( 0 == HI_MPI_SYS_GetReg(addr,val) )
	{
		if(flag)
		{
			val |= 1 << gpio_offset;
		}
		else
		{
			val &= ~(1 << gpio_offset);
		}
		
		if( 0 == HI_MPI_SYS_SetReg(addr,val) )
		{
			printf("HI_MPI_SYS_SetReg success! val: %d\n",val);
			return 0;
		}
		else
		{
			printf("HI_MPI_SYS_SetReg Error! val: %d\n",val);
			return -1;
		}
	}
	else
	{
		printf("HI_MPI_SYS_GetReg Error! val: %d\n",val);
		return -1;
	}
}

int gpio_write(unsigned char gpio_group, unsigned char gpio_offset, unsigned char flag)
{
    unsigned int val = 0;
    unsigned int addr = 0;

    addr = GPIO_DATA(h_gpio_group_reg_base[gpio_group], gpio_offset);
    if(flag)
    {
        val = 1 << gpio_offset;
    }
    else
    {
        val = 0;
    }

	if( 0 == HI_MPI_SYS_SetReg(addr,val) )
	{
		printf("HI_MPI_SYS_SetReg success! val: %d\n",val);
		return 0;
	}
	else
	{
		printf("HI_MPI_SYS_SetReg Error! val: %d\n",val);
		return -1;
	}	

}

int gpio_read(unsigned char gpio_group, unsigned char gpio_offset)
{
    unsigned int val = 0;
    unsigned int addr = 0;

    addr = GPIO_DATA(h_gpio_group_reg_base[gpio_group], gpio_offset);
    if( 0 == HI_MPI_SYS_GetReg(addr,val) )
	{
		if(val & (1 << gpio_offset))
		{
			val = 1;
		}
		else
		{
			val = 0;
		}
		printf("HI_MPI_SYS_GetReg Error! val: %d\n",val);
		return val;
	}
	else
	{
		printf("HI_MPI_SYS_GetReg Error! val: %d\n",val);

		return -1;
	}
}

int hal_hi3518ev200_gpio_init(void) //gpio初始化函式
{
	hal_hi3518ev200_gpio_dir_config(4,0,1); //GPIO_SPEAKER,設定GPIO4_0輸出模式
	hal_hi3518ev200_gpio_dir_config(0,3,1); //GPIO_WIFI_EN,設定GPIO0_3輸出模式
	hal_hi3518ev200_gpio_dir_config(4,6,0); //GPIO_RESER,設定GPIO4_6輸入模式
	hal_hi3518ev200_gpio_dir_config(1,7,1); //GPIO_ONBOARD_LED,設定GPIO1_7輸出模式
	hal_hi3518ev200_gpio_dir_config(4,2,1); //GPIO_LIGHTBOARD_LED,設定GPIO4_2輸出模式
	hal_hi3518ev200_gpio_dir_config(8,1,1); //GPIO_INFRARED,設定GPIO8_1輸出模式
	hal_hi3518ev200_gpio_dir_config(7,6,0); //GPIO_CDSADC,設定GPIO7_6輸入模式
	hal_hi3518ev200_gpio_dir_config(8,0,1); //GPIO_CDSADC,設定GPIO8_0輸出模式

	return 0;
}

int hal_hi3518ev200_speaker_enable(void)  //使能喇叭
{	
	gpio_write(4,0,0); //輸出0開啟揚聲器
	
	return 0;
}
int hal_hi3518ev200_speaker_disable(void)   //關閉喇叭
{
	gpio_write(4,0,0); //輸出1關閉揚聲器
	
	return 0;
}

int hal_hi3518ev200_wifi_poweron(void)    //使能wifi供電
{
	gpio_write(0,3,1); //輸出1開啟wifi供電
	
	return 0;
}

int hal_hi3518ev200_wifi_powerdown(void) //關閉wifi供電
{
	gpio_write(0,3,0); //輸出0關閉wifi供電
	
	return 0;
}

int  hal_hi3518ev200_check_reset(void)  //復位按鍵 >>>返回 1 按下, 返回 0 沒按
{
	int reset_value;
	reset_value = gpio_read(4,6); //獲取復位按鍵鍵值
	
	return reset_value;
}
int hal_hi3518ev200_led_control(int led_index ,int value) //led控制  led_index 0:板載LED;1:燈板LED || value 1:亮 0:滅
{
	if(led_index == 0)
	{
		gpio_write(1,7,~value)) //板載LED
	}
	else
	{
		gpio_write(4,2,~value)) //燈板LED
	}
	return 0;
}
int hal_hi3518ev200_get_cds_value(void)  //光敏  1白天 0 夜晚
{
	int reset_value;
	reset_value = gpio_read(7,6); //獲取復位按鍵鍵值
	return reset_value;
}
int hal_hi3518ev200_set_ircut_value(int value) //icut 0/1 切換
{
	gpio_write(8,0,value)) //板載LED

	return 0;
}

int main(void)
{
	hal_hi3518ev200_gpio_init();
	
	return 0;
}

該程式就是操作GPIO的暫存器,分為兩步,一步複用,一步使能方向。

當然,對於複雜一點的GPIO操作的話,驅動肯定是不能這樣寫的了,還是老老實實寫成module的模式。