一、前言

高通平台,硬件同事让我在lk阶段去控制一个gpio模拟时序,通过查询,发现可通过gpio_tlmm_config()函数实现初始化,gpio_set_dir()设置高低电平。但是其中有两个地方折磨了我整整一天,记录一下,如果有错误,请指正

二、函数介绍

gpio_tlmm_config(uint32_t gpio,uint8_t func, uint8_t dir, uint8_t pull, uint8_t drvstr, uint32_t enable)函数在platform目录下,这个函数一定要注意!!:

设置gpio为普通Io时,输出或者输入的设置参数不是第三个 dir,而是最后一个 enable,DISABLE为输出,ENABLE为输入。dir函数在函数中根本没有调用,他就是个无效的参数,怎么设置都不影响。

剩下的就是正常参数,第一个为gpio号,比如gpio50,就为50(这个编号好像不一定,自己根据自己的平台确认一下);

第二个参数时设置IO的功能,0就为普通IO,也可以设置SPI、IIC之类的。

第四个参数为上下拉,输出为不拉(no pull),输入时上下拉要根据硬件写。

第五个参数为驱动强度,这个一般会有相应的文档描述,不同的gpio驱动强度不同。比如我这个平台。gpio50的驱动强度就是8mA

第六个参数,设置使能,或者输入输出。

void gpio_tlmm_config(uint32_t gpio,uint8_t func,
                     uint8_t dir, uint8_t pull,
                     uint8_t drvstr, uint32_t enable)
{
       uint32_tval = 0;
 
       val|= pull;
       val|= func << 2;
       val|= drvstr << 6;
       val|= enable << 9;//如果func=0,enable=1为输出,enable=0为输出
 
       writel(val,(uint32_t *)GPIO_CONFIG_ADDR(gpio));
       return;
}

设置高低电平函数 ,gpio_set_dir()函数,看函数名字,以为是设置方向的,但是没想到是设置高低电平的,唉,让我自我怀疑了很久。也有很多平台的设置高低电平函数为gpio_set(),函数参数和内容都是一样的,只有名字不一样。

第一个参数时gpio编号,

第二个参数为2时输出高,0时输出低。之所以这样设置,是因为GPIO_IN_OUT寄存器的两位,0位为GPIO_OUT,控制输出状态设置,1位为GPIO_IN使能当前IO是否可读。当设置输出高电平时,寄存器的值为二进制10,等于十进制2,低电平为00,等于十进制0。

void gpio_set_dir(uint32_t gpio, uint32_t dir)
{
	writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio));

	return;
}

三、使用例子

gpio_tlmm_config(50, 0, GPIO_OUTPUT, GPIO_NO_PULL,

    GPIO_8MA, GPIO_DISABLE);//设置GPIO50为输出模式

gpio_set_dir(50, 2);//设置输出高电平