NanoPi R6S GPIO 使用
GPIO,全称 General-Purpose Input/Output(通用输入输出),是一种软件运行期间能够动态配置和控制的通用引脚。
在 NanoPi R6S 的主控芯片 RK3588S 中,一共有 5 组 GPIO bank,即 GPIO0 ~ GPIO4,每组又以 A0~A7、B0~B7、C0~C7、D0~D7 作为编号区分。所有的 GPIO 在上电后的初始状态都是输入模式,可以通过软件设为上拉或下拉,也可以设置为中断脚,驱动强度都是可编程的。
每个 GPIO 引脚除了用作通用输入/输出功能外,还可能有其他复用功能,例如 GPIO1_B3,可以作为 SPI0 的时钟引脚以及 UART4 的发送引脚。
GPIO 驱动
RK3588 的 GPIO 驱动是在以下 pinctrl 文件中实现的:
kernel/drivers/pinctrl/pinctrl-rockchip.c
其核心是填充 GPIO bank 的方法和参数,并调用 gpiochip_add
注册到内核中。
GPIO 编号计算
RK3588S 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0~A7、B0~B7、C0~C7、D0~D7 作为编号区分,可通过以下公式计算引脚编号。
GPIO pin脚计算公式:pin = bank * 32 + number
GPIO 小组编号计算公式:number = group * 8 + X
下面演示 GPIO1_B3 pin 脚计算方法:
bank = 1; //GPIO1_B3 => 1, bank ∈ [0,4]
group = 1; //GPIO1_B3 => 1, group ∈ {(A=0), (B=1), (C=2), (D=3)}
X = 0; //GPIO1_B3 => 3, X ∈ [0,7]
number = group * 8 + X = 1 * 8 + 3 = 11
pin = bank * 32 + number = 1 * 32 + 11 = 43;
GPIO 扩展引脚
NanoPi R6S 主板上提供了一个 12-pin 0.5mm FPC 连接器,除电源和地以外一共有 8 个 GPIO,还可扩展出最多 1 路 SPI、3 路 UART、1 路 I2C、2 路 SPDIF,具体引脚定义及其对应的 sysfs 编号如下表所示。
Pin | GPIO | /sys/class/gpio | 说明 |
---|---|---|---|
1 | VCC3V3_SYS_S3 | 3.3V 电源输出 | |
2 | VCC3V3_SYS_S3 | 3.3V 电源输出 | |
3 | GPIO1_B3 | 32*1+8+3 = 43 | 3.3V |
4 | GND | 地 | |
5 | GPIO1_B1 | 32*1+8+3 = 41 | 3.3V |
6 | GPIO1_B4 | 32*1+8+3 = 44 | 3.3V |
7 | GPIO1_B2 | 32*1+8+3 = 42 | 3.3V |
8 | GND | 地 | |
9 | GPIO1_B7 | 32*1+8+3 = 47 | 3.3V |
10 | GPIO1_B6 | 32*1+8+3 = 46 | 3.3V |
11 | GPIO3_C4 | 32*3+16+4 = 116 | 3.3V |
12 | GPIO3_C5 | 32*3+16+4 = 117 | 3.3V |
设备树
GPIO1_B3 对应的 设备树属性描述为:<&gpio1 11 GPIO_ACTIVE_HIGH>
,由 kernel/include/dt-bindings/pinctrl/rockchip.h
的宏定义可知,也可以将 GPIO1_B3 描述为 <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>
。
#define RK_PA0 0
#define RK_PA1 1
#define RK_PA2 2
#define RK_PA3 3
#define RK_PA4 4
#define RK_PA5 5
#define RK_PA6 6
#define RK_PA7 7
#define RK_PB0 8
#define RK_PB1 9
#define RK_PB2 10
#define RK_PB3 11
...
当 GPIO1_B3 脚没有被其它外设复用时, 我们可以通过 export 导出该引脚去使用
$ cd /sys/class/gpio/
$ ls
export gpiochip128 gpiochip32 gpiochip64 unexport
gpiochip0 gpiochip200 gpiochip509 gpiochip96
# 导出 gpio56
$ sudo echo 56 > /sys/class/gpio/export
$ ls /sys/class/gpio/
export gpiochip0 gpiochip200 gpiochip509 gpiochip96
gpio56 gpiochip128 gpiochip32 gpiochip64 unexport
# 查看 gpio56 的方向和电平状态
$ ls /sys/class/gpio/gpio56
active_low device direction edge power subsystem uevent value
$ sudo cat /sys/class/gpio/gpio56/direction
in
$ sudo cat /sys/class/gpio/gpio56/value
0