使用linux的gpio点亮imx6ull的led灯

一.查看硬件原理图,确定原理图上的led灯的引脚位置

二.查看imx6ull芯片手册<IMX6ULLRM>

参考资料:芯片手册《Chapter 28: General Purpose Input/Output(GPIO)》,
有 5 组 GPIO( GPIO1~GPIO5),每组引脚最多有 32 个。

led灯引脚对应的是GPIO第5组的第3个引脚。

1)打开 100ask_imx6ull-14x14.dts,在 iomuxc 节点的 imx6ul-evk 子节点下创建一个名为“pinctrl_led”的子节点。

MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03存放在                                           linux_imx6ull\imx-linux4.9.88\arch\arm\boot\dts\imx6ul-pinfunc.h文件中。

节点内容如下所示:

/* wuping LED */
pinctrl_led: ledgrp {
    fsl,pins = <
        /* 将 TAMPER3 这个 PIN 复用为 GPIO5_IO03,电气属性值为 0X10B0。 */
    	MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x10B0 /* LED0 */
    >;
};

<mux_reg conf_reg input_reg mux_mode input_val>

#define MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03        0x0028 0x02b4 0x0000 5 0

根 据 其 reg 属 性 可 知 IOMUXC 外 设 寄 存 器 起 始 地 址 为 0x020e0000

将0x10B0配置寄存器的值写入 0x020e 02b4配置寄存器。

/*相等于IOMUX_SW_MUX->GPIO5_IO03 = 0X5;
IOMUX_SW_PAD->GPIO5_IO03 = 0X10B0;*/

/* 配置 GPIO5_IO03 的 IO 属性
bit 16:0 HYS 关闭
bit [15:14]: 00 默认下拉
bit [13]: 0 kepper 功能
bit [12]: 1 pull/keeper 使能
bit [11]: 0 关闭开路输出
bit [7:6]: 10 速度 100Mhz
bit [5:3]: 110 R0/6 驱动能力
bit [0]: 0 低转换率

1 0000 1011 0000 =0x10b0


*/

芯片手册《Chapter 32​: IOMUX Controller (IOMUXC)》

2)添加 LED 设备节点

在根节点“/”下创建 LED 灯节点,节点名为“gpioled”,节点内容如下:

pioled {
	#address-cells = <1>;
	#size-cells = <1>;
	compatible = "atkalpha-gpioled";
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_led>;   /* pinctrl_led:复用功能节点名字 */
	led-gpio = <&gpio5 3 GPIO_ACTIVE_LOW>;
	status = "okay";
;

pinctrl-0 属性设置 LED 灯所使用的 PIN 对应的 pinctrl 节点。
led-gpio 属性指定了 LED 灯所使用的 GPIO,在这里就是 GPIO5 的 IO03,低电平
有效。稍后编写驱动程序的时候会获取 led-gpio 属性的内容来得到 GPIO 编号,因为 gpio 子系
统的 API 操作函数需要 GPIO 编号。

3)在Linux-4.9.88目录下: make dtbs

修改uboot中设备树名字,100ask_imx6ull-14x14_wp.dtb 为了区别之前的设备树文件。

编译后的设备树由两种更换方法:

        第一,通过nfs从pc传文件至开发板,把dtb文件替换/boot里的dtb文件,开发板/boot里面应该有两个文件zImage和*.dtb,开发板启动要用的,缺少或者不匹配内核无法启动。Starting Kernel ...之后板子再无其他输出,启动失败!替换成功后可以reboot重新启动开发板,如果正常开机就可以使用新的设备树。

        第二,通过imx6ull_flashing_tool.exe,把Ubuntu的设备树通过FileZila传输到pc上,然后替换/files文件里的.dtb文件。打开.exe,开发板设置为USB启动方式,显示设备已连接,点击更新设备树,软件会把dtb文件替换开发板/boot目录下的dtb文件。换成emmc模式,重新启动,可以用新的设备树。

[root@wu:/mnt/zheng/led]# insmod gpioled.ko            //加载驱动
[root@wu:/mnt/zheng/led]# ./ledAPP /dev/gpioled 0    //关灯
[root@wu:/mnt/zheng/led]# ./ledAPP /dev/gpioled 1    //开灯
[root@wu:/mnt/zheng/led]# rmmod gpioled                  //卸载驱动

驱动实现:

1.定义file_operations结构体变量;

