海思gpio控制(应用层用例和驱动用例)及寄存器操作

一、海思设置寄存器操作

通过命令行工具进行操作:

使用应用层的调试工具 himm

~ # himm
*** Board tools : ver0.0.1_20121120 *** 
[debug]: {
     source/utils/cmdshell.c:166}cmdstr:himm
usage: himm <address>. sample: himm 0x80040000 
[error]:  exit:0XFFFFFFFF.{
     source/tools/himm.c:45}
[END]

使用方式是 himm 0x80040000 后面跟的是需要操作的地址信息。

~ # himm 0x80040000
*** Board tools : ver0.0.1_20121120 *** 
[debug]: {
     source/utils/cmdshell.c:166}cmdstr:himm
====dump memory 0X80040000====
0x80040000: 0xFFBEEFAE
NewValue:

输入后可以得出其寄存器的值,在默认值的基础上我们再做修改。切记只修改需要改变的位,其他寄存器位保持一致。在NewValue中输入改变后的值。
另外还有其他的工具;

~ # himc
*** Board tools : ver0.0.1_20121120 *** 
[debug]: {
     source/utils/cmdshell.c:166}cmdstr:himc
 clear(set) memory. 
usage: himc <address> <length> [value]. 
Address: Phy address. 0x80040000 
Length: the length to set 
Value: default 0 
sample: himc 0x80040000 100 1
Clear memory from 0x80040000, to 0x80040064
[error]:  exit:0XFFFFFFFF.{
     source/tools/himc.c:50}
[END]
~ # himd
*** Board tools : ver0.0.1_20121120 *** 
[debug]: {
     source/utils/cmdshell.c:166}cmdstr:himd
usage: himd <address>. sample: himd 0x80040000
[error]:  exit:0XFFFFFFFF.{
     source/tools/himd.c:107}
[END]
~ # himd.l 
*** Board tools : ver0.0.1_20121120 *** 
[debug]: {
     source/utils/cmdshell.c:166}cmdstr:himd.l
usage: himd.l <address> [length]. sample: himd.l 0x80040000 0x100
[error]:  exit:0XFFFFFFFF.{
     source/tools/himd.c:50}
[END]

用法有给出来,但是作用的话,我没用过,有用过的同学可以在评论补充下。谢谢。

二、应用程序控制海思gpio输出电平

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "hi_gpio.h"

int main(int argc, char *argv[])
{
     
	//管脚gpio15_pin4复用为gpio功能
	//可以采用HI_S32 HI_MPI_SYS_SetReg(HI_U32 u32Addr, HI_U32 u32Value);和
	//HI_S32 HI_MPI_SYS_GetReg(HI_U32 u32Addr, HI_U32 *pu32Value); 来替代
	system("himm 0x120F00F0 0x1");
	//设置为推挽输出
	BSPGpioInit(GPIO_PORT_15, GPIO_Pin_4, IS_INPUT, GPIO_MODE_Out_PP);
	//设置为开漏输出
	BSPGpioInit(GPIO_PORT_15, GPIO_Pin_4, IS_OUTPUT, GPIO_MODE_Out_OD);
	//输出低电平
	BSPGpioClearOutput(GPIO_PORT_15, GPIO_Pin_4);
	//输出高电平
	BSPGpioSetOutput(GPIO_PORT_15, GPIO_Pin_4);
	return 0;
}

三、驱动ko设置gpio输出电平

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
#include 
#include 
#include  
#include 



#define REG_WRITE(addr, value)  ((*(volatile unsigned int *)(addr)) = (value))
#define REG_READ(Addr)         	(*(volatile unsigned int *)(Addr))

#define GPIO_CONFIG_OFFSET_ADDR    0xF0
#define GPIO_DIR_OFFSET_ADDR    0x400
#define GPIO_DATA_OFFSET_ADDR    0x40 //输出偏移位 gpio15_4

unsigned int muxctrl_virtual_addr = 0;
unsigned int gpio_15_virtual_addr = 0;

static void gpio15_4_output_height();
static void gpio15_4_output_low();
static int hi3536_virtual_addr_map(void)
{
     
    muxctrl_virtual_addr = (unsigned int)ioremap_nocache(GPIO_MUXCTRL_BASE_ADDR, 0x10000);
    if(!muxctrl_virtual_addr)
    {
     
        printk("GPIO_MUXCTRL_BASE_ADDR ioremap addr failed !\n");
        return -1;
    }
	gpio_15_virtual_addr = (unsigned int)ioremap_nocache(GPIO15_BASE_ADDR, 0x10000);
    if(!gpio_15_virtual_addr)
    {
     
        printk("GPIO15_BASE_ADDR ioremap addr failed !\n");
        return -1;
    }
}

