参考这篇文章所写
也可参考这篇文章
在这份文档中查找复用关系
找到电路图
以上面的UART4_TXD(KEY_COL0为例)
在芯片手册第四章找到KEY_COL0
找到相关寄存器
这里我们找到了三个名字
SW_PAD_CTL_PAD_KEY_COL0(Pad的控制寄存器名称)
IOMUXC_SW_MUX_CTL_PAD_KEY_COL0(Mux的控制寄存器名称)
IOMUXC_UART4_UART_RX_DATA_SELECT_INPUT(Select Input的寄存器名称)
其实SW_PAD_CTL_PAD_KEY_COL0是有一个前缀的,全称是IOMUXC_SW_PAD_CTL_PAD_KEY_COL0
查找该名称可以找到相关寄存器的地址
上面的地址是什么意思呢,请看下图
这里我们知道了,这组寄存器的地址起始值为20E_0000,所以我们的IOMUXC_SW_PAD_CTL_PAD_KEY_COL0相对偏移地址是05c8
继续查找,下图就是该寄存器每个位的功能,同时这里也提到了基址和相对地址。
上面这个寄存器主要功能就是控制引脚的电气属性
再查找第二个寄存器
上面这个寄存器的主要功能就是选择引脚的复用功能
再查找第三个寄存器
上图寄存器的功能就是选择到底是通过哪个引脚输入进来的信号
linux内核源码里
参数的意义
_pad_ctrl_ofs pad控制寄存器的偏移地址
_mux_ctrl_ofs mux控制寄存器的偏移地址
_mux_mode mux的模式
_sel_input_ofs input寄存器的偏移地址
_sel_input input的类型
通过上面三个寄存器说明即可使用iomux函数去配置自己的引脚了
相关源码位置是在arch/arm/boot/dts/imx6dl-pinfunc.h中
/*
- The pin function ID is a tuple of
-
<mux_reg conf_reg input_reg mux_mode input_val>
*/
以上规则为:
mux_reg:mux控制寄存器偏移地址
conf_reg:pad控制寄存器偏移地址
input_reg:select_input控制寄存器偏移地址
mux_mode:mux模式
input_val:select_input寄存器值
添加串口2和4
其中MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0X1b0b1代表pad_ctrl寄存器的值
0x170 0x540 0x000 0x4 0x1 0x1b0b1
mux_ctrl_ofs | pad_ctrl_ofs | sel_input_ofs | mux_mode | sel_input | pad_ctrl
修改完后编译设备树
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
export ARCH=arm
export CROSS_COMPILE=arm-poky-linux-gnueabi-
make imx6q-krt.dtb
sudo dd if=arch/arm/boot/dts/imx6q-krt.dtb of=/dev/sdb bs=512 seek=20480 conv=fsync
linux下查看串口4配置,默认波特率9600
stty -F /dev/ttymxc3 -a
linux下修改串口4配置为115200
stty -F /dev/ttymxc3 ispeed 115200 ospeed 115200 cs8
有客户反馈读GPIO始终为0
其原因是因为当复用为GPIO后,我们第一反应是给direction赋值为out,也就是说GPIO变为输出模式了。而系统读取的value是从PSR中读取的。而写入output值是写入到DR中的。所以就根本不是读取的输出值,一直为0也就正常了。看下图中的NOTE描述,正常的read操作是读取GPIO_PSR的值。
我们可以可以通过设置SION位让GPIO的输出输入进入回环(下图第一点说明),既SION的意义数既做输入又做输出,注意:此模式下GPIO复用功能是会被忽略的。
至于如何修改SION,去arch/arm/boot/dts/imx6ul-pinfunc.h中找到相关GPIO宏定义(注意,此时我使用的是IMX6ULL官方EVK),然后把mux_ctl寄存器的bit5改为1就行,其他随意(因为SION=1时会忽略复用模式的配置信息),这里就改成0X01即可,不过在这里修改是个偷懒的方法,并不漂亮,容易以后给自己留坑(忘记修改过这个宏定义,导致复用功能失效),建议计算出来值,在宏定义的引用处再进行置位操作。