static const struct file_operations led_fops = {
    .owner        =    THIS_MODULE,
    .write        =    led_write,
    .open        =    led_open,
    .release    =    led_release,
};

2.注册file_operations结构体变量;

 alloc_chrdev_region(&gpioled.devid, 0, GPIOLED_CNT, GPIOLED_NAME);

3.创建类

gpioled.class = class_create(THIS_MODULE, GPIOLED_NAME);

4.创建设备

gpioled.device = device_create(gpioled.class, NULL, gpioled.devid, NULL, GPIOLED_NAME);

5.查找设备节点

gpioled.nd = of_find_node_by_path("/gpioled");

6.获取LED所对应的GPIO

gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpio", 0);

7.使用gpio 子系统,申请io

ret = gpio_request(gpioled.led_gpio, "led-gpio");

8.设置为输出功能

ret = gpio_direction_output(gpioled.led_gpio, 1);

9.完成点灯的配置,点个灯

 gpio_set_value(gpioled.led_gpio, 0);

2.1 普通方式——IO配置

2.1) IOMUX复用选择器

与STM32的引脚复用功能类似,i.MX6ULL芯片的每个GPIO通过IOMUX设置,可以支持多种功能。

IOMUX由其左侧的IOMUXC提供寄存器给用户进行配置,它又分成MUX_Mode(IO 模式控制)以及Pad Settings(Pad 配置)两个部分:

① MUX_Mode配置:用来配置引脚的复用功能

 Pad Settings 配置:配置引脚的属性,例如驱动能力,是否使用上下拉电阻,是否使用保持器,是否使用开漏模式以及使用施密特模式还是CMOS模式等

在IOMUXC外设中关于MUX_Mode和Pad Settings寄存器命名格式如下:

IOMUXC 控制类型寄存器名称
MUX_ModeIOMUXC_SW_MUX_CTL_PAD_XXXX
Pad SettingsIOMUXC_SW_PAD_CTL_PAD_XXXX

2.1.1)MUX_Mode寄存器介绍:

从上图可以看出,IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3的MUX寄存器,其地址为0X2290014H

这个寄存器是32位的,但只用到了低5位,其中bit0~bit3(MUX_MODE)就是设置SNVS_TAMPER3的复用功能的。

SNVS_TAMPER3只能复用为 种功能 IO,即ALT5作为 GPIO5_IO03

 2.1.2)Pad Settings寄存器介绍:

 PAD 寄存器的配置项相对于MUX寄存器就更加丰富。

从下图可以看出,IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的PAD寄存器,其地址为0X2290058H

也是个32位寄存器,但是只用到了其中的低17位

2.2 普通方式——GPIO配置

上面的MUX和PAD这两种寄存器都是配置IO的,当把IO配置为了GPIO功能后,还有继续对GPIO外设的各种寄存器进行配置:

2.2.1 配置DR寄存器

DR(data register),即数据寄存器,它是32位的,一个GPIO组最大只有32个IO,因此DR寄存器中的每个位都对应一个 GPIO。

当GPIO被配置为输出模式后,向指定的位写入数据那么相应的IO就会输出相应的高低电平,例如,要设置GPIO5_IO03输出低电平,那么就应该设置 GPIO5.DR=0x08。

当 GPIO被配置为输入模式后,此寄存器就保存着对应IO的电平值,每个位对对应一个GPIO,例如,当GPIO5_IO03这个引脚接地的话,那么 GPIO5.DR 的bit3就是0。

2.2.2 配置GDIR寄存器

GDIR(GPIO direction register),即方向寄存器,也是32位的,用来设置某个GPIO的工作方向的,即输入/输出。

同样的,每个IO对应一个位,如果要设置GPIO为输入,就设置相应的位为0,如果要设置为输出,就设置为 1。

比如要设置 GPIO5_IO03 为输出,那么 GPIO5.GDIR=0x00;

2.2.3 配置PSR寄存器

PSR(Pad Status Register),即状态寄存器,也是32位的。

注意它是一个只读寄存器,每个IO对应一个位,读取相应的位即可获取对应的GPIO的状(高低电平值),功能和输入状态下的DR寄存器一样。

这个寄存器使用ipg_clk_s时钟,这意味着只有在访问这个位时才对输入信号进行采样。所以,为了同步访问这个寄存器都需要两个等待状态。

2.2.4 配置ICR1寄存器

