Many thanks to Indiedroid community member macromorgan
and others for their work on this.
GPIO can be controlled from Linux using sysfs
(/sys/class/gpio) or by installing libgpiod
for your operating system.
Check out How to control PWM fan for an example of GPIO control via the sysfs
method.
According to community member macromorgan
, I2S is not available on the GPIO header. For I2S to work, a serial clock/bitclock pin is required, and there aren't any on the GPIO header.
Every pin that can act as an SCLK - here's the result:
GPIO1 C3 - Used by onboard ES8388
GPIO4 A1 - Used by type-c controller (can't break out)
GPIO0 B6 - uart2 (could be stolen with a breakout, but the word select line is taken by the i2c regulator for the NPU)
GPIO3 B5 - Used by bluetooth
GPIO3 A1 - sdio
GPIO2 B7 - unmapped, possibly only available on rk3588 (not rk3588s)
Bottom line: No i2s possible as you can't break out a bitclock line (sclk) and a word clock line (lrclk). I2S is a no-go, and any accessories that use I2S will not work.
Discussion on the Indiedroid Nova Discord channel on this topic:
https://discordapp.com/channels/1072231504295493742/1073693147785338950/1128353618916016188
From community member macromorgan
: As for why some of the pins are 1.8v and some are 3.3v (and why that can't be changed), it looks like there is a common voltage rail on the board according to the schematic called vcc_1v8_s0. This voltage rail is hard wired into pins on the SoC that are only 1.8v tolerant (called vccio1). However, this rail is also hard wired into pins that can either be driven by 3.3v or 1.8v (vccio2, vccio4, and vccio5). If this rail was only driving pins that were tolerant of 3.3v we could just raise the voltage of the regulator and have all our pins at 3.3v. But... we can't without frying stuff because vccio1 can only take 1.8v.
A few of the pins that are powered by 1.8v have level shifters on them though that drive them up to 3.3v... pins 3, 5, 27 and 28 have level shifters that make them 3.3v when they otherwise would have been 1.8v.
From community member J-Sode
: I'd like to share an update with the community regarding the GPIO pinout documentation. I noticed the Wiki's GPIO table (https://wiki.indiedroid.us/Nova/gpio) and the Wiki's schematic PDF (https://wiki.indiedroid.us/schematics.pdf) were showing different pinouts for the 40-Pin header. Based on my testing, the accurate pinout appears to be in the schematic, so I have attached a screenshot of it. I wonder if there was a revision change which caused this discrepancy? Also, for anyone curious, I finally got a UART port working in the Ubuntu image. I enabled the "rk3588-uart0-m2" overlay and am now communicating with the UART0 port on Pins 8 & 10.
From community member macromorgan
: The initial table was populated with pinouts from a pre-production device. The table has been corrected with the pinouts from the retail model.
These are the pin outs for the 40Pin GPIO header
PIN | FUNC | PIN_VOLTAGE | ALT6 | ALT8 | ALT9 | ALTA | ALTB |
1 | 3.3v | 3.3v | |||||
2 | 5v | 5v | |||||
3 | GPIO1 RK_PD7 | 3.3v | I2C8_SDA_M2 | PWM15_IR_M3 | |||
4 | 5v | 5v | |||||
5 | GPIO1 RK_PD6 | 3.3v | I2C8_SCL_M2 | PWM14_M2 | |||
6 | GND | ||||||
7 | GPIO1 RK_PA6 | 1.8v | |||||
8 | GPIO4 RK_PA3 | 3.3v | UART0_TX_M2 | ||||
9 | GND | ||||||
10 | GPIO4 RK_PA4 | 3.3v | I2C3_SCL_M2 | UART0_RX_M2 | |||
11 | GPIO1 RK_PB4 | 1.8v | SPI0_CS0_M2 | UART7_RX_M2 | |||
12 | GPIO0 RK_PD0 | 1.8v | PWM7_IR_M0 | ||||
13 | GPIO1 RK_PB5 | 1.8v | SPI0_CS1_M2 | UART7_TX_M2 | |||
14 | GND | ||||||
15 | GPIO3 RK_PC4 | 1.8v | CAN2_RX_M0 | UART5_TX_M1 | |||
16 | GPIO3 RK_PB0 | 1.8v | PWM9_M0 | ||||
17 | 3.3v | 3.3v | |||||
18 | GPIO3 RK_PB1 | 1.8v | PWM2_M1 | ||||
19 | GPIO3 RK_PB7 | 1.8v | SPI1_MOSI_M1 | I2C3_SCL_M1 | |||
20 | GND | ||||||
21 | GPIO3 RK_PC0 | 1.8v | SPI1_MISO_M1 | I2C3_SDA_M1 | UART7_TX_M1 | ||
22 | GPIO3 RK_PC5 | 1.8v | CAN2_TX_M0 | UART5_RX_M1 | |||
23 | GPIO3 RK_PC1 | 1.8v | SPI1_CLK_M1 | UART7_RX_M1 | |||
24 | GPIO0 RK_PD3 | 1.8v | |||||
25 | GND | ||||||
26 | GPIO3 RK_PC3 | 1.8v | SPI1_CS1_M1 | I2C8_SDA_M4 | UART7_CTSN_M1 | PWM15_IR_M0 | |
27 | GPIO1 RK_PA0 | 3.3v | |||||
28 | GPIO1 RK_PC1 | 3.3v | |||||
29 | GPIO1 RK_PA4 | 1.8v | |||||
30 | GND | ||||||
31 | GPIO1 RK_PB1 | 1.8v | SPI0_MISO_M2 | ||||
32 | GPIO4 RK_PA6 | 3.3v | I2C5_SCL_M2 | ||||
33 | GPIO1 RK_PB2 | 1.8v | SPI0_MOSI_M2 | ||||
34 | GND | ||||||
35 | GPIO4 RK_PA7 | 3.3v | I2C5_SDA_M2 | ||||
36 | GPIO4 RK_PB5 | 3.3v | UART9_RX_M1 | PWM12_M1 | |||
37 | GPIO4 RK_PA2 | 3.3v | SPI0_CLK_M1 | ||||
38 | GPIO4 RK_PB4 | 3.3v | SPDIF0_TX_M1 | UART9_TX_M1 | PWM11_IR_M1 | ||
39 | GND | ||||||
40 | GPIO4 RK_PB3 | 3.3v | PWM15_IR_M1 |
PIN_NUM | BANK | PINS | FUNCTION |
0 | GPIO0 | RK_PA0 | |
1 | GPIO0 | RK_PA1 | |
2 | GPIO0 | RK_PA2 | PMIC |
3 | GPIO0 | RK_PA3 | PMIC |
4 | GPIO0 | RK_PA4 | SDMMC |
5 | GPIO0 | RK_PA5 | SPI2 |
6 | GPIO0 | RK_PA6 | SPI2 |
7 | GPIO0 | RK_PA7 | PMIC |
8 | GPIO0 | RK_PB0 | RTC_INT |
9 | GPIO0 | RK_PB1 | SPI2 |
10 | GPIO0 | RK_PB2 | |
11 | GPIO0 | RK_PB3 | SPI2 |
12 | GPIO0 | RK_PB4 | |
13 | GPIO0 | RK_PB5 | UART2 |
14 | GPIO0 | RK_PB6 | UART2 |
15 | GPIO0 | RK_PB7 | I2C2 |
16 | GPIO0 | RK_PC0 | I2C2 |
17 | GPIO0 | RK_PC1 | PMIC |
18 | GPIO0 | RK_PC2 | PMIC |
19 | GPIO0 | RK_PC3 | PMIC |
20 | GPIO0 | RK_PC4 | USBC_INT |
21 | GPIO0 | RK_PC5 | BT_WAKE_HOST |
22 | GPIO0 | RK_PC6 | BT_WAKE_DEV |
23 | GPIO0 | RK_PC7 | WIFI_ENABLE |
24 | GPIO0 | RK_PD0 | HEADER_12 |
25 | GPIO0 | RK_PD1 | I2C0 |
26 | GPIO0 | RK_PD2 | I2C0 |
27 | GPIO0 | RK_PD3 | HEADER_24 |
28 | GPIO0 | RK_PD4 | BT_RESET |
29 | GPIO0 | RK_PD5 | |
30 | GPIO0 | RK_PD6 | PMIC |
31 | GPIO0 | RK_PD7 | |
32 | GPIO1 | RK_PA0 | HEADER_27 |
33 | GPIO1 | RK_PA1 | |
34 | GPIO1 | RK_PA2 | |
35 | GPIO1 | RK_PA3 | |
36 | GPIO1 | RK_PA4 | HEADER_29 |
37 | GPIO1 | RK_PA5 | |
38 | GPIO1 | RK_PA6 | HEADER_7 |
39 | GPIO1 | RK_PA7 | |
40 | GPIO1 | RK_PB0 | |
41 | GPIO1 | RK_PB1 | HEADER_31 |
42 | GPIO1 | RK_PB2 | HEADER_33 |
43 | GPIO1 | RK_PB3 | |
44 | GPIO1 | RK_PB4 | HEADER_11 |
45 | GPIO1 | RK_PB5 | HEADER_13 |
46 | GPIO1 | RK_PB6 | |
47 | GPIO1 | RK_PB7 | |
48 | GPIO1 | RK_PC0 | |
49 | GPIO1 | RK_PC1 | HEADER_28 |
50 | GPIO1 | RK_PC2 | |
51 | GPIO1 | RK_PC3 | |
52 | GPIO1 | RK_PC4 | |
53 | GPIO1 | RK_PC5 | |
54 | GPIO1 | RK_PC6 | |
55 | GPIO1 | RK_PC7 | |
56 | GPIO1 | RK_PD0 | I2C7 |
57 | GPIO1 | RK_PD1 | I2C7 |
58 | GPIO1 | RK_PD2 | |
59 | GPIO1 | RK_PD3 | |
60 | GPIO1 | RK_PD4 | |
61 | GPIO1 | RK_PD5 | |
62 | GPIO1 | RK_PD6 | HEADER_5 |
63 | GPIO1 | RK_PD7 | HEADER_3 |
64 | GPIO2 | RK_PA0 | |
65 | GPIO2 | RK_PA1 | |
66 | GPIO2 | RK_PA2 | |
67 | GPIO2 | RK_PA3 | |
68 | GPIO2 | RK_PA4 | |
69 | GPIO2 | RK_PA5 | |
70 | GPIO2 | RK_PA6 | |
71 | GPIO2 | RK_PA7 | |
72 | GPIO2 | RK_PB0 | |
73 | GPIO2 | RK_PB1 | |
74 | GPIO2 | RK_PB2 | |
75 | GPIO2 | RK_PB3 | |
76 | GPIO2 | RK_PB4 | |
77 | GPIO2 | RK_PB5 | |
78 | GPIO2 | RK_PB6 | |
79 | GPIO2 | RK_PB7 | |
80 | GPIO2 | RK_PC0 | |
81 | GPIO2 | RK_PC1 | |
82 | GPIO2 | RK_PC2 | |
83 | GPIO2 | RK_PC3 | |
84 | GPIO2 | RK_PC4 | |
85 | GPIO2 | RK_PC5 | |
86 | GPIO2 | RK_PC6 | |
87 | GPIO2 | RK_PC7 | |
88 | GPIO2 | RK_PD0 | |
89 | GPIO2 | RK_PD1 | |
90 | GPIO2 | RK_PD2 | |
91 | GPIO2 | RK_PD3 | |
92 | GPIO2 | RK_PD4 | |
93 | GPIO2 | RK_PD5 | |
94 | GPIO2 | RK_PD6 | |
95 | GPIO2 | RK_PD7 | |
96 | GPIO3 | RK_PA0 | SDIO |
97 | GPIO3 | RK_PA1 | SDIO |
98 | GPIO3 | RK_PA2 | SDIO |
99 | GPIO3 | RK_PA3 | SDIO |
100 | GPIO3 | RK_PA4 | SDIO |
101 | GPIO3 | RK_PA5 | SDIO |
102 | GPIO3 | RK_PA6 | |
103 | GPIO3 | RK_PA7 | |
104 | GPIO3 | RK_PB0 | HEADER_16 |
105 | GPIO3 | RK_PB1 | HEADER_18 |
106 | GPIO3 | RK_PB2 | |
107 | GPIO3 | RK_PB3 | |
108 | GPIO3 | RK_PB4 | |
109 | GPIO3 | RK_PB5 | |
110 | GPIO3 | RK_PB6 | |
111 | GPIO3 | RK_PB7 | HEADER_19 |
112 | GPIO3 | RK_PC0 | HEADER_21 |
113 | GPIO3 | RK_PC1 | HEADER_23 |
114 | GPIO3 | RK_PC2 | |
115 | GPIO3 | RK_PC3 | HEADER_26 |
116 | GPIO3 | RK_PC4 | HEADER_15 |
117 | GPIO3 | RK_PC5 | HEADER_22 |
118 | GPIO3 | RK_PC6 | |
119 | GPIO3 | RK_PC7 | |
120 | GPIO3 | RK_PD0 | |
121 | GPIO3 | RK_PD1 | PCIE-RESET |
122 | GPIO3 | RK_PD2 | UART9 |
123 | GPIO3 | RK_PD3 | UART9 |
124 | GPIO3 | RK_PD4 | UART9 |
125 | GPIO3 | RK_PD5 | UART9 |
126 | GPIO3 | RK_PD6 | |
127 | GPIO3 | RK_PD7 | |
128 | GPIO4 | RK_PA0 | |
129 | GPIO4 | RK_PA1 | |
130 | GPIO4 | RK_PA2 | HEADER_37 |
131 | GPIO4 | RK_PA3 | HEADER_8 |
132 | GPIO4 | RK_PA4 | HEADER_10 |
133 | GPIO4 | RK_PA5 | TYPEC_PWR |
134 | GPIO4 | RK_PA6 | HEADER_32 |
135 | GPIO4 | RK_PA7 | HEADER_35 |
136 | GPIO4 | RK_PB0 | I2C6 |
137 | GPIO4 | RK_PB1 | I2C6 |
138 | GPIO4 | RK_PB2 | |
139 | GPIO4 | RK_PB3 | HEADER_40 |
140 | GPIO4 | RK_PB4 | HEADER_38 |
141 | GPIO4 | RK_PB5 | HEADER_36 |
142 | GPIO4 | RK_PB6 | |
143 | GPIO4 | RK_PB7 | |
144 | GPIO4 | RK_PC0 | |
145 | GPIO4 | RK_PC1 | |
146 | GPIO4 | RK_PC2 | |
147 | GPIO4 | RK_PC3 | |
148 | GPIO4 | RK_PC4 | |
149 | GPIO4 | RK_PC5 | |
150 | GPIO4 | RK_PC6 | |
151 | GPIO4 | RK_PC7 | |
152 | GPIO4 | RK_PD0 | SDMMC |
153 | GPIO4 | RK_PD1 | SDMMC |
154 | GPIO4 | RK_PD2 | SDMMC |
155 | GPIO4 | RK_PD3 | SDMMC |
156 | GPIO4 | RK_PD4 | SDMMC |
157 | GPIO4 | RK_PD5 | SDMMC |
158 | GPIO4 | RK_PD6 | |
159 | GPIO4 | RK_PD7 |
Community member Alexander Mundy
sent the following note:
I added the command line gpioget to read the value of the header pins with libgpiod installed
Header pin #24 is not used by anything else according to the info on the wiki and it is 1.8V set to pulled up internally so perfect if you only need to pull a pin down and monitor it.