hi3516 gpio


原文链接: hi3516 gpio

海思Hi3516A在用户态GPIO操作 - 嵌入式 - CSDN博客
海思芯片上GPIO操作步骤的整理 - 博客小站 - CSDN博客
Hi35xx 通用GPIO 使用篇(板子3G电源控制脚说明) - 怀想天空 - 博客园

//system("himm 0x2016040 0xFF");
HI_MPI_SYS_SetReg(0x20160040,0x00);

芯片支持 12 组 GPIO(General Purpose Input/Output),即 GPIO0~GPIO11。每组 GPIO 提供 8 个可编程的输入输出管脚(GPIO11 只有 4 个)。
每个管脚可以配置为输入或者输出。这些管脚用于生成特定应用的输出信号或采集特 定应用的输入信号。作为输入管脚时,GPIO 可作为中断源;作为输出管脚时,每个 GPIO 都可以独立地清 0 或置 1。
8 42 1
10 电平转换速率控制,为0时电平转换速率快,为1时电平转换速率慢。
9 下拉电阻使能,高有效。
8 上拉电阻使能,高有效。10

7:4 驱动能力,0~3对应IO驱动能力IO2_档位1~档位4。
3:0 "功能选择:

0:GPIO2_0 0
1:USB_OVRCUR"

2*8 +7 = 23
继电器控制
支持继电器控制。
通过操作GPIO19可以控制继电器的常开和闭合。
echo 16 > /sys/class/gpio/export #导出GPIO2_3
echo out > /sys/class/gpio/gpio16/direction #设置GPIO2_3方向为输出
echo 1 > /sys/class/gpio/gpio16/value #控制继电器断开
echo 0 > /sys/class/gpio/gpio16/value #控制继电器闭合
echo 19 > /sys/class/gpio/unexport #取消GPIO2_3的导出

himm 0x10FF003C 0x0530 GPIO2_0
himm 0x10FF0040 0x620 GPIO2_1
himm 0x114F000C 0x620 GPIO2_7

echo 23 > /sys/class/gpio/export #导出GPIO2_7
echo out > /sys/class/gpio/gpio23/direction #设置GPIO2_7方向为输出
echo 1 > /sys/class/gpio/gpio23/value #控制继电器断开
echo 0 > /sys/class/gpio/gpio23/value #控制继电器闭合
echo 23 > /sys/class/gpio/unexport #取消GPIO2_7的导出

echo 16 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio16/direction
echo 1 > /sys/class/gpio/gpio16/value
echo 0 > /sys/class/gpio/gpio16/value

#!/bin/sh

#GPIO6_5 -> GPIO53 (6*8+5 = 53)
#GPIO6_6 -> GPIO54 (6*8+6 = 54)
#GPIO3_0 -> GPIO24 (3*8+0 = 24)

#(normal mode)
ir_cut_enable()
{
	# pin_mux
	echo "$gpio_0" > /sys/class/gpio/unexport;
	echo "$gpio_1" > /sys/class/gpio/unexport;
	echo "$gpio_0" > /sys/class/gpio/export;
	echo "$gpio_1" > /sys/class/gpio/export;
	
	# dir
	echo "out" > /sys/class/gpio/gpio$gpio_0/direction;
	echo "out" > /sys/class/gpio/gpio$gpio_1/direction;
	
	# data, gpio_1: 0, gpio_0: 1  (normal mode)
	echo "1" > /sys/class/gpio/gpio$gpio_0/value;
	echo "0" > /sys/class/gpio/gpio$gpio_1/value;
	
	#sleep 1s
	sleep 1;
	
	# back to original 
	echo "0" > /sys/class/gpio/gpio$gpio_0/value;
	echo "0" > /sys/class/gpio/gpio$gpio_1/value;
}

# (ir mode)
ir_cut_disable()
{
	# pin_mux
	echo "$gpio_0" > /sys/class/gpio/unexport;
	echo "$gpio_1" > /sys/class/gpio/unexport;
	echo "$gpio_0" > /sys/class/gpio/export;
	echo "$gpio_1" > /sys/class/gpio/export;
	
	# dir
	echo "out" > /sys/class/gpio/gpio$gpio_0/direction;
	echo "out" > /sys/class/gpio/gpio$gpio_1/direction;
	
	# data, gpio_1: 1, gpio_0: 0  (ir mode)
	echo "0" > /sys/class/gpio/gpio$gpio_0/value;
	echo "1" > /sys/class/gpio/gpio$gpio_1/value;
	
	#sleep 1s
	sleep 1;
	
	# back to original 
	echo "0" > /sys/class/gpio/gpio$gpio_0/value;
	echo "0" > /sys/class/gpio/gpio$gpio_1/value;
}

gpio_0=0
gpio_1=0

if [ $# -lt 2 ]; then
    echo "usage : ./demo_config.sh <chip> <mode>";
    echo "for example:";
    echo "ir mode : ./demo_config.sh hi3516cv300 1";
else
	if [ $1 = "hi3516ev100" ]; then
		gpio_0=53;
		gpio_1=24;
	elif [ $1 = "hi3516cv300" ]; then
		gpio_0=53;
		gpio_1=54;
	else
		echo "wrong chipid: $1, please select: hi3516cv300 or hi3516ev100.";
		exit;
	fi

    if [ $2 -eq 0 ]; then
        echo "normal mode, ir_cut on"
        ir_cut_enable > /dev/null;
    elif [ $2 -eq 1 ]; then
        echo "ir mode, ir_cut off"
        ir_cut_disable > /dev/null;
	else
		echo "invalid mode, please slect 0 or 1."
    fi
fi

利用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的模式。
————————————————
版权声明:本文为CSDN博主「AI技术」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_29214249/article/details/78275478

`