static void gpio15_4_output_height()
{
     
	REG_WRITE(gpio_15_virtual_addr + GPIO_DATA_OFFSET_ADDR, 0xFF);//GPIO15_4
}
static void gpio15_4_output_low()
{
     
	REG_WRITE(gpio_15_virtual_addr + GPIO_DATA_OFFSET_ADDR, 0x0);//GPIO15_4
}

//取消地址映射
static void hi3531_virtual_addr_unmap(void)
{
     
    iounmap((void*)muxctrl_virtual_addr);
    iounmap((void*)gpio_15_virtual_addr);
}


static void hi3531_button_gpio_config(void)
{
     
    unsigned int u32Reg = 0;
 
    //配置为gpio
    REG_WRITE(muxctrl_virtual_addr + GPIO_CONFIG_OFFSET_ADDR, 0x1);//KEY1   -   GPIO6_1
 
    //配置为输出
    u32Reg = REG_READ(gpio_15_virtual_addr + GPIO_DIR_OFFSET_ADDR);
    u32Reg |= (0x10);
    REG_WRITE(gpio_15_virtual_addr + GPIO_DIR_OFFSET_ADDR, u32Reg);//GPIO15_4
	
}
static int __init hi_gpio_init(void)
{
     
	int retval=0;
	
	hi3536_virtual_addr_map();
	hi3531_button_gpio_config();
	gpio15_4_output_low();
	
	return retval; 
}

static void __exit hi_gpio_exit(void)
{
     
	hi3531_virtual_addr_unmap();
	printk(" FUNC:%s LINE:%d\n", __func__, __LINE__);
}

module_init(hi_gpio_init);
module_exit(hi_gpio_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Hisilicon");

表13-18 GPIO 寄存器概览
偏移地址 名称 描述
0x000~0x3FC GPIO_DATA GPIO 数据寄存器
0x400 GPIO_DIR GPIO 方向控制寄存器
0x404 GPIO_IS GPIO 中断触发寄存器
0x408 GPIO_IBE GPIO 双沿触发中断寄存器
0x40C GPIO_IEV GPIO 触发中断条件寄存器
0x410 GPIO_IE GPIO 中断屏蔽寄存器
0x414 GPIO_RIS GPIO 原始中断状态寄存器
0x418 GPIO_MIS GPIO 屏蔽状态中断寄存器
0x41C GPIO_IC GPIO 中断清除寄存器

当 GPIO_DIR 相应的比特配置为输入时,有效读取的结果将返回管脚的值;当配置为
输出的时候,有效读取的结果将返回写入的值;
对数据寄存器GPIO_DATA进行说明:
GPIO_DATA 寄存器利用 PADDR[9:2]实现了读写寄存器比特的屏蔽操作。该寄存器对
应 256 个地址空间。PADDR[9:2]分别对应 GPIO_DATA[7:0],当相应的 bit 为高时,则
可以对相应的位进行读写操作;反之,若对应 bit 为低则不能进行操作。例如:
若地址为 0x3FC(0b11_1111_1100),则对 GPIO_DATA[7:0]这 8bit 操作全部有效。
若地址为 0x200(0b10_0000_0000),则仅对 GPIO_DATA[7]的操作有效。
什么意思呢,就是说,地址0x3FC(0b11_1111_1100)[10:2]位分别对应了GPIO_DATA[n]寄存器,相当于mask位的作用。
如果你要操作gpio_data[7] 第7管脚pin7 (海思的gpio脚标从0开始)那你要在0x00的偏移上加0x200 然后让它输出高往里写入0XFF。
上面例子里我操作的是gpio15pin4 也就是gpio_data[4] 也就是(0b00_0100_0000)0x40。

好了通过上面的介绍,我们可以通过himm用命令行操作寄存器让我们的gpio实时的输出高低电平,也可以用应用程序提供的接口来操作gpio。
当然也可以通过底层映射寄存器的方式来直接操作gpio的寄存器,从而达到设置和控制gpio的目的。

你可能感兴趣的:(海思,linux,嵌入式)