1. 程式人生 > >HI3518linux--GPIO配置

HI3518linux--GPIO配置

由於海思linux沒有提供GPIO驅動,但是有himm工具,所以可以直接使用它配置GPIO。

如果需要驅動的話,網上也有資源連結如下

http://bbs.ebaina.com/forum.php?mod=viewthread&tid=8833&highlight=gpio

由於除錯的時候還沒有正式的板子,所以不知道到底是配置不對還是管腳數錯,最終花了兩個週末的時間才點亮LED。。。

首先講一下配置GPIO的流程;

    1.管腳複用設定

    2.設定輸入輸出

    3.設定管腳狀態(高/低)

注:本文只設置GPIO的輸出設定,其他功能待新增;不想看原理的直接跳到最後,看程式碼例子。

例: 設定GPIO7-3 輸出為高。

    按照步驟來,

    1、設定管腳複用為GPIO

          檢視資料手冊(可以直接搜尋 7_3)

                

                如上圖所示,在手冊的308頁,GPIO7_3和PWM1是同一個管腳,如果要使用GPIO功能,則要設定暫存器muxctrl_reg59為1。接下來就是要知道 muxctrl_reg59的地址,可以看到表格上方Offset Address 是0X0EC,意思是從基地址偏移0X0EC個位置就是暫存器muxctrl_reg59。那麼基地址是多少,往前翻翻手冊(274頁)可以得到基地址0x200F_0000 。

那麼暫存器muxctrl_reg59的地址就是 (0x200F_0000 | 0X0EC)0X200F00EC。

所以設定GPIO模式 : himm 0X200F00EC 0x1

              pwm1模式:himm  0X200F00EC 0x0

 2、設定GPIO7_3為輸出

        查詢手冊(1587頁)

                        

        如圖,可以得到各組GPIO的基地址。GPIO7為0x201B_0000

        

            如圖所示,這個配置管腳功能的暫存器,表格中的偏移地址與之前的用法一樣。

              

              設定管腳輸出需要用到暫存器GPIO_DIR,偏移地址為0X400。

               那麼GPIO7方向控制暫存器為(0x201B_0000 | 0X400)0x201B0400 ,

                這個暫存器器一共有八位,每一位對應GPIO7_0到GPIO7_7 ,0為輸入,1為輸出。

                所以設定GPIO7_3為輸出:himm 0x201B0400 0x08

                注意:這一次設定相當於是把其他幾位都設定為0了,所以實際運用中最好是先讀出此暫存器的值 ,然後 或 0X08 ,在寫入。

3、設定GPIO7_3輸出為1

        

    如圖(1588頁),暫存器GPIO_DIR是控制管腳輸出資料和輸入資料的暫存器。可以看到它的偏移地址是不固定的因為用來對應一組(就比如GPIO7)GPIO的不同管腳(比如 GPIO7_1、GPIO_2)的組合。而且它是從低三個位開始的。

            

   如圖,io表示IO號,ad表示PADDR。GPIO7_3就是io行3的位置,(ad行)相應位置設定1,

    ad的值為(00 0010 0000)0x20。這就是GPIOx_3的偏移值。

    那麼GPIO7_3的資料暫存器 資料暫存器的地址就是:(0x201B_0000 | 0X20)0x201B0020 

    設定GPIO7_3為輸出高:himm 0x201B0020 0x08

[如果要多個io一起設定的話 ,也是可以,只要把相對應的ad設為1就好]

程式碼例子:

    1. 設定GPIO7_3輸出為高(himm)

        1)himm 0x200F00EC 0x01  //設定管腳複用為GPIO

        2)himm 0x201B0400 0x08  //設為輸出狀態

        3)himm 0x201B0020 0x08  //設定GPIO7_3輸出為1

    2.設定GPIO7_3輸出為高(驅動)

int gpio_init(void)
{
	int ret, gpiofd;
	gpio_ctl_t val;
	gpiofd = dev_open();
	if(gpiofd < 0)
	{	
		printf("open gpio failed\n");
		return -1;
	}
	//設定管腳複用
	val.uRegAddr = 0x200F00EC;            
	val.uRegValue = 0x01;
	ret = ioctl(gpiofd, DRV_reg_write, &val);
	dev_close(gpiofd);
	return ret;

}

void led_on()
{
	unsigned int regvalue = 8;
	reg_read(0x201B0400, &regvalue);    
	regvalue &= 0xFFFFFFFC;
	reg_write(0x201B0400, regvalue);
	gpioSetMode(7, 3, GPIO_OUTPUT, 0);
}


//關於驅動連結 在文章開頭  
//在此感謝一下 分享驅動的大神