目录
一、RK GPIO计算方法
- 1.1 GPIO2_A6计算它的num值
二、在烧录的Loader模式拉高GPIO
- 2.1 如何找到GPIOA2_A6的寄存器
- 2.2 设置GPIO上面的映射的地址
- 2.3 设置GPIO上面的映射的地址代码
- 2.4 Loader模式串口log
一、RK GPIO计算方法
1.1 GPIO2_A6计算它的num值
K3399 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0~A7, B0~B7, C0~C7, D0~D7 作为编号区分
A : 0 B: 1 C: 2 D: 3
GPIO2_A6 计算方式为:2*32 + 0*8 + 6 = 70
GPIO4_A7计算方式为: 4*32 + 0*8 + = 135
GPIO 在 Debugfs 文件系统中的使用情况:
看到是从1000开始所以在此基数上+1000即可
# cat /sys/kernel/debug/gpioGPIOs 1000-1031, platform/pinctrl, gpio0:
gpio-1001 ( |vcc_sdmmc ) out hi
gpio-1005 ( |power ) in hi
gpio-1006 ( |ap_wake_module_gpio ) out lo
gpio-1008 ( |module_state_gpio ) in hi
gpio-1011 ( |spk-ctl ) out lo
GPIOs 1032-1063, platform/pinctrl, gpio1:
gpio-1032 ( |destroy_gpio ) in hi
gpio-1045 ( |goodix_pwr ) out hi
gpio-1046 ( |vsel ) out hi
gpio-1049 ( |vsel ) out lo
gpio-1052 ( |goodix_reset ) out lo
gpio-1055 ( |vcc5v0_host ) out hi
gpio-1056 ( |GPIO Key Home ) in hi
GPIOs 1064-1095, platform/pinctrl, gpio2:
gpio-1064 ( |module_wake_ap_gpio ) in hi
gpio-1065 ( |ap_state_gpio ) out hi
gpio-1066 ( |reset_modem_gpio ) out lo
gpio-1067 ( |reset_module_gpio ) out hi
gpio-1070 ( |module_pwr_sw_gpio ) out hi
gpio-1071 ( |camsys_gpio ) out lo
gpio-1073 ( |camsys_gpio ) out hi
gpio-1074 ( |camsys_gpio ) out lo
gpio-1076 ( |camsys_gpio ) out lo
gpio-1091 ( |avdden ) out lo
gpio-1092 ( |aveeen ) out lo
GPIOs 1096-1127, platform/pinctrl, gpio3:
gpio-1109 ( |wacom_irq ) in hi
gpio-1111 ( |mdio-reset ) out hi
gpio-1112 ( |wacom_rst ) in hi
gpio-1124 ( |sy7803b_flen ) out lo
gpio-1125 ( |sy7803b_fltri ) out lo
gpio-1126 ( |reset ) out lo
GPIOs 1128-1159, platform/pinctrl, gpio4:
gpio-1132 ( |vcc5v0_host1 ) out hi
gpio-1133 ( |headset_gpio ) in lo
gpio-1134 ( |chg_source_sw_gpio ) out lo
gpio-1135 ( |pwr_module_gpio ) out hi
gpio-1149 ( |GTP_RST_PORT ) out hi
gpio-1150 ( |GTP_INT_IRQ ) out lo
gpio-1154 ( |vibrator ) out lo
gpio-1156 ( |goodix_irq ) in lo
gpio-1158 ( |chg_source_sw_gpio ) out hi
二、在烧录的Loader模式拉高GPIO
问题:
使用GPIO的设置函数不生效
int gpio_direction_output(unsigned gpio);
int gpio_get_value(unsigned gpio);
解决方法:直接写GPIO的寄存器来控制
目标:
1.查看并设置GPIO2_A6的IOMUX和Pull Up/Pull Down状态,并设置其默认Pull Up。
2.查看并设置输入输出状态,并设置其输出高电平。
3.查看并设置GPIO的电源域 GPIO2_A6:1.8V
2.1 如何找到GPIOA2_A6的寄存器
查阅RK3399的数据手册找到寄存器地址
官方手册下载地址:
Rockchip open source Documenthttps://opensource.rock-chips.com/wiki_Main_Page
GRF_GPIO2A_IOMUX: GPIO2A iomux control
Address: Operational Base + offset (0x0e000)
GRF_GPIO2A_P : GPIO2A PU/PD control
Address: Operational Base + offset (0x0e040)
GPIO_SWPORTA_DDR
Address: Operational Base + offset (0x0004)
GRF_IO_VSEL : 电源域设置
Address: Operational Base + offset (0x0e640)
从 RK3399 Address Mapping 可以查到
GRF : 0xFF770000
GPIO2 : 0xFF780000
GPIO4 : 0xFF790000
2.2 设置GPIO上面的映射的地址
设置步骤:
- 设置复用类型位gpio
设置的地址为: 0xFF770000 + 0x0e000 = 0xFF77E000
- 设置gpio为output
设置的地址为:0xFF770000 + 0x0e040 = 0xFF77E040
- 设置gpio pull-up
设置的地址为:0xFF780000 + 0x00004 = 0xFF780004
- 设置电源域为1.8v
设置的地址为:0xFF770000 +0x0e640 = 0xFF77E640
由于在开机状态下两个GPIO是OK的可以用io工具导出寄存器值再去设置寄存器效率会高一些(偷个懒不然一个个算有点麻烦哈哈哈);
130|rk3399_syber:/ # io -4 -l 0x100 0xff77e040
ff77e040: 00004a11 00005515 0000ff03 000003f3
rk3399_syber:/ # io -4 -l 0x100 0xff77e000
ff77e000: 00000000 000000c0 00005555 00000005rk3399_syber:/ # io -4 -l 0x100 0xff780004
ff790004: 180016ce 00000000 00000000 00000000rk3399_syber:/ # io -4 -l 0x100 0xff77e640
ff77e640: 00000003 00000004 00000080 00000084
2.3 设置GPIO上面的映射的地址代码
代码块标题
u32 value = readl((void *)(0xFF77E000));
printf("YQ- GPIO2_Ax PU/PD Reset value:[0xFF77E000] 0x%08x\n",value); value = readl((void *)(0xFF77E040));
printf("YQ- GPIO2_Ax PU/PD Reset value:[0xFF77E040] 0x%08x\n",value);value = readl((void *)(0xFF780004));
printf("YQ- GPIO2_Ax PU/PD Reset value:[0xFF780004] 0x%08x\n",value);value = readl((void *)(0xFF77E640));
printf("YQ- GPIO2A Setting PMU value:[0xFF77E640] 0x%08x\n",value);
printf("########### YQ- Read end ########### \n");value = 0xffff4a11;
writel(value,(void *)(0xFF77E040));
udelay(500*1000);
value = readl((void *)(0xFF77E040));
printf("YQ- GPIO2_Ax PU/PD Setting value:[0xFF77E040] 0x%08x\n",value);value = 0x180016ce;
writel(value, (void *)(0xFF780004));
udelay(500*1000);
value = readl((void *)(0xFF780004));
printf("YQ- GPIO2_xx DDR Setting value:[0xFF780004] 0x%08x\n",value);value = 0xffff0003;
writel(value, (void *)(0xFF77E640));
udelay(500*1000);
value = readl((void *)(0xFF77E640));
printf("YQ- GPIO2A Setting value:[0xFF77E640] 0x%08x\n",value);