1 参考
https://wiki.t-firefly.com/zh_CN/Firefly-RK3399/driver_gpio.html
Rockchip GPIO 常见问题.pdf
Rockchip_RK3399TRM_V1.4_Part1-20170408.pdf
2 基本说明
本文内容来源于调试广州眺望电子科技有限公司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_B7 | 8 |
GPIO3_C0 | GPIO3_C1 | 2 |
GPIO3_D0 | GPIO3_D7 | 8 |
GPIO4_A0 | GPIO4_A7 | 8 |
GPIO4_B0 | GPIO4_B5 | 6 |
GPIO4_C0 | GPIO4_C7 | 8 |
GPIO4_D0 | GPIO4_D6 | 7 |
RK3399 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0~A7, B0~B7, C0~C7, D0~D7 作为编号区分(不是所有 bank 都有全部编号,例如 GPIO4 就只有 C0~C7, D0~D2)。所有的 GPIO 在上电后的初始状态都是输入模式,可以通过软件设为上拉或下拉,也可以设置为中断脚,驱动强度都是可编程的。
控制之前首先确保相关时钟已经使能,比如:
cat sys/kernel/debug/clk/clk_summary |grep gpio,查看时钟使能状态
echo 1 > sys/kernel/debug/clk/pclk_gpio3/clk_enable_count,使能gpio3的时钟
注意:
要想看到/sys/kernel/debug,需要配置内核及挂载debugfs,
内核配置文件.config中CONFIG_DEBUG_FS=y,
挂载debugfs,mount -t debugfs none sys/kernel/debug
3 操作
3.1 sys/class/gpio方式
使用/sys/class/gpio方式控制GPIO时,指定gpio的值的计算方式如下:
GPIO bank | 基值 | GPIO 组 | 基值 |
GPIO0 | 0 | A | 0 |
GPIO1 | 32 | B | 8 |
GPIO2 | 64 | C | 16 |
GPIO3 | 96 | D | 24 |
GPIO4 | 128 |
所以,GPIO2_D3:64+24+3=91;GPIO1_A3:30+0+3=35。
示例:
蓝牙状态指示灯,GPIO2_D3:64+24+3=91。
向/sys/class/gpio/export导出指定的管脚:
echo /sys/class/gpio/91 > export
设置gpio为输出方向:
echo out > /sys/class/gpio/gpio91/direction,out表示输出,in表示输入
输出高电平:
echo 1 > /sys/class/gpio/gpio91/value,1表示高电平,0表示低电平
3.2 直接操作寄存器控制GPIO
当设备树有控制GPIO时,使用/sys/class/gpio/的方式会出现冲突。如下:
[root@rk3399:/sys/class/gpio]# echo 149 > export
[ 6924.833544] gpio-149 (gpio_num): gpiod_request: status -16
[ 6924.839131] export_store: status -16
sh: write error: Device or resource busy
可以更改设备树配置或者直接操作寄存器解决。
执行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的方向,
所以只要设置方向寄存器和设置数据寄存器即可,
[root@rk3399:/home/nfs]# io -4 -l 8 0xff790000
ff790000: 62600000 6f600000
可以看出GPIO4_C5为输出高电平状态,
通过执行io -4 -w 0xff790000 0x62400000,可以控制GPIO4_C5为输出低电平状态,此时执行cat /sys/kernel/debug/gpio可以看到变化。