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:

ParameterConditionMinTypMax
Vil -0.3V0V 0.9V
Vih 2.31V3.3V 3.6V
Vol -0.3V0V NA
Voh NA 3.3V 3.6V
VThr+ 1.53V1.46V 1.43V
VThr- 1.19V1.12V 1.05V
R Pullup 33.7kΩ58kΩ101.5kΩ
R Pulldown 34.2kΩ60.1kΩ109.3kΩ
Il 0V to 3.3VNA NA 10µA
Iz 0V to 3.3VNA NA 10µA
Iil V=0VNA NA 10µA
Iil-Pde V=0VNA NA 106.4µA
Iih V=3.3VNA NA 10µA
Iih-Pue V=3.3VNA 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.

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.

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

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 FUNCTIONDevice
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:

FunctionRock64 Pin
(Pi-2)
Pine64 Pin
(Euler)
AF 954 USB-Serial
Wire Color
GroundP6E25Black
Tx Rock to PineP8E23White (Rx)
Rx Rock from PineP10E24Green (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. But they may come without things like gcc and networking utilities.

Then there are various useful things that can be installed, as usual:

apt install vim gcc build-essential 
apt install net-tools
apt install binutils less file
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

The i2c-tools are in /usr/sbin, so can add this to the path in .profile, similar to additions made for local bin directories.

if [ -d "/usr/sbin" ] ; then
    PATH="/usr/sbin:$PATH"
fi

For kernel-headers, that go into /usr/src, Look at uname -a. It shows something like

Linux rock64 6.6.60-current-rockchip64 #2 SMP PREEMPT Fri Nov  8 15:28:28 UTC 2024 aarch64 GNU/Linux

Then in order to install the corresponding header, use that, such as

apt install linux-headers-current-rockchip64 

Then in the user's .profile, add

export KERNEL_SRC=/usr/src/linux-headers-`uname -r`

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.


Powered by Apache

Valid XHTML 1.0!