热度 2
2023-3-1 14:46
1516 次阅读|
0 个评论
B y Toradex 秦海 1). 简介 为了提高处理器的设计灵活性和可用性, NXP 的所有 i.MX 系列处理器都配备了基于 IOMUX Controller (IOMUXC) 和 IOMUX 来使能 Pin Mux 功能,使得一个特定的 IO 管脚可以选择不同的可能多达 8 种的功能定义模块 (ALT0, ALT1, ALT2, ALT3 ... ) ,同时为了适配不同的功能模块, IOMUXC 可以对应配置管脚的配置参数(比如上拉 / 下拉,驱动能力等等)。本文就基于 NXP 最新的 i.MX8 系列平台说明 Pin Mux 的定义和配置方式。 本文所演示的平台来自于 Toradex Apalis iMX 8 嵌入式平台,这个平台是基于 近年发布的 NXP iMX 8 系列 ARM 处理器,核心为 Cortex-A 72/A53 。 2. 准备 a). Apalis iMX8 ARM 核心版配 合 Apalis Eva Board 载板, 并连接调试串口用于测试 。 b). 参考 这里 下载 Toradex Ycoto Linux BSP5 Linux Kernel (toradex_5.4-2.3.x-imx 分支 ) 用于后续 Device Tree 修改和编译。 3). 规划管脚功能定义 a). 参考 Apalis iMX8 datasheet 文档 4.4 SoC Functions List 章节来找到所需要的 iMX8 管脚的功能定义和默认状态,比如这里我们就用 X1 Pin 6 作为示例,其基本信息如下图,有 4 个功能模块定义,目前在 Toradex Ycoto Linux Device Tree 中默认配置功能是黄色高亮显示的 ALT1 PWM 功能, Reset Sate 参考 datasheet 4.3 Pin Reset Status 章节定义是 Pull-Down (Input) 状态。 b). Device Tree 中一个管脚的 IOMUX 定义由两部分组成,如下是上述管脚 X1 Pin 6 在 Devcie tree 中作为 PWM 功能的管脚 Pin mux 定义作为参考 -------------------------------- /* Apalis PWM3 */ pinctrl_pwm0: pwm0grp { fsl,pins = < IMX8QM_UART0_RTS_B_LSIO_PWM0_OUT 0x00000020 ; }; -------------------------------- ./ fsl,pins 里面的定义就是具体的 Pin mux 定义,包含两部分。第一部分是 PIN_FUNC_ID ,其由 _ 组成,示例中 ” IMX8QM_UART0_RTS_B ” 就是 ,而 ” LSIO_PWM0_OUT ” 就是 ,也就是具体的功能模块定义( ALT1 )。 PIN_FUNC_ID 在 Kernel Device Tree 源代码中通过相应 pinctrl 头文件定义,下面是 NXP iMX8/iMX8x/iMX8MM/iMX8MP 系列处理器对应的头文件位置列表供参考 -------------------------------- Apalis iMX8 - /include/dt-bindings/pinctrl/pads-imx8qm.h Colibri iMX8X - /include/dt-bindings/pinctrl/pads-imx8qxp.h Verdin iMX8M Plus - /arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h Verdin iMX8M Mini - /arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h -------------------------------- ./ 第二部分是管脚的配置参数 (BIT_CONFIG) ,详细的定义需要从对应 SoC 处理器的 Reference Manual 文档 IOMUXD 章节的对应管脚 Pad Control 寄存器说明找到,比如上述示例引脚的相关定义可以从 NXP iMX8QM Reference Manual 9.2.5.1.26 UART0_RTS_B (UART0_RTS_B) 章节找到,如下。 需要注意的是默认情况下 Pin Ctrl 寄存器 29-27bit mux mode 的配置保持 000 即可,因为这部分已经在前面 PIN_FUNC_ID 那里定义了。另外配置参数还有下面两个软件设置状态: -------------------------------- NO_PAD_CTL(1 << 31) - 声明当前管脚无需配置参数 SION(1 << 30) - Software Input On Field ,强制当前管脚 Input Path 而忽略 mux mode 设定的状态 -------------------------------- ./ Kernel Documentation 关于 NXP i.MX 系列处理器的 Pin Mux 的说明可以参考如下 -------------------------------- / Documentation/devicetree/bindings/pinctrl/fsl, * -pinctrl.txt -------------------------------- c ). 基于上述描述,这里要将上述管脚功能定义从 PWM 修改为标准 GPIO ,并将 GPIO 管脚的初始状态设置为下拉( pull down )和高驱动能力( high drive strength ) ./ 查找 pads-imx8qm.h 文件确定所需 PIN_FUNC_ID 为 “IMX8QM_UART0_RTS_B_LSIO_GPIO0_IO22” -------------------------------- #define IMX8QM_UART0_RTS_B_DMA_UART0_RTS_B IMX8QM_UART0_RTS_B 0 #define IMX8QM_UART0_RTS_B_LSIO_PWM0_OUT IMX8QM_UART0_RTS_B 1 #define IMX8QM_UART0_RTS_B_DMA_UART2_RX IMX8QM_UART0_RTS_B 2 #define IMX8QM_UART0_RTS_B_LSIO_GPIO0_IO22 IMX8QM_UART0_RTS_B 3 -------------------------------- ./ 从 iMX8QM Reference Manual UART0_RTS_B Pin Ctrl 寄存器确认所需的 BIT_CONFIG 参数是 0x00000040 4). 修改配置 Device Tree 文件 a). 修改方式由两种,一种是直接在 Kernel 源代码中修改设备对应的 Device Tree 文件源码然后重新编译 Device Tree binary 文件( .dtb) 后部署,另外一种是通过生成 Device Tree Overlay 文件的方式直接部署,无需编译源代码。本文就简单示例通过源代码编译方式,如果需要了解 Device Tree Overlay 方式可以参考如下两个文档 ./ https://developer.toradex.cn/knowledge-base/pin-multiplexing-in-device-tree ./ https://www.toradex.cn/blog/device-tree-overlay-shi-yong ./ https://developer.toradex.cn/knowledge-base/device-tree-overlays-linux b). Device Tree 源代码修改 Patch 如下,分别关闭默认占用 X1 Pin 6 的 PWM 功能,以及重新将 X1 Pin6 配置为 GPIO 通过 iomuxc 输出。另外,具体的 Device Tree 编译和部署可以参考如下文档 ./ https://developer.toradex.cn/knowledge-base/build-u-boot-and-linux-kernel-from-source-code ./ https://developer.toradex.cn/device-tree-customization ./ https://developer.toradex.cn/knowledge-base/device-tree-customization-examples -------------------------------- diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi index 0a4fe3898993..b75c649e706c 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi @@ -271,7 +271,7 @@ /* Apalis PWM3, MXM3 pin 6 */ &pwm0 { - status = "okay"; + status = "disabled"; }; /* Apalis PWM4, MXM3 pin 8 */ diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi index 0ece42889af8..8dfe04714ec7 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi @@ -426,7 +426,7 @@ , , , , , , - ; + , ; apalis-imx8qm { /* Apalis AN1_ADC */ @@ -600,6 +600,13 @@ IMX8QM_MLB_DATA_LSIO_GPIO3_IO28 0x00000021 ; }; + + /* Apalis Pin Mux Demo GPIO9 */ + pinctrl_gpio9: gpio9grp { + fsl,pins = < + IMX8QM_UART0_RTS_B_LSIO_GPIO0_IO22 0x00000040 ; + }; /* Apalis I2C1 */ pinctrl_lpi2c2: lpi2c2grp { -------------------------------- b). 测试部署 Device Tree 文件 ./ 在修改部署之前 X1 Pin 6 管脚的状态可以参考如下文章,通过连接 LED 硬件配合 libgpiod 库进行测试,由于被 PWM 驱动占用因此无论通过 gpioset 如何设置这个管脚,外部 LED 始终是不亮状态没有变化 https://www.toradex.cn/blog/nxp-imx8-qian-ru-shilinux-xialibgpiod-ying-yong-shi-li -------------------------------- ### 系统启动后查看 PWM 驱动状态,管脚对应的 PWM 设备 (5d000000.pwm) 状态正常 ### root@apalis-imx8-07308034:~# cat /sys/kernel/debug/pwm platform/57244000.pwm, 1 PWM device pwm-0 (backlight ): requested enabled period: 6666667 ns duty: 3111111 ns polaritye platform/5d030000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal platform/5d020000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal platform/5d010000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal platform/5d000000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal ### 由于管脚被 PWM 驱动占用,因此启动后 LED 为灭状态,而且无论通过 gpioset 如何设置, LED 始终为灭状态,无法控制 ### root@apalis-imx8-07308034:~# gpioset 0 22=1 root@apalis-imx8-07308034:~# gpioset 0 22=0 -------------------------------- c). 修改部署新的 Device Tree binary “imx8qm-apalis-v1.1-eval.dtb” 后,通过 LED 发现可以正常控制 X1 Pin 6 管脚作为输出的电平状态了 -------------------------------- ### 系统启动后,基于管脚初始状态为 Pull Down ,连接的 LED 灯为灭状态 ### root@apalis-imx8-07308034:~# gpioinfo 0 |grep -e "MXM3_6" line 22: "MXM3_6" unused input active-high ### 查看 PWM 驱动状态,管脚对应的 PWM 设备 (5d000000.pwm) 已经没有了 ### root@apalis-imx8-07308034:~# cat /sys/kernel/debug/pwm platform/57244000.pwm, 1 PWM device pwm-0 (backlight ): requested enabled period: 6666667 ns duty: 3111111 ns polarity: inverse platform/5d030000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal platform/5d020000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal platform/5d010000.pwm, 1 PWM device pwm-0 ((null) ): period: 2730667 ns duty: 0 ns polarity: normal ### 通过如下命令将管脚配置为输出高电平,连接的 LED 灯为亮状态 ### root@apalis-imx8-07308034:~# gpioset 0 22=1 ### 翻转输出为低电平,,连接的 LED 灯为灭状态 ### root@apalis-imx8-07308034:~# gpioset 0 22=0 -------------------------------- ./ 如果将 X1 Pin 6 管脚的 Pin Mux 配置 BIT_CONFIG 参数改为 0x000000 2 0 , 也就是由 Pull Down 改为 Pull Up ,那么实际测试上电启动系统后,连接的 LED 灯为亮状态。 5 ). 总结 本文 基于 NXP iMX8 处理器演示了 Pin Multiplexing 的定义和配置方法,其他 i.MX 处理器也都是类似的思路。