调试过程中,很重要的参照开发资料给的复用GPIO,基本所有工程师都需要去了解并且调试,需要注意的是不同开发板会存在差异,我们使用过程中需要注意一些细节的修改,如果是同一平台按照如下操作可以调试成功,亲测。简单的使用步骤附(飞凌工程师参考笔记): 设备树说明: emmc 核心板 256M nand 核心板 设备树文件 arch/arm/boot/dts/okmx6ull-s-emmc .dts arch/arm/boot/dts/okmx6ull-s-nand. dts 上述两个设备树文件最终都会调用 imx6ull-14x14-evk.dts 1. 现采用 CSI_DATA01 用作 GPIO。 2. 首先在 arch/arm/boot/dts/imx6ul-pinfunc.h 查找 此处的具体参数不再说明,查看 IMX6ULRM.pdf 手册中对应寄存器。(可以查看应用笔记中的“引脚 复用的参数说明”) 3. 在设备树中 iomux 中添加复用 gpio 引脚如下: 同时在设备树中搜索 MX6UL_PAD_CSI_DATA01 引脚名称,看其他地方是否有复用成其他功能。 可以看到此引脚也复用成了 CSI 功能,所以需要将 csi 功能屏蔽掉。技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 5 - 编译设备树。替换设备树,并重新烧写。 4. 此时可以使用 echo 命令进行控制,以 GPIO4_IO22 为例进行命令说明。 4.1 GPIO 设置,步骤如下: a 计算对应 sys/class/gpio 的值 GPIOn_IOx = (n-1)*32 + x GPIO4_IO22=( 4-1)*32+22=118 b 将 GPIO4_IO22 设置为输出。 echo 118 > /sys/class/gpio/export 用于通知系统需要导出控制的 GPIO 引脚编号 echo "out" > /sys/class/gpio/gpio118/direction 控制为输出 echo "1" > /sys/class/gpio/gpio118/value 输出为高电平 或者 echo "0" > /sys/class/gpio/gpio118/value 输出为低电平 echo 118 > /sys/class/gpio/unexport 通知系统取消导出 c 将 GPIO4_IO22 设置为输入。 echo 118 > /sys/class/gpio/export 用于通知系统需要导出控制的 GPIO 引脚编号 echo "in" > /sys/class/gpio/gpio118/direction 控制为输入 这时给该引脚接高电平,输入即为高电平,反之为低电平 echo 118 > /sys/class/gpio/unexport 通知系统取消导出 d 另外客户可以自己通过 shell 文件来控制多个 gpio 做为输入或者输出。 4.2 GPIO 输出测试 编写测试脚本 vi gpiotest_o.sh #!/bin/bash # gpio list gpio (bank-1)*32 + nr for test in 118 119 120 137 136 12技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 6 - do echo Exporting pin $test. echo $test> /sys/class/gpio/export echo Setting pin $1. echo out > /sys/class/gpio/gpio$test/direction echo $1 > /sys/class/gpio/gpio$test/value echo $test> /sys/class/gpio/unexport done echo complete 修改脚本执行权限:chmod u+x gpiotest_o.sh 测试 gpio 输出为低。进入到脚本所在路径:./gpiotest_o.sh 0 所有 GPIO 输出低电平 0V。 测试 gpio 输出为高电平。进入到脚本所在路径:./gpiotest_o.sh 1 所有 GPIO 输出高电平。输出的高电平,根据引脚所在的电源域不同,可能会有区别。 另外有些客户发现 echo 118 > /sys/class/gpio/export 用于通知系统需要导出控制的 GPIO 引脚编号 echo "out" > /sys/class/gpio/gpio118/direction 控制为输出 echo "1" > /sys/class/gpio/gpio118/value 输出为高电平 cat /sys/class/gpio/gpio118/value 仍旧为 0 原因如下图所示,客户可以从 CPU 手册中查找到相关内容: 输入模式读取的是 psr 的值。技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 7 - 读取 output 的 value 值是从 PSR 中读取的。而写入 output 值是写入到 DR 中的。可以通过设置 SION 位回环。 4.3 GPIO 输入测试 编写测试脚本 vi gpiotest_i.sh #!/bin/bash # gpio list gpio (bank-1)*32 + nr for test in 118 119 120 137 136 12 do echo Exporting pin $test. echo $test> /sys/class/gpio/export echo in > /sys/class/gpio/gpio$test/direction gpioval=`cat /sys/class/gpio/gpio$test/value` echo GPIO $test = $gpioval echo echo $test> /sys/class/gpio/unexport done echo complete 修改脚本执行权限:chmod u+x gpiotest_i.sh 测试 gpio 输入为低。进入到脚本所在路径:./gpiotest_i.sh 所有 GPIO 输入为 0。 测试 gpio 输入为高电平,比如 5v。进入到脚本所在路径:./gpiotest_i.sh 所有 GPIO 输入为 1。 \iomuxc\shell\di\in-test.sh,复制到 forlinx(比如)目录下./in-test.sh 118 \iomuxc\shell\do\close.sh,复制到 forlinx(比如)目录下./close.sh 118 \iomuxc\shell\do\open.sh,复制到 forlinx(比如)目录下./open.sh 118 或者采用\iomuxc\write-117-out-high\test,复制到 forlinx(比如)目录下./test 将 gpio 117 输出为高。 引脚复用参数的说明 技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 8 - arch/arm/boot/dts/imx6ul-pinfunc.h 与 arch/arm/boot/dts/imx6ull-pinfunc.h 定义了各个引脚和复用功 能的宏定义 以 GPIO1_IO08 引脚为例进行说明 GPIO1_IO08 为引脚的名称,PWM1_OUT 为此引脚复用成的功能 在设备树 arch/arm/boot/dts/imx6ull-14x14-evk.dts 中有设置 将其展开为:0x007C 0x0308 0x0000 0x0 0x0 0x110b0 0x007C | 0x0308 | 0x0000 | 0x0 | 0x0 | 0x110b0 ---------------------------------------------------------------------------------------------------------------------------- mux_ctrl_ofs | pad_ctrl_ofs | sel_input_ofs | mux_mode | sel_input | pad_ctrl 注:下述参考手册为《IMX6ULLRM.pdf》找到 32 章节 IOMUX Controller 从下图可以看到此引脚复用寄存器的偏移地址就是 7C,想把此引脚复用成 pwm1,需要选择 ALT0 所以 mux_ctrl_ofs 为 0x007C,mux_mode 为 0x0 pad_ctrl_ofs 为电气属性寄存器的偏移地址 0x0308,并根据 pad_ctrl 的值(0x110b0)来设置此寄 存器。此寄存器主要时配置一些内部上下拉电阻,转换速率,引脚驱动强度等电气属性。技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 9 - GPIO1_IO08 GPIO1_IO09 使用注意事项 GPIO1_IO08 在 u-boot 阶段使能 lcd 背光/屏蔽 lcd 背光函数中有相应的电平设置,在 kernel 阶段再 次使用该 GPIO 复用为 ADC 时需要注意。 GPIO1_IO09 在 u-boot 阶段的 mmc 初始化函数中有相应的电平设置,在 kernel 阶段再使用该 GPI 复用 为 ADC 时需要注意。 去掉 SN74HC595 有客户反馈说不使用 SN74HC595 芯片,uboot 与内核中均有设置,对应的 CPU 侧的这个几个引脚, 如果悬空,不影响使用。如果用作输入,可能会影响启动。技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 10 - 另外这个 SPI 转 GPIO 对应出来的 GPIO 控制一些使能引脚,去掉此模块的话,其他的功能也需要修 改。 比如采用 CSI_DATA0-ENET1_NRST GPIO4_IO21 CSI_DATA1-ENET2_NRST GPIO4_IO22 CSI_DATA2-CAN_STBY GPIO4_IO23 CSI_DATA3-WIFI_EN GPIO4_IO24 CSI_DATA4-CSI_RST GPIO4_IO25 CSI_DATA5-CSI_PWDN GPIO4_IO26 CSI_DATA6-LCD_NPWREN GPIO4_IO27 查看设备树 arch/arm/boot/dts/imx6ull-14x14-evk.dts 1、避免引脚复用冲突,先把 csi 功能 disabled 2、将 74hc595 的功能 disabled spi4 { compatible = "spi-gpio"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi4>; pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; status = "okay"; gpio-sck = <&gpio5 11 0>; gpio-mosi = <&gpio5 10 0>; cs-gpios = <&gpio5 7 0>; num-chipselects = <1>; #address-cells = <1>; #size-cells = <0>; gpio_spi: gpio_spi@0 { compatible = "fairchild,74hc595";技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 11 - gpio-controller; #gpio-cells = <2>; reg = <0>; registers-number = <1>; registers-default = /bits/ 8 <0xa7>; spi-max-frequency = <100000>; }; }; 将 status 修改为 disabled 搜索 gpio_spi,有 CAN_STBY 设置: reg_can_3v3: regulator@0 { compatible = "regulator-fixed"; reg = <0>; regulator-name = "can-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>; startup-active-us = <20000>; enable-active-high; }; 修改为 gpio = <&gpio4 23 GPIO_ACTIVE_LOW>; 在 pinctrl_hog_1 下添加引脚复用: pinctrl_hog_1: hoggrp-1 { fsl,pins = < ... MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x17059 ... >; }; CSI_RST/CSI_PWDNSHE 设置 ov9650: ov9650@30 { compatible = "ovti,ov9650"; reg = <0x30>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_csi1>; clocks = <&clks IMX6UL_CLK_CSI>; clock-names = "csi_mclk"; pwn-gpios = <&gpio_spi 6 1>; rst-gpios = <&gpio_spi 5 0>; csi_id = <0>; mclk = <24000000>; mclk_source = <0>;技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 12 - status = "okay"; port { ov9650_ep: endpoint { remote-endpoint = <&csi1_ep>; }; }; }; 修改为 pwn-gpios = <&gpio4 26 1>; rst-gpios = <&gpio4 25 0>; 在 pinctrl_hog_1 下添加引脚复用: pinctrl_hog_1: hoggrp-1 { fsl,pins = < ... MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x17059 MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x17059 ... >; }; WIFI_EN 设置 在 pinctrl_hog_1 中加入 MX6UL_PAD_CSI_DATA03__GPIO4_IO24 &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog_1>; imx6ul-evk { pinctrl_hog_1: hoggrp-1 { sl,pins = < MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */ MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x130b1 MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x1b0b1 >; }; 并在文件系统开机自启动脚本/etc/rc.local 中加入 echo 120 >/sys/class/gpio/export echo out >/sys/class/gpio/gpio120/direction echo 0 >/sys/class/gpio/gpio120/value ENET1_NRST/ENET2_NRST 设置 在设备树下修改 &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet1>; phy-mode = "rmii";技术参考手册_应用笔记 OKMX6ULL-S www.forlinx.com - 13 - phy-handle = <ðphy0>; status = "okay"; }; &fec2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2>; phy-mode = "rmii"; phy-handle = <ðphy1>; status = "okay"; …… 为 &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet1>; phy-mode = "rmii"; phy-handle = <ðphy0>; phy-reset-duration = <100>; phy-reset-gpios = <&gpio4 21 0>; status = "okay"; }; &fec2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2>; phy-mode = "rmii"; phy-handle = <ðphy1>; phy-reset-duration = <100>; phy-reset-gpios = <&gpio4 22 0>; status = "okay"; …… 在 pinctrl_hog_1 下添加引脚复用: pinctrl_hog_1: hoggrp-1 { fsl,pins = < ... MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x17059 MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x17059 ... >; }; LCD_NPWREN 如果硬件默认设置死的话,软件不用修改。如果软件修改的话,uboot 阶段设置 GPIO 控制。在内核 arch/arm/mach-imx/mach-imx6ul.c 的 imx6ul_init_machine 中添加 GPIO 控制高低电平。或者 在设备树中加入对应的 gpio,方法参考“创建 dev/gpio 节点”部分。
|