https://gitlab.com/TeeFirefly/rk3399-android10.0-bundle/-/commits/master
https://wiki.t-firefly.com/zh_CN/Firefly-RK3399/driver_gpio.html
Rockchip GPIO 常见问题.pdf
Rockchip_RK3399TRM_V1.4_Part1-20170408.pdf
本文内容来源于调试广州眺望电子科技有限公司 rk3399 开发板的过程中总结的经验。
从 Rockchip_RK3399_Datasheet_V2.1-20200323.pdf 入手
起始 | 结尾 | 个数 |
---|---|---|
GPIO0_A0 | GPIO0_A7 | 8 |
GPIO0_B0 | GPIO0_B5 | 6 |
GPIO1_A0 | GPIO1_A7 | 8 |
GPIO1_B0 | GPIO1_B7 | 8 |
GPIO1_C0 | GPIO1_C7 | 8 |
GPIO1_D0 | GPIO1_D0 | 1 |
GPIO2_A0 | GPIO2_A7 | 8 |
GPIO2_B0 | GPIO2_B4 | 5 |
GPIO2_C0 | GPIO2_C7 | 8 |
GPIO2_D0 | GPIO2_D4 | 5 |
GPIO3_A0 | GPIO3_A7 | 8 |
GPIO3_B0 | GPIO3_B4 | 5 |
GPIO3_C0 | GPIO3_C7 | 8 |
GPIO3_D0 | GPIO3_D4 | 5 |
GPIO4_A0 | GPIO4_A7 | 8 |
GPIO4_B0 | GPIO4_B5 | 6 |
GPIO4_C0 | GPIO4_C7 | 8 |
GPIO4_D0 | GPIO4_D6 | 7 |
RK3399 有 5 组 GPIO bank:GPIO0GPIO4,每组又以 A0A7, B0B7, C0C7, D0D7 作为编号区分(不是所有 bank 都有全部编号,例如 GPIO4 就只有 C0C7, D0~D2)。所有的 GPIO 在上电后的初始状态都是输入模式,可以通过软件设为上拉或下拉,也可以设置为中断脚,驱动强度都是可编程的。
控制之前首先确保相关时钟已经使能,比如:
1 | cat sys/kernel/debug/clk/clk_summary |grep gpio,查看时钟使能状态 |
注意:
要想看到/sys/kernel/debug,需要配置内核及挂载debugfs
内核配置文件.config 中 CONFIG_DEBUG_FS=y,
挂载 debugfs,mount -t debugfs none sys/kernel/debug
使用/sys/class/gpio 方式控制 GPIO 时,指定 gpio 的值的计算方式如下:
| GPIO bank | 基值 | GPIO group | 基值 |
| ——– | ——– | —- | —- |
| GPIO0 | 0 | A | 0 |
| GPIO1 | 32 | B | 8 |
| GPIO2 | 64 | C | 16 |
| GPIO3 | 96 | D | 24 |
| GPIO4 | 128 | E | 0 |
计算公式为:
管脚索引号 = bank * 16 + group * 8 + index
如GPIO2_B6:
2 * 32 + 1 * 8 + 6 = 78
示例:
蓝牙状态指示灯,GPIO2_D3:2 * 32 + 3 * 8 + 2 = 91
向/sys/class/gpio/export 导出指定的管脚:
1 | echo /sys/class/gpio/91 > export |
设置 gpio 为输出方向:
1 | echo out > /sys/class/gpio/gpio91/direction,out表示输出,in表示输入 |
输出高电平:
1 | echo 1 > /sys/class/gpio/gpio91/value,1表示高电平,0表示低电平 |
当设备树有控制 GPIO 时,使用/sys/class/gpio/的方式会出现冲突。如下:
1 | [root@rk3399:/sys/class/gpio]# echo 149 > export |
可以更改设备树配置或者直接操作寄存器解决。
执行 cat /sys/kernel/debug/gpio 查看当前管脚状态,
gpio-149 对应管脚 GPIO4_C5,
1:设置管脚复用寄存器,2:设置方向寄存器,3:设置数据寄存器
查看手册,管脚复用寄存器(GRF_GPIO4C_IOMUX:0xff77e028,GRF 的映射基址为 0xff770000)当前的值设置了 GPIO4_C5 为 GPIO 工作模式,GPIO4 映射基址为 0xff790000,
0xff790000 保存了当前 32 个 GPIO 的电平值,0xff790004 保存了当前 32 个 GPIO 的方向,
所以只要设置方向寄存器和设置数据寄存器即可,
1 | [root@rk3399:/home/nfs]# io -4 -l 8 0xff790000 |
可以看出 GPIO4_C5 为输出高电平状态,
通过执行 io -4 -w 0xff790000 0x62400000,可以控制 GPIO4_C5 为输出低电平状态,此时执行 cat /sys/kernel/debug/gpio 可以看到变化。
其中 rk3399 P2 引出的 GPIO0_A6 原理图与实物,如下:
首先需要计算对应的 gpio number 的值,可以通过/sys/kernel/debug/gpio 查询信息:
1 | rk3399_firefly_aioc_ai:/ $ cat /sys/kernel/debug/gpio |
通过上面的返回结果可以看到,GPIO1 是以 nubmer 为 32 开始, 那么 GPIO1*A0 就是 1 * 32 + 0 _ 8 + 0 = 32。
然后查看/sys/class/gpio 目录下存在的 gpio,这时候并没有 gpioxxxx_32,需要我们导出一个。
1 | rk3399_firefly_aioc_ai:/ $ ls /sys/class/gpio |
1 | rk3399_firefly_aioc_ai:/sys/class/gpio $ su |
此时就会发现多了一个 gpio32 的文件夹, 这个文件对应着 GPIO1_A0 引脚对应的功能。
注意:由于 rk3399 kernel 自带了通用 GPIO 驱动,所以这里可以直接 export 对应的引脚。
进入到 gpio32 文件夹,然后 echo out > direction,如下:
1 | rk3399_firefly_aioc_ai:/sys/class/gpio # cd gpio32/ |
1 | # 使能 |
使能 gpio32 引脚,用万用表测量下对应的针脚是否为 1.8V(FET3399-C 核心板引出的 GPIO,除了 RGMII 和 MDC,MDIO 是 3.3V 的,其余 GPIO 全部是 1.8V 电平)。
https://github.com/huangzhenzeng/android-unpackbootimg
只需要在 linux(需安装 gcc,make,一般是标配)或 windows(需要安装 mingw)的命令行执行 make,即可产生可执行文件 mkbootimg、unpackbootimg
一般编译镜像后,将产生这个工具,目录为:u-boot/tools/resource_tool/resource_tool
一般编译镜像后,将产生这个工具,目录为:kernel/scripts/dtc/dtc
需到如下地址https://www.t-firefly.com/doc/download/54.html
下载《RKDevTool》
window 下,打开“RKDevTool”,选中“高级”,然后导入固件,选择解压即可,如下图:
最终 output 目录,输出各个子分区,如下图:
1 | 因为boot.img的格式比较简单,它主要分为三大块(有的可能有四块) |
linux 下输入命令:mkdir output
unpackbootimg -I boot.img -O ./output
生成文件如下:
1 | ├── boot.img-base (mkbootimg base参数) |
执行命令:mkdir out
./resource_tool --verbose --unpack --image=boot.img-second
生成文件如下:
1 | ├── logo.bmp |
执行命令:./dtc -I dtb -O dts out/rk-kernel.dtb -o tmp.dts
生成 tmp.dts 文件,
最终通过 gedit 或文本编辑查看