一. 简介
这里主要学习创建SPI节点及ICM20608设备(SPI从设备)子节点。
二. ICM20608设备的硬件原理图
ICM20608设备的硬件原理图如下所示:
通过硬件原理图可以看出,ICM20608设备(SPI设备)的SPI使用的是(IMX6ULL的)SPI3接口,的四个IO对应如下:
SPI3_CS -> UART2_TXD //片选信号
SPI3_SCLK -> UART2_RXD //时钟信号
SPI3_MISO -> UART2_RTS //主收从发
SPI3_MOSI -> UART2_CTS //主发从收
三. 创建SPI节点及SPI设备子节点
这里学习支持设备树的情况下,通过设备节点信息来描述SPI设备信息,方法就是在设备树文件中创建SPI节点及SPI设备节点,IO的pinctrl节点。
1. 创建IO的pinctrl节点
打开ubuntu系统,通过 vscode软件打开 Linux内核源码(NXP官方提供。在 imx6ull-14x14-evk.dts设备树文件中添加 SPI的 pinctrl节点信息。
注意:这里开发板使用的 Nand_Flash版的ALPHA开发板,所对应的设备树文件为 imx6ull-alientek-nand.dts,设备树根节点不在这个文件中,所以要找到 imx6ull-alientek-nand.dts调用的上层设备树文件imx6ull-14x14-evk.dts。调用关系如下:
imx6ull-alientek-nand.dts
-> imx6ull-14x14-evk-gpmi-weim.dts
-> imx6ull-14x14-evk.dts
打开 imx6ull-14x14-evk.dts设备树文件,在 "&iomuxc"节点下添加 SPI的 pinctrl节点:
/*WeiWuXian //2024/04/15*/
pinctrl_ecspi3: icm20608{
fsl,pins = <
MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0 /* CS */
MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x10b0 /* SCLK */
MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x10b0 /* MOSI */
MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x10b0 /* MISO */
>;
};
UART2_TX_DATA 这个 IO 是 ICM20608 的片选信号,这里我们并没有将其复用为 ECSPI3
注意:这里添加好 IO以后,需要在设备树文件中检查这四个IO是否有其他设备在使用,复用的话,这里配置就不能使用了。如果有其他设备使用到,则需要删除掉。
在imx6ull-14x14-evk.dts设备树文件中 分别搜索 UART2_TX,UART2_RX,UART2_CTS,以及UART2_RTS,有其他设备使用则需要屏蔽掉,如下设备有使用到则屏蔽掉:
pinctrl_uart2: uart2grp {
fsl,pins = <
/* MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1 */
MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1
MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1
>;
};
pinctrl_uart2dte: uart2dtegrp {
fsl,pins = <
/* MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1
MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1 */
MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x1b0b1
MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x1b0b1
>;
};
..........................
pinctrl_flexcan2: flexcan2grp{
fsl,pins = <
/* MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020 */
>;
};
2. 创建SPI节点及SPI设备子节点
关于所创建的SPI节点可以查看 SPI节点的绑定文档,在Linux内核源码如下目录下:
/linux-imx-rel_imx_4.1.15_2.1.0_ga\Documentation\devicetree\bindings\spi\fsl-imx-cspi.txt
也就是 fsl-imx-spi.txt 绑定文档 ,该文档说明了SPI节点如何创建,包括SPI节点必须写的属性或可选的属性,也会有SPI节点的举例。
我们也可以参考 imx6qdl-sabresd.dtsi 这个设备树头文件中关于 SPI节点的内容,在此文件里面找到如下所示内容:
&ecspi1 {
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio4 9 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
status = "okay";
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,m25p32";
spi-max-frequency = <20000000>;
reg = <0>;
};
};
在 imx6ull-14x14-evk.dts设备树文件的最后,添加 SPI节点及SPI设备子节点:
&ecspi3 {
fsl,spi-num-chipselects = <1>; /*片选数量*/
cs-gpios = <&gpio1 20 0>; /*设置为软件片选*/
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi3>;
status = "okay";
icm20608: icm20608@0 {
compatible = "alientek,icm20608"; /*设备与驱动匹配(设备树匹配方法)*/
spi-max-frequency = <8000000>; /*SPI从设备icm20608最大支持频率*/
reg = <0>; /*SPI通道*/
};
};
这里也需要检查 gpio1 20是否有其他设备使用,即在 imx6ull-14x14-evk.dts设备树文件中进行搜索 "gpio1 20"字符串是否在其他设备中使用到,如果有就必须删除或屏蔽掉。
& ecspi3: 意思是向 ecspi3节点追加内容,根设备树文件 imx6ull.dtsi中其实已经存在 ecspi3节点(NXP官方写的),这里是在NXP官方提供的 ecspi3节点信息基础上追加(或更改)信息。
第 3 行,一定要使用 “cs-gpios” 属性来描述片选引脚,SPI 主机驱动就会控制片选引脚,SPI主机控制器驱动实现了SPI的软件片选功能, 后面我们在编写SPI设备驱动时,软件上不用手动设置片选电平的高低。
第 5 行,设置 IO 要使用的 pinctrl 子节点,也就是我们在示例代码 62.5.1.1 中新建的pinctrl_ecspi3。
第 8~12 行,icm20608 设备子节点,因为 icm20608 连接在 ECSPI3 的第 0 个通道上,因此,@后面为 0。
第 9 行设置节点属性兼容值为“alientek,icm20608”。
第 10 行设置 SPI 最大时钟频 率为 8MHz,这是 ICM20608 的 SPI 接口所能支持的最大的时钟频率。
第 11 行,icm20608 连接在通道 0 上,因此 reg 为 0。
编译设备树文件
make dtbs
这里可以正常编译通过。会生成新的设备树文件 imx6ull-alientek-nand.dtb。
接下来开发板上电后加载运行新的设备树文件,测试SPI节点及icm20608设备子节点是否创建好。