Rock64 single-board computer
This is a cousin of the Pine A64 board; it has made by the same people,
and like the Pine A64, it has a 4-core, 64-bit processor. There are 3
variants available, with 1, 2 or 4 GB of memory. I have the ones with
4 GB, identified as ROCK64_V2.0 2017-0713 written on the circuit board,
right above the location of the Rockchip RK3328.
This is where OS-developments are happening:
https://github.com/ayufan-rock64/linux-build/releases.
Kernel 4.4.70 is what is being used here at present.
There is quite a lot of development going on, so this info may change
frequently as new versions come into existence.
GPIOs
The board has a form-factor very similar to the Raspberry Pi: around the
edges, the sd-card, the power, HDMI, Ethernet, and USB connections, are all in
the same locations. With a small modifications to the case, it fit right into
a case originally made for the Raspberry Pi. This modification comprised
drilling out the opening for the power inlet to fit the barrel connector
which the Rock64 has in place of the less robust micro-usb connector. On the edge near the SD-card,
there are two pushbuttons, labeled Pwr Btn and Reset Btn. Here are also 3 LEDs,
a red one labeled STBY, a white one labeled PWR, and a green one labeled IR.
Further inwards near the others, is a third pushbutton labeled Recovery Btn.
There is also two GPIO connectors, one of them, called the Pi-2 Bus,
is in the by now familiar 2 by 20 form, and with pins with similar power, ground
and other functions as the one on the Raspberry Pi. In addition, there is a
second row of pins, 2 by 11, called the Pi P5+ Bus, which appears to
have been inspired by the P5 connector that was present on the earlier Raspberry
Pi A and B models. Of note is the presence of i2s signals here.
Electrically, all pins operate on standard 3.3 V digital voltage levels.
From the RK3328 Datasheet V1.1:
Parameter | Condition | Min | Typ | Max |
Vil | | -0.3V | 0V | 0.9V |
Vih | | 2.31V | 3.3V | 3.6V |
Vol | | -0.3V | 0V | NA |
Voh | | NA | 3.3V | 3.6V |
VThr+ | | 1.53V | 1.46V | 1.43V |
VThr- | | 1.19V | 1.12V | 1.05V |
R Pullup | | 33.7kΩ | 58kΩ | 101.5kΩ |
R Pulldown | | 34.2kΩ | 60.1kΩ | 109.3kΩ |
Il | 0V to 3.3V | NA | NA | 10µA |
Iz | 0V to 3.3V | NA | NA | 10µA |
Iil | V=0V | NA | NA | 10µA |
Iil-Pde | V=0V | NA | NA | 106.4µA |
Iih | V=3.3V | NA | NA | 10µA |
Iih-Pue | V=3.3V | NA | NA | 107.8µA |
The pin-out has been quite well documented, and is as found here:
http://files.pine64.org/doc/rock64/ROCK64_Pi-2%20_and_Pi_P5+_Bus.pdf
We notice that the gpio numbering is on the form exemplified by GPIO3_A5. GPIOs
are organized in four banks, identified as GPIO0 through GPIO3. Then within each,
there are several sets of ports associated with one of four pads, and numbered within
each of these.
Each gpio is identified thus on schematics and on the map referenced above, as
GPIO(bank)_(pad)(number)
To convert from this to the linear numbering seen with sysfs and kernel modules,
the following applies:
index = bank * 32 + pad * 8 + number
GPIO3_A5
^ ^^
| |\_number
| \__pad: A=0, B=1, C=2, D=3
\____bank
Example, 3*32+0*8+5 = 96+0+5 = 101 so this is gpio-101
Several of the gpios are in use for various other system-related purposes.
There is some discussion and links to other diagrams here:
https://forum.pine64.org/showthread.php?tid=4695
There is also some information from the kernel, about its
reserved GPIOs. Three of these exist on pins on the headers,
as annotated in boldface.
# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/pinctrl, gpio0:
gpio-0 ( |vbus-drv ) out hi (Pin P13)
gpio-2 ( |? ) out lo
gpio-27 ( |otg-vbus ) out lo (Pin F13)
gpio-30 ( |vcc_sd ) out lo
GPIOs 32-63, platform/pinctrl, gpio1:
gpio-37 ( |cd ) in lo (Pin P36)
gpio-50 ( |mdio-reset ) out hi
GPIOs 64-95, platform/pinctrl, gpio2:
GPIOs 96-127, platform/pinctrl, gpio3:
GPIOs 510-511, platform/rk8xx-gpio, rk8xx-gpio, can sleep:
gpio-510 ( |? ) out hi
gpio-511 ( |? ) out lo
#
As noted in the diagrams linked above, there are a number of possible conflicts, even with
the ones made available. Indeed, many of the GPIOs available on the pin-headers are already
used for, in some cases, rather vital other functions, and we must tread carefully. Or maybe
re-purpose some of the connected devices, when we know which ones they are. General warnings,
such as Do not Use on Pain of Failure or Emissions of Magic Smoke, or
Reserved, without any further details, tend to make me irritated, then curious,
and so as to avoid actual likely pain && suffering, here are the details on where the dragons be
as well as the particular nature of these dragons.
Hence, I have been pulling in this data, and looked at the schematics. And here is the summary
on what is behind the various GPIO pins. Unfortunately, there is no good obvious mnemonics for the pin
headers and numbers here, as the two sets of interesting pins are labeled Pi-2 and Pi-5+. Practice on
the Pine64 had the 40-pin set identified as Pnn; this convention makes sense here. For the other
one, the Pi-5+, I will refer to these as Fnn for now, (F for Five).
Pi-2 bus. Pnn
Black is ground,
Red and Orange are power,
Green gpios are available, Cyan indicate operating i2c busses, Yellow are operating uarts.
Gray marked gpios are, or might be, in use with some other function and thus might not be freely available.
These include the PMIC and power control signals, the on-board SPI memory chip and the SD card. If the SD-card
is not used, the SDMMC0_xxx gpios will be free for something else. Since the on-board memory chip uses the SPI
lines, these are also of limited access.
P1 3.3V | P2 5.0V |
P3 89 GPIO2_D1 I2C0_SDA NET_Speed | P4 5.0V |
P5 88 GPIO2_D0 I2C0_SCL NET_Link | P6 Gnd |
P7 60 GPIO1_D4 CLK32OUT_M1 | P8 64 GPIO2_A0 UART2_TX |
P9 Gnd | P10 65 GPIO2_A1 UART2_RX |
P11 NC (66 GPIO2_A2 IR_RX) | P12 67 GPIO2_A3 (input only?) |
P13 0 GPIO0_A0 vbus-drv USB3 power control (U2502 Enable) | P14 Gnd |
P15100 GPIO3_A4 (uart1_tx) | P16 101 GPIO3_A5 |
P17 3.3V | P18 102 GPIO3_A6 (uart1_rx) |
P19 97 GPIO3_A1 SPI_TXD_M2 | P20 Gnd |
P21 98 GPIO3_A2 SPI_RXD_M2 | P22 103 GPIO3_A7 |
P23 96 GPIO3_A0 SPI_CLK_M2 | P24 104 GPIO3_B0 SPI_CSN0_M2 |
P25 Gnd | P26 76 GPIO2_B4 (SPI_CSN1_M0) |
P27 68 GPIO2_A4 I2C1_SDA_PMIC | P28 69 GPIO2_A5 I2C1_SCL_PMIC |
P29 NC (70 GPIO2_A6 PMIC_INT) | P30 GND |
P31 NC (2 GPIO0_A2 USB20_HOST_DRV, USB2 power control) | P32 38 GPIO1_A6 SDMMC0_CLK |
P33 32 GPIO1_A0 SDMMC0_D0 | P34 GND |
P35 33 GPIO1_A1 SDMMC0_D1 | P36 37 GPIO1_A5 SDMMC0_DET |
P37 34 GPIO1_A2 SDMMC0_D2/JTAG_TCK | P38 36 GPIO1_A4 SDMMC0_CMD |
P39 Gnd | P40 35 GPIO1_A3 SDMMC0_D3/JTAG_TMS DET |
Notes on some of the pins
Pins P3 and P5 might not always be configured as an i2c buss (no /dev/i2c-0). They can be enabled as such in recent kernel versions.
Pins P11, P29, and P31 appear to have no actual electrical connection to anything.
Pin P13 is connected, but its function was reserved for the power control of the USB3 lines on the Revision 1 systems.
It is still in use by a kernel function.
Pin P12, GPIO2_A3, gpio-67, seems to stick at value=1 when set to output. The wire reads +3.18V no matter which way the output is set,
and reading the value setting when it is at output returns 1 even if it was just set to 0.
With this gpio in the input direction, value reads 1 when not connected as there is a pull-up to 3.3V here. Pulling it down to 0V
(through 3.3 kΩ) drops the voltage on the wire to 0.13V makes the value read 0, so this has a limited use as input.
Schematics does not show any additional components connected to this line.
Pin P26 appears to be an available gpio, GPIO2_B4, gpio-76, from the technical manual page 483, we see there exist 3 SPI busses, of which SPI2 is the one
used for the memory. This SPI buss only has one chip select, the one connected on P24 which is used for the memory chip.
Meanhwile SPI0 only has this second chip select exposed, so unless SPI0 is being used as such for something else, this pin may be
freely used as a gpio. By the same token, pins P19, P21, and P23 are occupied by the memory chip and not really available.
Pins P27 and P28 operate as an i2c-buss, /dev/i2c-1, including pull-up resistors 2.2kΩ.
Address 0x18 is reserved for the PMIO but others can be used.
Pins P32, P33, P35, P37, and P40 are used with the SD card, and if we change to using eMMC instead, these will be
freed. Pin P36, gpio-37, is still being allocated by the kernel for detecting if an sd card is present,
(shows as lo when the card is in place and hi if it is absent.) so this is not immediately free.
For now, these gpios can be considered occupied. There might possibly also be some activity on these gpios
during bootup, even when no sd-card is in place.
Pi-P5+ bus. Fnn
Black is ground, Red and Orange are power,
Pink are the 10/100 second network (eth1) connections, these are not gpios.
Green gpios are available, all of these are useable for an I2S connection,
but can be used for something else when i2s is not being used.
Gray gpios are used with other functions and are not freely, or at all, available.
F1 3.3V | F2 5.0V |
F3 81 GPIO2_C1 I2S1_LRCKTX | F4 82 GPIO2_C2 I2S1_SCLK |
F5 87 GPIO2_C7 I2S1_SDO | F6 83 GPIO2_C3 I2S1_SDI |
F7 GND | F8 GND |
F9 80 GPIO2_C0 I2S1_LRCKRX | F10 79 GPIO2_B7 I2S1_MCLK |
F11 85 GPIO2_C5 I2S1_SDO2 | F12 84 GPIO2_C4 I2S1_SDO1 |
F13 27 GPIO0_D3 SPDIF_TX_MX (otg-vbus) | F14 86 GPIO2_C6 I2S1_SDO3 |
F15 GND | F16 GND |
F17 NET RD+ | F18 NET_RD- |
F19 NET TX+ | F20 NET_TD- |
F21 89 GPIO2_D1 I2C0_SDA NET_Speed | F22 88 GPIO2_D0 I2C0_SCL NET_Link |
From all the above, the following pins and gpios are the ones that are freely available
on the baseline system, with an SD card in place:
Pin gpio-# GPIOb_pn FUNCTION | Device |
P7 60 GPIO1_D4 CLK32OUT_M1 | |
P8 64 GPIO2_A0 UART2_TX | /dev/ttyFIQ0 |
P10 65 GPIO2_A1 UART2_RX | /dev/ttyFIQ0 |
P27 68 GPIO2_A4 I2C1_SDA_PMIC | /dev/i2c-1 |
P28 69 GPIO2_A5 I2C1_SCL_PMIC | /dev/i2c-1 |
P26 76 GPIO2_B4 (SPI_CSN1_M0) | |
F10 79 GPIO2_B7 I2S1_MCLK | |
F9 80 GPIO2_C0 I2S1_LRCKRX | |
F3 81 GPIO2_C1 I2S1_LRCKTX | |
F4 82 GPIO2_C2 I2S1_SCLK | |
F6 83 GPIO2_C3 I2S1_SDI | |
F12 84 GPIO2_C4 I2S1_SDO1 | |
F11 85 GPIO2_C5 I2S1_SDO2 | |
F14 86 GPIO2_C6 I2S1_SDO3 | |
F5 87 GPIO2_C7 I2S1_SDO | |
P5/F22 88 GPIO2_D0 I2C0_SCL NET_Link | /dev/i2c-0 |
P3/F21 89 GPIO2_D1 I2C0_SDA NET_Speed | /dev/i2c-0 |
P15 100 GPIO3_A4 (uart1_tx) | |
P16 101 GPIO3_A5 | |
P18 102 GPIO3_A6 (uart1_rx) | |
P22 103 GPIO3_A7 | |
UART
There are 3 uarts defined in the Rockchip RK3382, but one of them, uart0, competes with the Ethernet for its pins, so
it is not available. The other two have pins exposed however and might be made to work.
Although there exist /dev/ttyS0 through /dev/ttyS3, none of these appear to be hooked up to anything -- they merely
respond with "Input/output error" when attempted used. One would have expected that ttyS2 was found on pins P8 and P10,
and ttyS1 on pins P15 and P18.
Instead, the actual tty device that works with the internally defined UART2, on pins P8 and P10 is /dev/ttyFIQ0.
On boot-up, this emits startup messages, and it seems to be fixed at the high baudrate of 1500000, 1.5 Mbits/s. Even if
stty -F /dev/ttyFIQ0 -a says something else, it only seems to want to transmit and receive at this rather high rate.
As not all USB-connected devices of the FTDI or PL2303 varieties can deal with this speed, one thing that I found worked
well was to use the /dev/ttyS3 UART on a PineA64, and run minicom -D /dev/ttyS3 -b 1500000 on the PineA64 and use
this as a terminal.
Note that sometimes the Pine's UART3 has been allocated to use different pins.
See the discussion on Pine's UARTs for what this is all about.
The interconnection is fairly simple, three jumper wires:
Function | Rock64 Pin (Pi-2) | Pine64 Pin (Euler) | AF 954 USB-Serial Wire Color |
Ground | P6 | E25 | Black |
Tx Rock to Pine | P8 | E23 | White (Rx) |
Rx Rock from Pine | P10 | E24 | Green (Tx) |
I2C
Pinouts indicate there are i2c-0 signals on pins P3/F21 (SDA) and P5/F22 (SCL),
and i2c-1 on pins P27 (SDA) and P28 (SCL),
and looking at the system shows there are three i2c busses, /dev/i2c-0, /dev/i2c-1, and /dev/i2c-4.
in the 1233 kernel, of 2019-08-20.
(Earlier kernels didn't have this turned on.
but looking at the system shows only the /dev/i2c-1 and /dev/i2c-4 busses defined.)
Scanning i2c-0 with i2cdetect -y 0 shows there are lots of addresses found, but this is
because there are no pull-up resistors. When adding these on an additional card with pull-up
resistors and some devices on it, the listing show these appearing just as expected.
Scanning i2c-1 with i2cdetect -y 1, shows address 0x18 on /dev/i2c-1 being occupied by some
device or kernel function, presumably the PMIC, and i2cdetect -y 4 shows that the /dev/i2c-4 is on the hdmi
line and the DDC bus for monitor. The system emits messages about dw_hdmi_i2c_read calls erroring out.
Indeed, the schematics show that these i2c-1 lines go to a RK805-1 power control chip, the PMIC,
and there are 2.2kΩ pull-up resistors on them, so this can be used with some care (stay away from
address 0x18).
This address does give access to an RTC within the RK805-1 chip. Unfortunately, the designers have omitted
connections to a crystal and a backup-battery, so it can't work as an actual RTC that runs when the device is
turned off. However, we can still access it, set and read its time. By the time of the kernel identified
as 4.4.126-rockchip-ayufan-239 the time here does appears to be set at startup, since reading it on a
newly powered-up machine returns the correct date and time.
The i2c-0 buss on P3/F21 and P5/F22 shares wires with the two LED drive signals for the secondary network
interface (schematics page 12). These do not appear to have any pull-up resistors associated with them.
Since the kernel has an eth1 networking interface in place, chances are this will not be available for
use as an i2c bus for the time being. For now, these two lines do work as regular gpios and are identified
as such in the above lists.
In kernel
4.4.126-rockchip-ayufan-239 and presumably later on, this i2c-0 buss can be enabled by
device-tree overlays, with the command
enable_dtoverlay i2c0 i2c@ff150000 okay
With pull-up resistors in place, i2c-0 works as expected for an i2c buss. All addresses are available here.
I connected my test kit, a board comprising a pcf8574A and a ds1621; with SDA to pin P27
and SCL to pin P28, 3.3V power from pin P1 and ground from pin P6; then on running
i2cdetect -y 1, I see something appearing at 0x48 and 0x3d, besides the reserved UU at 0x18.
These should be the ds1621 and the pcf8574A, as expected. And
indeed, upon accessing them with my regular test programs, the ds1621 tells me the ambient
temperature is 25.8 degrees here, and the pcf8574A cycles through the 256 bit combinations as
shown on the LEDs. So whatever is present or absent, the i2c-1 buss works as expected.
Similarly, the same test kit worked as it should on i2c-0 when the device-tree overlay was
used to enable it.
Device-tree overlays
As seen with the i2c-0 buss, various supported devices can be enabled via overlays in the
device-tree structures.
Device names are defined in
https://github.com/ayufan-rock64/linux-kernel/blob/release-4.4/arch/arm64/boot/dts/rockchip/rk3328.dtsi
where the various i2c busses can be seen, as for example:
enable_dtoverlay i2c1 i2c@ff160000 okay
This i2c-1 buss is already turned on, as it has the PMIO/RTC chip sitting at address 0x18.
More about turning things on in
https://github.com/ayufan-rock64/linux-build/blob/master/recipes/additional-devices.md#use-additional-devices
MAC adress in
stretch-minimal-rock64-0.7.9-1067-arm64.img
from ayufan
There is now a file, /etc/dhcpcd.duid which contains a string such as:
00:01:00:01:22:ec:49:6c:5e:8e:b8:47:3b:bb
defining 14 octets, of which the MAC address is taken as the last 6.
This file appears to stay the same across reboots. The one I have
here is dated 2018-07-26, on a system that was brought up the first time 2018-12-06.
The contents thus are the same, and this might cause some issues when running several
units with the same edition of the OS...
Thus, on initial writing of the file systems, it might be advisable to check this file
before booting the first time.
SPI memory and MAC address
This applied to earlier kernels and has changed.
The SPI interface is connected to an onboard NVRAM memory chip, with 256K, 262144, or 0x40000 bytes in it.
It is made available through the /dev/mtd[0-4] device files. (There are the mtd[0-4]ro which appears to
be the same but not writeable.) With some versions of Linux, the MAC address sits inside
the /dev/mtd3, which contained all FF except for the first and last few octets:
00000000 44 56 4b 52 0f 00 00 00 01 00 ff ff 00 00 f8 fb *DVKR............*
0003fff0 ff ff ff ff ff ff ff ff ff ff ff ff 12 00 00 00 *................*
Now apparently, the system pulls the MAC address from locations 0x400-0x405 in this memory,
here, and if this is all 0xFFs it will be seen as an impossible -1, while if it is all 0s, the
kernel code will presumably allocate, store, and then keep on using this new mac address.
The quick way to deal with this is to wipe out the whole memory with 0s from
/dev/zero, as that will work; then after a reboot the address will have been set, and stay set.
The /dev/mtd3 is just a part of the memory space -- /proc/mtd shows what the size of all these
partitions are, and what names they have, which presumably has to do with the intended use.
# cat /proc/mtd
dev: size erasesize name
mtd0: 00008000 00001000 "system"
mtd1: 003f8000 00001000 "loader"
mtd2: 003c0000 00001000 "reserved"
mtd3: 00040000 00001000 "vendor"
mtd4: 00400000 00001000 "uboot"
mtd5: 00400000 00001000 "atf"
#
Looking at the list, and adding the sizes, the total size of this memory chip is 0x01000000 = 16M
This MAC address mechanism has not continued with later kernels. There is ongoing work to make the
Rock64 able to boot from code in this memory space, then continue running from an external USB-connected
disk -- thus making it work without either an SD-card or EMMC module as a third configuration option.
SPI memory and boot
It is now (2018-06-06) possible to put the u-boot bootloader code into the SPI memory, and the operating system
on an external USB device.
https://github.com/ayufan-rock64/linux-build/releases
provides some special images, including u-boot-flash-spi-rock64.img.xz that can be flashed to
an SD card in the usual way, then the Rock64 is powered on and boots off of that. After a few minutes the
white LED starts flashing, then the Rock64 can be powered off. Put the regular operating system image onto
the USB disk, memory stick or whatever, REMOVE THE SD CARD, connect the USB device, and power on again.
With spinning hard disks, I've noticed that the disk isn't always ready to go when the Rock64 expects it, so
it may have to be reset with the reset switch.
Installation notes
The Rock64's performance is very dependent on the SD-card being used. Samsung EVO+ are recommended,
I have tried several of the cards I have here, and the best performance, which is very good indeed, appears
with the Samsung EVO card. Another SD card, brand Patriot, still U1 and class 10, was totally inadequate,
while some of the Kingston cards, even a class-4 32GB one, made for acceptable performance, but not as good
as the Samsung EVO.
Notably, all these cards work fine on the PineA64 and on Raspberry Pies, so they are not wasted.
The images as being written to the card only have a root fs of a GB or so, so in order to continue setup,
the following can be done.
resize_rootfs
apt update
apt upgrade
Newer kernels seem to contain the necessary resize_rootfs operation on startup, so that is no longer
needed.
Then there are various useful things that can be installed, as usual:
apt install man manpages manpages-dev
apt install i2c-tools libi2c-dev python-smbus
apt install libasound2-dev libasound2-doc
apt install sqlite3 libsqlite3-dev sqlite3-doc
apt install zlib1g-dev
apt install libX11-dev libxcb-doc
apt install less
apt install gnuplot
apt install ntp
apt install bc
Using the EMMC
The Rock64 has a connector for an EMMC module, such as the ones available from the Pine Store,
and this can be used for mass storage, as an alternative to the SD card. The system will perform
consistenly well with the EMMC, and some of the GPIO lines that were used for the SD card will now
be available for other things.
In order to use an EMMC chip instead of an SD-card for the operating system, the OS image file has to be
written to this, and in order to do that, we need to make the operating system see the card when it is present.
This requires using an external serial monitor on the UART0, as discussed with the use of a Pine64 above.
First of all, get the Rock64 going with the SD-card in the usual way; and make sure
you have the image-file to be used for the EMMC available on the card. This image-file can be pulled from the
Internet, but it might as well be stored locally, making this whole procedure slightly less complex and less
error-prone later when the image file is to be written to the EMMC.
Next, make sure that the serial terminal to the system works (
sometimes the UART3 on the Pine appears on different wires, but can be put back to the expected location)
When that works, turn power off, make sure the EMMC module is in place, and then connect the two pins on
the EMMC Disable connector, with a jumper cable or similar. Turn the Rock64 on, then interrupt the boot sequence
when it is says you have a few seconds to hit a key in order to do so.
When the boot sequence has been interrupted thus, pull the jumper cable off the EMMC Disable connector,
so there is no longer any connection between the pins there. Once this has been done,
enter boot in the terminal, so that booting will continue. Now, both the EMMC and
the SD card will become visible in the operating system.
With fdisk -l, the SD-card will show as /dev/mmcblk0, and the EMMC will show as /dev/mmcblk1. There may be several
partitions in each, but what we will do now is to put the new image file onto the EMMC, in much the same way as we did
back when the SD-card was first written: dd if=imagefile.img of=/dev/mmcblk1 bs=4M will do.
Once this is done, shutdown the Rock64, power it off, then remove the SD-card, and power on again. It should now
boot from the image that we put into the EMMC, and be ready for further action and updates, exactly the same as when
it ran with the SD-card.
Boot from SPI memory
Instead of booting from an SD-card before then running the OS on an external disk, we can boot from the in-build SPI
memory. The wiki has info about how to go about this at
http://wiki.pine64.org/index.php/NOOB#Flashing_u-boot_to_SPI_Flash . This is a little simpler than the
above configuration with the EMMC.
Ubuntu operation notes
When the screen locks from inactivity, it looks like the mouse has failed to work, but what is happening
is that the Rock64 is waiting for the user to unlock the screen by typing in the password. Once that is done,
the desktop is back in action. It is NOT broken nor afflicted by a bad bug...
To stop this confusing behavior, find the settings for the screensaver and turn off locking of the screen.