打印
[嵌入式Linux]

RK3326 RK3399 GPIO寄存器操作指南

[复制链接]
1314|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 qq7643066 于 2020-8-3 15:58 编辑

RK3326 RK3399 GPIO寄存器操作指南
参考资料
http://www.sunychip.com/list-35.html
Rockchip+RK3399TRM+V1.1+Part2+20160728.pdf
Rockchip GPIO常见问题.pdf
基本环境
RK3326 小板
8pin引出接口中的GPIO0_B3(实际为GPIO1_C2)
RK3326 EVB开发板
RK3399 EVB开发板
Linux与Android系统都适用
FAE给的操作步骤
  • IOMUX复用为GPIO
  • GPIO设置为输出
  • 设置GPIO高低
  • 补充,事实上还漏了一个重要一部,要先设置时钟,否则前面的设置都不生效
RK3326寄存器手册查询
参考寄存器手册Address Maping部分
GRF基地址为0xFF140000
GPIO1基地址为0xFF250000
DDR(方向寄存器)偏移地址0x04, 所以寄存器地址为0xFF250004
DR(设置高低电平)偏移地址为0x00, 所以寄存器地址为0xFF250000
GRF_GPIO1C_IOMUX_L 偏移地址为0x10, 所以IOMUX地址为0xFF140010
GPIO1_C2对应的位为bit19
RK3326 GPIO1_C2 设置实验
读取GPIO1_C2的值(DR)
io -4 -l 4 0xFF250000
输出
ff250000: 00000000
bit19 为0, 测得电压为0.26V
写入bit19 为 1
io -4 -w 0xff250000 0x00040000
回读正常,测得电压为3V
方向寄存器
io -4 -l 4 0xFF2500004
输出
ff250004: 00040000
IOMUX寄存器
io -4 -l 4 0xFF140010
输出
ff140010: 00000011
根据寄存器手册P104可知, bit11:8为0, gpio1_c2为gpio功能
RK3326 WAKE_UP设置实验(对应GPIO1_C3, 对应bit20)
有前面可知,IOMUX已经设置为GPIO
设置方向寄存器(DR)为输出
io -4 -w 0xff250004 0x000C0000
设置为高电平
io -4 -w 0xff250000 0x000C0000
回读
io -4 -l 4 0xFF250000
返回:
ff250000: 000c0000
万用表测得为3V, 同理,设置为低电平,万用表测得为0.027V,实验成功!
RK3326 MAV022 GPIO驱动分析
内核文件节点
/sys/class/leds/call_answer_led/brightness
echo 255 > /sys/class/leds/call_answer_led/brightness (高电平)
echo 0 > /sys/class/leds/call_answer_led/brightness(低电平)
原先的驱动设计是具有pwm功能的,这里我借用了这个接口,没有pwm功能,只有高低电平
DTS中的位置
rk3326-mav022-v10.dts
关键字
搜索RK_PC2或者gpio-leds
驱动不用修改,只需要修改DTS中两处即可,移植到开发板GPIO3_C2也可行
RK3326 EVB GPIO寄存器控制
选定开发板D12-GPIO3-C0作为控制脚,对应的bit = (C-A)*8 + 0 = 16
对应位设为1, 0x00010000, 设为0, 0x00000000
设置DDR方向寄存器
io -4 -w 0xFF270004 0x00050000
设置输出为低电平
io -4 -w 0xFF270000 0x00000000
LED灯亮
设置输出为高电平
io -4 -w 0xFF270000 0x00010000
LED灯灭
这一步一开始实验一直控制无效,后来参考文档《Rockchip GPIO常见问题.pdf》,发现是CLK没有设置造成的,前面的实验之所以成功,应该是在DTS里配置了相应的管脚,CLK在驱动里已经打开,而DTS没有配置的管脚,CLK默认是关闭的
查询clk
cat /sys/kernel/debug/clk/clk_summary |grep gpio
GPIO3果然为0
使能GPIO3 ClK
echo 1 > /sys/kernel/debug/clk/pclk_gpio3/clk_enable_count
RK3399 EVB GPIO2_B2, GPIO2_B3测试
首先根据RK3326经验查询CLK
cat /sys/kernel/debug/clk/clk_summary |grep gpio
gpio2为0, 写入1
echo 1 > /sys/kernel/debug/clk/pclk_gpio2/clk_enable_count
GPIO2_B2 bit位为(B-A)8 + 2 = 10
GPIO3_B3 bit位为(B-A)
8 + 3 = 11
测试DDR寄存器
io -4 -r 0xff780004
返回
807f1
读取DR寄存器
io -4 -r 0xff780004
返回
0x3f0
开始GPIO控制
测试GPIO2_B2
写入GPIO2_B2位低电平
io -4 -w 0xff780000 0x7f0
红灯亮,设置生效
测试GPIO2_B3
写入GPIO2_B3为输出
io -4 -w 0xff780004 0x80ff1
GPIO2_B3输出为低
io -4 -w 0xff780000 0xff0
发现不生效,查询IOMUX寄存器
io -4 -r 0xff77e004
返回
0x00c0
查询寄存器文档可知bit7:6为11, gpio2_b3没有设为gpio
设置iomux为gpio
io -4 -w 0xff7e004 0x0000
设置无效,可能是被驱动限制了
测试GPIO2_B1
bit位为(B-A)*8 + 1 = 9
由前面可知,DDR应该已经是输出
直接设置DR
io -4 -w 0xff780000 0x5f0
设置成功,黄灯亮!
另外一种用GPIO Debug接口控制的方法
原作者是在Android6.0下实验的,经测试Android8.1下一样可以使用
以GPIO2_B2为例
  • 查看GPIO2_B2的gpio number
