pinctrl子系统
pinctrl子系统简介
pinctrl 和 gpio 子系统就是驱动分离与分层思想下的产物,驱动分离与分层其实就是按照面向对象编程的设计思想而设计的设备驱动框架。
- gpio子系统不用多去介绍,决定一个管脚作为普通管脚时候的输入输出还是电平高低。
- pinctrl子系统不一样,是决定io口的复用功能,决定io是为普通io还是其他功能io,并且当其为普通io时候,确定其电气属性,是上拉电阻还是下拉,输出速度多少等属性
如果学过stm32的,使用io前,应该知道要配置一个复用功能。一个管脚上常常绑定了很多功能,根据开发者需求进行配置。
设备树中pinctrl子系统的体现方式
使用一个例子
在自己定义的节点之中使用pinctrl子系统。
my_gpio_led {
compatible = "my_gpio_led";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_my_gpio_led>;
led-gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>;
status = "okay";
};
然后在iomux节点下进行pinctrl的配置,label名字一定要以pinctrl_开始。
pinctrl_my_gpio_leds: my_gpio_leds {
fsl,pins = <
MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x17059 /* led run */
>;
};
这样子gpio4_16就被配置为一个普通管脚,可以用来电灯了(有时不去配置,系统有可能默认也是普通模式,建议配置一下)
pinctrl节点属性的配置方式
在自己节点添加的两行内容很好理解,但是在pinctrl中的一行内容很多人不知如何去配置。
- 本文最主要的内容就是探索如何配置这两个参数
参数一 MX6UL_PAD_NAND_DQS__GPIO4_IO16
参数一就是一个宏定义,他的定义位置在和设备树同路径下的imx6ul-pinfunc.h文件之中。
找到上面示例的宏定义位置
#define MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x01b8 0x0444 0x0000 5 0
可以看出来,是一个由五个数,前面五个hex数组成的宏。
无需百度,查看该文件的最前面,果然发现玄机。
/*
* The pin function ID is a tuple of
* <mux_reg conf_reg input_reg mux_mode input_val>
*/
看到注释,即对应后面五个参数的内容。
-
mux_reg - 0x01b8:是寄存器偏移地址,其对应的是mux_ctl控制寄存器的偏移地址。控制寄存器即控制管脚功能为哪个,查找数据手册。
-
conf_reg - 0x444配置寄存器的偏移地址,配置寄存器即为配置管脚的一些属性的参数,查找数据手册。
-
input_reg - 0x0000 input寄存器偏移地址,有的外设有input_reg,查看手册gpio4_16是不带有的,故为0.
-
mux_mode - 0x5 mux复用功能寄存器,这个值即为选择哪个复用功能,查看数据手册。
我们选择0101第五个功能,作为普通管脚。 -
input_val - 0 输入寄存器的值,这里无效
参数二 0x17059
本文讲解参数二,该参数十分重要,决定了管脚的电气属性,类似stm32中io口的配置上拉下拉、输出速率那些参数。但是这个参数如何计算,是个难题。
打开数据手册,查看管脚控制寄存器部分
这个寄存器的值即为0x17059,下面开始详聊这个寄存器每个位。
- 把0x17059拆成二进制,1 0111 0000 0101 1001 ,依次放入寄存器中。
分析每个位的作用
-
HYS - 1 使能迟滞比较器,0 则不使能
-
PUS - 01 配置47k的上拉电阻
其他有100k下拉和100k、22k上拉的配置 -
PUE - 1 拉动/保持字段。使其可以外部电路断电保持拉动状态。
-
PKE - 1 使能上下拉保持器。0则为不使能。
-
ODE - 0 作为输出时候使用,禁止开路输出。1则为允许。
-
SPEED - 01 管脚速率,使用中速100MHz。
00 低速50MHz,10中速,11高速200MHz。 -
DSE - 011 表示IO的驱动能力。
000 不使能输出驱动,001为一个输出能力基准,根据需求选择。 -
SRE - 1 设置压摆率,设为高速压摆率
pinctrl配置工具
看到前面复杂的配置方式,其实很头疼,如果每次都去计算下,工作量稍大,其实nxp官方提供了,一个引脚配置工具,图形化的交互,十分友好。
官方链接入口
需要先注册用户才能下载。
界面中配置管脚电气属性的地方,不用关心每个属性在寄存器的位置还是很友好的。
并且可以直接生成需要的pinctrl配置参数,可谓把前面所讲的内容直接抛弃,即拿即用,十分方便。