ICR1(interrupt configuration register1)和ICR2,都是中断控制寄存器, ICR1用于配置低16个GPIO,ICR2 用于配置高16 个GPIO。

ICR1寄存器中一个GPIO用两个位,这两个位用来配置中断的触发方式:

位设置中断触发方式
00低电平触发
01高电平触发
10上升沿触发
11下降沿触发

以GPIO1_IO15为例, 若要设置该引脚为上升沿触发中断, 需要配置为:GPIO1.ICR1=2<<30。

2.2.5 配置ICR2寄存器

ICR1和ICR2(interrupt configuration register2),都是中断控制寄存器, ICR1用于配置低16个GPIO,ICR2 用于配置高16 个GPIO。

若要设置GPIO1的IO16~31的话就需要设置ICR2寄存器了,设置方式参考上面的ICR1。下面这个图与ICR1类似,只截取部分显示。

2.2.6 配置IMR寄存器

IMR(interrupt mask register),即中断屏蔽寄存器,也是32位,每个IO对应一个位。

IMR寄存器用来控制GPIO的中断禁止和使能,如果使能某个GPIO的中断,那么设置相应的位为1即可,反之,如果要禁止中断,那么就设 置相应的位为0即可。

例如,要使能GPIO1_IO00的中断,需要配置为GPIO1.MIR=1。

2.2.7 配置ISR寄存器

ISR(interrupt status register),即中断状态寄存器,也是32位,每个IO对应一个位。

只要某个GPIO的中断发生,则ISR中相应的位就会被置1。所以通过读取ISR寄存器来判断是否发生了中断,类似于学习STM32用到的中断标志位。

当中断处理完以后,必须清除中断标志位,清除方法就是向ISR中相应的位写1,也就是写1清零。

为了同步,读访问需要两个等待状态,复位需要一个等待状态。

2.2.8 配置EDGE_SEL寄存器

EDGE_SEL(edge select register),即边沿选择寄存器,也是32位,每个IO对应一个位。

它用来设置边沿中断, 并会覆盖ICR1和ICR2的设置。

如果相应的位被置1,则相当于设置了对应的GPIO是双边沿(上升沿和下降沿)触发。例如,设置GPIO1.EDGE_SEL=1,则表示 GPIO1_IO01是双边沿触发中断,无论 GFPIO1_CR1的设置为多少。

2.3 GPIO各寄存器地址查询表

上面介绍的有关GPIO的7种寄存器,为了方便查询各个寄存器的地址,这里列出一张表:

2.4 时钟配置

与ST32类似,I.MX6ULL每个外设都有一个外设时钟,使用GPIO时,也必须先使能对应的时钟。

2.4.1 配置CCM寄存器

CCM(Clock Controller Module)时钟控制模块寄存器用来使能外设时钟。 CMM一共有CCM_CCGR0~CCM_CCGR6这 7 个寄存器,控制着I.MX6U的所有外设时钟开关。

GPIOxCCGRx(addr)CGx
GPIO1_CLK_ENABLECCGR1(0X020C406C)CG13
GPIO2_CLK_ENABLECCGR0(0X020C4068)CG15
GPIO3_CLK_ENABLECCGR2(0X020C4070)CG13
GPIO4_CLK_ENABLECCGR3(0X020C4074)CG6
GPIO5_CLK_ENABLECCGR1(0X020C406C)CG15

以CCM_CCGR0为例,它是个32位寄存器,每2位控制一个外设的时钟,比如 bit31:30 控制着GPIO2 的外设时钟,两个位就有 4 种操作方式:

位设置时钟控制
00所有模式下都关闭外设时钟
01只有在运行模式下打开外设时钟,等待模式和停止模式下均关闭外设时钟
10未使用(保留)
11除了停止模式以外,其他所有模式下时钟都打开

若要打开GPIO2的外设时钟,只需要设置CCM_CCGR0的bit31和bit30为1即可,即 CCM_CCGR0=3 << 30。

2.5 配置总结

使用i.MX6ULL的GPIO时,需要如下几步配置:

使能 GPIO 对应的时钟

配置MUX寄存器,设置IO的复用功能,使其复用为GPIO功能

配置PAD寄存器,设置 IO 的上下拉、速度等

配置GPIO的各种寄存器(DR、GDIR、...),设置输入/输出、是否使用中断、默认输出电平等

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值