1. rk3399:/sys/kernel/debug # cat gpio                                          GPIOs 0-31, platform/pinctrl, gpio0:    gpio-1   (                    |vcc_sd              ) out lo        GPIOs 0-31, platform/pinctrl, gpio0:
    gpio-1   (                    |vcc_sd              ) out lo   
    gpio-4   (                    |bt_default_wake_host) in  lo   
    gpio-5   (                    |power               ) in  hi   
    gpio-9   (                    |bt_default_reset    ) out lo   
    gpio-10  (                    |reset               ) out hi   

GPIOs 32-63, platform/pinctrl, gpio1:
gpio-34  (                    |int-n               ) in  hi   
gpio-35  (                    |camsys_gpio         ) out hi   
gpio-45  (                    |enable              ) out hi   
gpio-46  (                    |vsel                ) out lo   
gpio-49  (                    |vsel                ) out lo   
gpio-54  (                    |mpu6500             ) in  lo   

GPIOs 64-95, platform/pinctrl, gpio2:
gpio-64  (                    |vbus-5v             ) out lo   
gpio-69  (                    |power33             ) out hi   
gpio-70  (                    |power               ) out hi   
gpio-71  (                    |reset               ) out hi   
gpio-72  (                    |stanby              ) out hi   
gpio-73  (                    |power18             ) out hi   
gpio-74  (                    |sysfs               ) out lo   
gpio-76  (                    |int                 ) in  hi   
gpio-83  (                    |bt_default_rts      ) in  hi   
gpio-90  (                    |bt_default_wake     ) in  lo

可知GPIO2_B2的number 为GPIO74
  • 导出为GPIO
  • rk3399:/sys/class/gpio # echo 74 >export
  • 1|rk3399:/sys/class/gpio # ls
    export gpiochip0   gpiochip32 gpiochip96
    gpio74 gpiochip128 gpiochip64 unexport   
    rk3399:/sys/class/gpio #


  • 设置输出高低电平
  • rk3399:/sys/class/gpio/gpio74 # lsactive_low device direction edge power subsystem uevent value rk3399:/sys/class/gpio/gpio74 # echo 1 > value                            rk3399:/sys/class/gpio/gpio74 # echo 0 > value                            rk3399:/sys/class/gpio/gpio74 #

但同样的方法GPIO73不能导出,看来这种方法还是有些局限
这个开发板可以了解


使用特权

评论回复

相关帖子

沙发
1348795481| | 2020-8-3 16:06 | 只看该作者
看起来不错,有没有写驱动控制gpio的案例

使用特权

评论回复
板凳
dufanghua| | 2020-8-3 16:54 | 只看该作者
多谢分享 不过我还没搞成功

使用特权

评论回复
地板
qq7643066|  楼主 | 2020-10-8 12:10 | 只看该作者
gpio控制有多种方式实现

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:承接MID、Android TV等项目定制 QQ:7643066

107

主题

422

帖子

5

粉丝