1、概述
最近在搞一个老平台AM335x,没有设备树,所以碰到一点麻烦,记录一下。
常规操作,不再赘述。
2、静态编译
ok,用万用表测量gpio4口电压,what?居然还是 高电平。然后看了一眼debug信息,gpio-4已经设置成low。
这,怀疑人生了,是自己技术有问题。于是一通琢磨,
arch\arm\mach-omap2\board-am335xevm.c
static struct pinmux_config i2c1_pin_mux[] = {
{"spi0_d1.i2c1_sda", OMAP_MUX_MODE2 | AM33XX_SLEWCTRL_SLOW |
AM33XX_PULL_ENBL | AM33XX_INPUT_EN},
{"spi0_cs0.i2c1_scl", OMAP_MUX_MODE2 | AM33XX_SLEWCTRL_SLOW |
AM33XX_PULL_ENBL | AM33XX_INPUT_EN},
{NULL, 0},
};
这一块要改一下,gpio4和gpio5现在配置的是i2c1的sda和scl pinmux功能,所以不能用成gpio模式。修改如下。
static struct pinmux_config i2c1_pin_mux[] = {
{"spi0_d1.gpio0_4", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT|AM33XX_PULL_UP},
{"spi0_cs0.gpio0_5", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT|AM33XX_PULL_UP},
{NULL, 0},
};
编译后gpio口又可以愉快的操作了。
总结
在操作gpio口之前需要确认该gpio是否有被其他设备或者总线复用功能,如果有,需要先修改成gpio口功能后才能echo操作。
3、动态编译
模块化编译的ko文件进行操作,那么我们需要绕开内核的配置。所以需要在ko文件中进行配置。
第一步:
先在原理图上查找对应gpio口,我们对应的gpio口是gpio3_17。
第二步:
在规格书上查找对应的gpio口的配置,对应的gpio口是模式7。
第三步:
参考手册中查找控制器寄存器以及offset偏置量.
第四步:
配置gpio口初始化设置,对寄存器进行操作配置,配置模式7和输出模式,这样上层才可以进行ioctl控制。
void TEST_PIN_init(void)
{
int ret;
int i;
uint32_t tmp_base;
for (i = 0; i < 1; i++)
{
ret = gpio_request(c_pin_gpios[i], "Test2");
if (ret) {
printk("%s: request-%d= GPIO %d for TEST failed, ret = %d\n", DEVICE_NAME,i,
c_pin_gpios[i], ret);
}
}
request_region(AM33XX_CONTROL_PADCONF_MUX_PBASE+AM33XX_CONTROL_PADCONF_MCASP0_AHCLKR_OFFSET,4,"c-test");
tmp_base=(unsigned)ioremap(AM33XX_CONTROL_PADCONF_MUX_PBASE+AM33XX_CONTROL_PADCONF_MCASP0_AHCLKR_OFFSET,4);
writel(OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT,tmp_base);
gpio_direction_output(c_pin_gpios[0], 1);
gpio_set_value(c_pin_gpios[0], 0);
printk(DEVICE_NAME"\tTEST_PIN_initialized 1\n");
}
第五步:
ioctl控制代码编写,完成后编译生成ko文件,arm板insmod ko文件后,上层就可以愉快的调用了。
static long beep_ioctl(struct file *file, unsigned int cmd)
{
printk("%s test,cmd = 0x%x,\n",__func__,cmd);
if(cmd == TEST_OFF)
{
gpio_set_value(c_pin_gpios[0], 0);
}
else if (cmd == TEST_ON)
{
gpio_set_value(c_pin_gpios[0], 1);
}
return 0;
}
第六步
上层测试模块接口,大功告成,这样软件cv工程师就可以愉快的玩耍了。可以通过测试波形或者示波器等debug工具进行验证。
ioctl(fd,GPIO_HIGH);
ioctl(fd,GPIO_LOW);
总结
对于gpio口的配置,一定要先进行gpio口的寄存器功能模式配置,配置完成后才能愉快的调用。