2020-03-05
md
I2C on the Orange Pi PC 2 with Armbian Bionic
<-ALSA and Bluetooth on the Orange Pi PC 2 with Armbian Bionic
<-A Second Look at the Orange Pi PC 2

Unlike the Raspberry Pi that hides the I2C bus used internally for recognizing extension boards (HATS), the two buses used internally by the Orange Pi PC 2 for managing on-board resources are visible yet not available for use. Armbian Bionic comes with overlays to enable three additional I2C controllers. The first two correspond to the physical buses available on the 40 pin GPIO header, just as on the Raspberry Pi. The third is used for the camera serial interface (CSI).

Table of Contents

  1. Default I2C Configuration
  2. Enabling the i2c0 Controller
  3. Enabling the i2c1 Controller
  4. The i2c2 Controller and the Camera Serial Interface (CSI)
  5. Enabling the DS1307/DS3231 driver on i2c1 with a Custom Overlay

Default I2C Configuration toc

The Allwinner H5 SoC has up to 4 I2C controllers according to the TWI overview found in the Allwinner H5 Datasheet (page 49).

2.2.9.6. TWI

Remember that TWI (Two Wire Interface) is the same thing as I2C (Inter-Integrated Circuit). The GPIO map shows that two physical I2C buses are available on the same pins of the 40 pin header as on Raspberry Pi models with a 40 pin header. Physical pins 3 and 27 are the data lines (TWI0_SDA and TWI1_SDA respectively) and pins 4 and 28 are the clocks (TWI0_SCK and TWI1_SCK respectively).

Orange Pi PC 2 GPIO Header
FunctionPinFunction
3.3V 125V
PA12 (TWI0_SDA/DI_RX/PA_EINT12) 345V
PA11 (TWI0_SCK/DI_TX/PA_EINT11) 56GND
PA6 (SIM_PWREN/PWM1/PA_EINT6) 78PC5 (NAND_RE/SDC2_CLK)
GND 910PC6 (NAND_RB0/SDC2_CMD)
PA1 (UART2_RX/JTAG_CK0/PA_EINT1) 1112PD14 (RGMII_NULL/MII_TXERR/RMII_NULL)
PA0 (UART2_TX/JTAG_MS0/PA_EINT0) 1314GND
PA3 (UART2_CTS/JTAG_DI0/PA_EINT3) 1516PC4 (NAND_CE0)
3.3V 1718PC7 (NAND_RB1)
PA15 (SPI1_MOSI/UART3_RTS/PA_EINT15) 1920GND
PA16 (SPI1_MISO/UART3_CTS/PA_EINT16) 2122PA2 (UART2_RTS/JTAG_DO0/PA_EINT2)
PA14 (SPI1_CLK/UART3_RX/PA_EINT14) 2324PA13 (SPI1_CS/UART3_TX/PA_EINT13)
GND 2526PA21 (PCM0_DIN/SIM_VPPPP/PA_EINT21)
PA19 (PCM0_CLK/TWI1_SDA/PA_EINT19) 2728PA18 (PCM0_SYNC/TWI1_SCK/PA_EINT18)
PA7 (SIM_CLK/PA_EINT7) 2930GND
PA8 (SIM_DATA/PA_EINT8) 3132PG8 (UART1_RTS/PG_EINT8)
PA9 (SIM_RST/PA_EINT9) 3334GND
PA10 (SIM_DET/PA_EINT10) 3536PG9 (UART1_CTS/PG_EINT9)
PD11 (RGMII_NULL/MII_CRS/RMII_NULL) 3738PG6 (UART1_TX/PG_EINT6)
GND 3940PG7 (UART1_RX/PG_EINT7)

On a fresh install of the Raspbian Bionic there were two i2c devices present in the /dev directory. After installing the i2c-tools package, it was possible to check for connected I2C devices.

opipc@orangepipc2:~$ ls -l /dev/i2* crw-rw---- 1 root i2c 89, 0 Feb 29 14:59 /dev/i2c-0 crw-rw---- 1 root i2c 89, 1 Feb 29 14:59 /dev/i2c-1 opipc@orangepipc2:~$ sudo apt install i2c-tools -y ... Need to get 69.9 kB of archives. After this operation, 289 kB of additional disk space will be used. ... Processing triggers for man-db (2.8.3-2ubuntu0.1) ... Processing triggers for libc-bin (2.27-3ubuntu1) ... opipc@orangepipc2:~$ sudo i2cdetect -y 0 opipc@orangepipc2:~$ sudo i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: 30 -- 32 -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- 59 -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- opipc@orangepipc2:~$ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

The results were surprising because there were two devices connected to PA12 and PA11 (physical pins 3 and 5), which I thought would be controlled by i2c0, but the addresses (0x30, 0x32 and 0x59) were wrong. As for bus 1, I had no clue what could be at 0x65, but the address was probably correct since UU indicates the presence of a driver. A look at loaded modules gave some information

opipc@orangepipc2:~$ lsmod | grep -i i2c i2c_mv64xxx 20480 0

A Web search led to a 2013 commit in the Linux repository with a hint of what the module does.

i2c: mv64xxx: Add I2C Transaction Generator support The I2C Transaction Generator offloads CPU from managing I2C transfer step by step.

The SUNXI wiki Xunlong Orange Pi PC 2, CPU clock speed limit about the OPiPC2 had some information about I2C address 0x65. "The Orange Pi PC 2 board uses the SY8106A voltage regulator (U9) for providing the CPU core voltage (VDD_CPUX, nominally 1.2V at 6A). The default CPU voltage is 1.1V after power-on (selected by the resistors on the PCB) and can be changed at runtime by software via I2C interface (I2C address 0x65)." Looking into the voltabe regulator, the only register that I dared attempt to read was its status register, expecting a value of 0x01.

NameBitAccessDefaultDescription
OTP7R01 : Die temperature over 160°C, OTP is triggered
0 : OTP is not triggered
6R0Reserved
5R0Reserved
OC4R01. OCP is triggered and Vo drops below 1/3 of set point.
0. Current is below current limit
Temperature
Warning
3R01 : Die temperature over 125°C
0 : Die temperature below 125°
2R0Reserved
1R0Reserved
PGOOD0R01 : Vout in power good regulation range
0 : Vout not in power good regulation range

However, I did not get very far.

opipc@orangepipc2:~$ sudo i2cget -y 1 0x65 0x06 Error: Could not set address to 0x65: Device or resource busy opipc@orangepipc2:~$ lsmod | grep -i sy8106 sy8106a_regulator 16384 1 opipc@orangepipc2:~$ sudo rmmod sy8106a_regulator rmmod: ERROR: Module sy8106a_regulator is in use

While removing the rtc_ds1307 module in order to read the temperature of the DS3231 real time clock had worked on the Raspberry Pi, I was clearly out of luck here. That's that, time to move on to the other I2C bus. Here's what I found about i2c-0 by listing the I2C bus devices and pertinent startup messages.

opipc@orangepipc2:~$ ls -l /sys/bus/i2c/devices total 0 lrwxrwxrwx 1 root root 0 Mar 5 12:03 1-0065 -> ../../../devices/platform/soc/1f02400.i2c/i2c-1/1-0065 lrwxrwxrwx 1 root root 0 Mar 5 12:02 i2c-0 -> ../../../devices/platform/soc/1ee0000.hdmi/i2c-0 lrwxrwxrwx 1 root root 0 Mar 5 12:03 i2c-1 -> ../../../devices/platform/soc/1f02400.i2c/i2c-1 opipc@orangepipc2:~$ dmesg | grep hdmi [ 2.104958] sun8i-dw-hdmi 1ee0000.hdmi: 1ee0000.hdmi supply hvcc not found, using dummy regulator [ 2.105789] sun8i-dw-hdmi 1ee0000.hdmi: Detected HDMI TX controller v1.32a with HDCP (sun8i_dw_hdmi_phy) [ 2.106117] sun8i-dw-hdmi 1ee0000.hdmi: registered DesignWare HDMI I2C bus driver [ 2.106341] sun4i-drm display-engine: bound 1ee0000.hdmi (ops 0xffff800010bdcd30)

According to SUNXI, the Allwinner H3 SoC uses a Synopsys DesignWare HDMI controller. Furthermore, "...H5 is basically an Allwinner H3 with the Cortex-A7 cores replaced with Cortex-A53 cores." Presumably, the OPiPC2 also has a Synopsys DesignWare HDMI controller which the startup messages appear to confirm. What can also be seen is that there is an I2C bus driver connected to the i2c-0 controller. By the way, the drm in the sun4i-drm display engine stands for Direct Rendering Manager, a subsystem of the Linux kernel interfacing with the GPU, not for Digital Rights Management. So it certainly looks like i2c-0 controls another internal I2C channel.

It would probably be best to avoid poking both these internal I2C buses given the warning in the i2cdetect man page:

Warning
This program can confuse your I2C bus, cause data loss and worse!

Fortunately, no OPiPC2 were harmed in the making of this post.

Enabling the i2c0 Controller toc

The system configuration utility, can be used to enable the i2c0 controller.

opipc@orangepipc2:~$ sudo armbian-config

Select System (System and security settings) then Hardware (Toggle hardware configuration: UART, I2C, etc. and finally mark i2c0 for installation. Notice that there are 3 I2C device tree overlays that can be enabled. Basically, the utility adds an entry in the configuration file /boot/armbianEnv.txt. Accordingly, it is possible to activate the wanted device tree overlay by including it in the configuration file (see Device Tree overlays in the Armbian User Guide Documentation).

opipc@orangepipc2:~$ sudo nano /boot/armbianEnv.txt

verbosity=1 console=both overlay_prefix=sun50i-h5 rootdev=UUID=a948f949-ea06-4a76-9d5d-4c9da81e0efe rootfstype=ext4 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u overlays=i2c0

No matter which way is used to activate the I2C controller, it will be necessary to reboot. When that is done, look for connected devices on i2c-0.

opipc@orangepipc2:~$ ls -l /sys/bus/i2c/devices/i2c* lrwxrwxrwx 1 root root 0 Mar 5 18:18 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/platform/soc/1c2ac00.i2c/i2c-0 lrwxrwxrwx 1 root root 0 Mar 5 18:18 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/platform/soc/1ee0000.hdmi/i2c-1 lrwxrwxrwx 1 root root 0 Mar 5 18:18 /sys/bus/i2c/devices/i2c-2 -> ../../../devices/platform/soc/1f02400.i2c/i2c-2 opipc@orangepipc2:~$ sudo ls -l /dev/i2c* crw-rw---- 1 root i2c 89, 0 Mar 2 19:30 /dev/i2c-0 Hardware I2C bus on PA12 and PA11 (physical pins 3 and 5) crw-rw---- 1 root i2c 89, 1 Mar 2 19:30 /dev/i2c-1 Internal I2C bus for hdmi controller crw-rw---- 1 root i2c 89, 2 Mar 2 19:30 /dev/i2c-2 Internal I2C bus for SY8106A voltage regulator opipc@orangepipc2:~$ sudo i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

The two devices connected to physical pins 3 and 5 of the 40 pin header assigned to the i2c-0 controller are found at the correct addresses.

The physical module with these two devices was discussed in detail when installed on a Raspberry Pi. I wanted to replicate the read and write to EEPROM test done in that post but I ran into a couple of difficulties. The first was easy to fix: add the default user to the i2c group that was created when i2c-tools was installed, to avoid the need to resort to the sudo command all the time when dealing with the I2C bus.

opipc@orangepipc2:~$ sudo adduser opipc i2c Adding user `opipc' to group `i2c' ... Adding user opipc to group i2c Done. opipc@orangepipc2:~$ exit

The second problem was a **** stack smashing detected *** error each time I tried running the eeprog program. All discussions of "stack smashing" talked of buffer overruns which sent me on a futile search for buffers in the source code. Trying to locate the latest version of the original branch of eeprog, I found a fork of version 0.7.6 by Alvin Wang with one change in the 24cXX.c source code that fixed the problem. Here is how to install and fix the "tear" version of eeprog in the same manner.

opipc@orangepipc2:~ $ wget https://github.com/jsarenik/eeprog/archive/master.zip --2020-01-29 19:10:06-- https://github.com/jsarenik/eeprog/archive/master.zip ... 2020-01-29 19:10:07 (268 KB/s) - ‘master.zip’ saved [19445] opipc@orangepipc2:~ $ unzip master.zip ... opipc@orangepipc2:~ $ mv eeprog-master eeprog opipc@orangepipc2:~ $ cd eeprog opipc@orangepipc2:~/eeprog$ nano 24cXX.c

In the editor change the first line of the eeprom_open function.

int eeprom_open(char *dev_fqn, int addr, int type, int write_cycle_time, struct eeprom* e) { int funcs, fd, r;

to

int eeprom_open(char *dev_fqn, int addr, int type, int write_cycle_time, struct eeprom* e) { // int funcs, fd, r; // https://github.com/alvintpwang/eeprog/commit/8ffb91311d87af0aa87a817f2a6cfd63121f7c02 unsigned long funcs; int fd, r;

What I think is going on is that ioctl(fd, I2C_FUNCS, &funcs), called in eeprom_open, returns a 64 bit list of functions in Armbian Bionic which is a 64 bit OS but an int is 32 bits. The problem did not occur in Raspbian Buster which is still a 32 bit system. After that fix, it was possible to carry on as with the Raspberry Pi.

opipc@orangepipc2:~/eeprog $ make opipc@orangepipc2:~/eeprog $ cd .. opipc@orangepipc2:~$ eeprog/eeprog -f -16 -r 0:16 /dev/i2c-0 0x57 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-0, Address: 0x57, Mode: 16bit Operation: read 16 bytes from offset 0, Output file: <stdout> Reading 16 bytes from 0x0 ���������������� opipc@orangepipc2:~$ echo "eeprom on i2c-0 " | eeprog/eeprog -f -16 -w 0x00 -t 2 /dev/i2c-0 0x57 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-0, Address: 0x57, Mode: 16bit Operation: write at offset 0, Input file: <stdin> Write cycle time: 2 milliseconds Writing <stdin> starting at address 0x0 ................. opipc@orangepipc2:~$ eeprog/eeprog -f -16 -r 0:16 /dev/i2c-0 0x57 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-0, Address: 0x57, Mode: 16bit Operation: read 16 bytes from offset 0, Output file: <stdout> Reading 16 bytes from 0x0 eeprom on i2c-0

Since there is a real-time clock on the H5 SoC which is enabled in the kernel and there does not seem to be a real-time clock overlay equivalent to i2c-rtc found in Raspbian, hwclock cannot be used to acces the DS3231 (this is not an accurate statement and, as shown further on, an rtc overlay can be installed.) It was easy to read and write the real time clock registers with some i2c-tools utilities: i2cdump and i2cset.

opipc@orangepipc2:~$ i2cdump -y -r 0x00-0x06 0 0x68 b 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 18 03 00 01 01 01 00 ??.???.

This corresponds to the time 00-01-01 00:03:18. Let's change the year and dump the RTC registers again.

opipc@orangepipc2:~$ i2cset -y 0 0x68 0x06 0x22 b opipc@orangepipc2:~$ i2cdump -y -r 0x00-0x06 0 0x68 b 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 14 08 00 01 01 01 22 ??.???"

The time was changed to 22-01-01 00:08:14 so that clearly the year had been updated without problem.

Enabling the i2c1 Controller toc

It was easy to check that i2c1 controls the hardware I2C bus on pins 27 and 28 of the 40 GPIO header by connecting the RTC/EEPROM module to those pins (SDA to pin 27, SCL to pin 28). This is the modified configuration file.

verbosity=1 console=both overlay_prefix=sun50i-h5 rootdev=UUID=a948f949-ea06-4a76-9d5d-4c9da81e0efe rootfstype=ext4 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u overlays=i2c0 i2c1

After rebooting, I checked all I2C buses.

opipc@orangepipc2:~$ ls -l /sys/bus/i2c/devices/i2c* lrwxrwxrwx 1 root root 0 Mar 5 19:56 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/platform/soc/1c2ac00.i2c/i2c-0 lrwxrwxrwx 1 root root 0 Mar 5 19:56 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/platform/soc/1c2b000.i2c/i2c-1 lrwxrwxrwx 1 root root 0 Mar 5 19:56 /sys/bus/i2c/devices/i2c-2 -> ../../../devices/platform/soc/1ee0000.hdmi/i2c-2 lrwxrwxrwx 1 root root 0 Mar 5 19:56 /sys/bus/i2c/devices/i2c-3 -> ../../../devices/platform/soc/1f02400.i2c/i2c-3 opipc@orangepipc2:~$ ls -l /dev/i2c* crw-rw---- 1 root i2c 89, 0 Mar 2 19:30 /dev/i2c-0 Hardware I2C bus on PA12 and PA11 (physical pins 3 and 5) crw-rw---- 1 root i2c 89, 1 Mar 2 19:30 /dev/i2c-1 Hardware I2C bus on PA19 and PA18 (physical pins 27 and 28) crw-rw---- 1 root i2c 89, 2 Mar 2 19:30 /dev/i2c-2 Internal I2C bus for hdmi controller crw-rw---- 1 root i2c 89, 3 Mar 3 23:10 /dev/i2c-3 Internal I2C bus for SY8106A voltage regulator

As before, the internal I2C controllers are assigned higher bus numbers because of the I2C controllers added with overlays. It was a simple matter to check that the EEPROM on bus 1 could be accessed.

opipc@orangepipc2:~$ echo "eeprom on i2c-1 " | eeprog/eeprog -f -16 -w 0x00 -t 2 /dev/i2c-1 0x57 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x57, Mode: 16bit Operation: write at offset 0, Input file: <stdin> Write cycle time: 2 milliseconds Writing <stdin> starting at address 0x0 ................. opipc@orangepipc2:~$ eeprog/eeprog -f -16 -r 0:16 /dev/i2c-1 0x57 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x57, Mode: 16bit Operation: read 16 bytes from offset 0, Output file: <stdout> Reading 16 bytes from 0x0 eeprom on i2c-1

This time I used an updated version of a rtc Python script to verify that it was possible to read and write to the DS3231 on bus 1.

opipc@orangepipc2:~$ ve rtcpy (rtcpy) opipc@orangepipc2:~$ rtcpy/rtc -i 1 Mon Sep 1 02:29:16 2059 (rtcpy) opipc@orangepipc2:~$ rtcpy/rtc -i 1 -s "2018-07-01 01:01:05" (rtcpy) opipc@orangepipc2:~$ rtcpy/rtc -i 1 Sun Jul 1 01:01:07 2018

The i2c2 Controller and the Camera Serial Interface (CSI) toc

Here is the part of the description file pertaining to I2C overlays.

opipc@orangepipc2:~$ cat /boot/dtb/allwinner/overlay/README.sun50i-h5-overlays ... ### i2c2 Activates TWI/I2C bus 2 I2C2 pins (SCL, SDA): PE12, PE13 On most board this bus is wired to Camera (CSI) socket ...

While the main reference for the OPiPC2 hardware does describe the camera serial interface (CSI), it does not specify the I2C controller used nor the GPIO pins. The schematic does show that pins PE12 and PE13 of the H5, identified as PE12/CSI_SCK/TWI2_SCK and PE13/CSI_SDA/TWI2_SDA are connected to CAM-SCK and CAM-SDA (pins 4 and 3 of the CSI connector).

I was hoping to use a Raspberry Pi camera to test the I2C - CSI connection on the OPiPC2 but a discussion on the Orange Pi Forum, How to Interface Raspberry Pi Camera on Orange pi, and a related Hackaday entry: Raspberry Pi camera on Orange Pi Plus board. Convert MIPI CSI-2 2 lanes into DVP using a FPGA. considerably diminished my hopes. They were completely dashed when it became obvious the camera cable did not fit in the OPiPC2 CSI connector. Nevertheless, I enabled the I2C bus and proceeded with the usual detection of the I2C buses.

verbosity=1 console=both overlay_prefix=sun50i-h5 rootdev=UUID=a948f949-ea06-4a76-9d5d-4c9da81e0efe rootfstype=ext4 overlays=i2c0 i2c1 i2c2 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

As before there are two more I2C buses beside the three enabled with device tree overlays.

opipc@orangepipc2:~$ ls -l /sys/bus/i2c/devices/i2c* lrwxrwxrwx 1 root root 0 Mar 5 20:36 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/platform/soc/1c2ac00.i2c/i2c-0 lrwxrwxrwx 1 root root 0 Mar 5 20:36 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/platform/soc/1c2b000.i2c/i2c-1 lrwxrwxrwx 1 root root 0 Mar 5 20:36 /sys/bus/i2c/devices/i2c-2 -> ../../../devices/platform/soc/1c2b400.i2c/i2c-2 lrwxrwxrwx 1 root root 0 Mar 5 20:36 /sys/bus/i2c/devices/i2c-3 -> ../../../devices/platform/soc/1ee0000.hdmi/i2c-3 lrwxrwxrwx 1 root root 0 Mar 5 20:36 /sys/bus/i2c/devices/i2c-4 -> ../../../devices/platform/soc/1f02400.i2c/i2c-4 opipc@orangepipc2:~$ ls -l /dev/i2c* crw-rw---- 1 root i2c 89, 0 Mar 5 20:36 /dev/i2c-0 Hardware I2C bus on PA12 and PA11 (physical pins 3 and 5) crw-rw---- 1 root i2c 89, 1 Mar 5 20:36 /dev/i2c-1 Hardware I2C bus on PA19 and PA18 (physical pins 27 and 28) crw-rw---- 1 root i2c 89, 2 Mar 5 20:36 /dev/i2c-2 Hardware I2C bus on PE13 and PE12 (pins 3 and 4 of CSI connector) crw-rw---- 1 root i2c 89, 3 Mar 5 20:36 /dev/i2c-3 crw-rw---- 1 root i2c 89, 4 Mar 5 20:36 /dev/i2c-4 opipc@orangepipc2:~$ ls -l /dev/i2c* crw-rw---- 1 root i2c 89, 0 Mar 4 14:28 /dev/i2c-0 Hardware I2C bus on physical pins 3 and 5 crw-rw---- 1 root i2c 89, 1 Mar 4 14:28 /dev/i2c-1 Hardware I2C bus on physical pins 27 and 28 crw-rw---- 1 root i2c 89, 2 Mar 4 14:28 /dev/i2c-2 Hardware I2C bus on CSI connector crw-rw---- 1 root i2c 89, 3 Mar 4 14:28 /dev/i2c-3 Internal I2C bus for hdmi controller crw-rw---- 1 root i2c 89, 4 Mar 4 14:28 /dev/i2c-4 Internal I2C bus for SY8106A voltage regulator

Strangely i2cdetect -y 2 took more than four minutes to complete the bus scan.

opipc@orangepipc2:~$ date Thu Mar 5 20:45:33 AST 2020 opipc@orangepipc2:~$ 2cdetect -y 2 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- opipc@orangepipc2:~$ date Thu Mar 5 20:49:51 AST 2020

Unfortunately, I could not investigate this I2C hardware bus any further.

Enabling the DS1307/DS3231 driver on i2c1 with a Custom Overlay toc

Among the example custom overlays in the Armbian Github repository, there is one named i2c-ds1307.dts which can be installed following the Armbian User Guide instructions. Preparing for that, I cutdown on the number of I2C controllers, installing only i2c1. Here is the content of the /boot/armbianEnv.txt file.

verbosity=1 console=both overlay_prefix=sun50i-h5 rootdev=UUID=a948f949-ea06-4a76-9d5d-4c9da81e0efe rootfstype=ext4 overlays=i2c1 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

After rebooting, there were three I2C devices.

opipc@orangepipc2:~$ ls -l /dev/i2c* crw-rw---- 1 root i2c 89, 1 Mar 4 14:28 /dev/i2c-1 Hardware I2C bus on physical pins 27 and 28 crw-rw---- 1 root i2c 89, 2 Mar 4 14:28 /dev/i2c-2 Spurious I2C bus crw-rw---- 1 root i2c 89, 3 Mar 4 14:28 /dev/i2c-3 Internal I2C bus for SY8106A voltage regulator

I created a directory and copied the overlay source file to it.

opipc@orangepipc2:~$ mkdir ds1307_dts opipc@orangepipc2:~$ wget https://raw.githubusercontent.com/armbian/sunxi-DT-overlays/master/examples/i2c-ds1307.dts -O ds1307_dts/i2c-ds1307.dts

I changed the alias to set the DS3231 as device rtc1 instead of rtc0 so that hwclock can read/write both the DS3231 and the built-in real-time clock.

opipc@orangepipc2:~$ cat ds1307_dts/i2c-ds1307.dts /dts-v1/; /plugin/; / { compatible = "allwinner,sun4i-a10", "allwinner,sun7i-a20", "allwinner,sun8i-h3", "allwinner,sun50i-a64", "allwinner,sun50i-h5"; /* * Aliases can be used to set the external RTC as rtc0 * Needs supplying the correct path to the I2C controller RTC is connected to, * this example is for I2C1 on H3 - works on I2C1 H5 * NOTE: setting time at boot by the kernel * may not work in some cases if the external RTC module is loaded too late */ fragment@0 { target-path = "/aliases"; __overlay__ { #rtc0 = "/soc/i2c@01c2b000/ds1307@68"; rtc1 = "/soc/i2c@01c2b000/ds1307@68"; }; }; fragment@1 { target = <&i2c1>; __overlay__ { #address-cells = <1>; #size-cells = <0>; ds1307@68 { compatible = "dallas,ds1307"; reg = <0x68>; status = "okay"; }; }; }; };

If the hardware clock was to be connected to the PA12 and PA11 I2C bus and appear as rtc3 in the /dev directory then the "alias" fragment should be rtc3 = "/soc//i2c@1c2ac00/ds1307@68";. Of course, the i2c0 parameter would have to be included in the overlays line of the /boot/armbianEnv.txt configuration file.

The overlay had to be compiled and the system then had to be rebooted.

opipc@orangepipc2:~/ds1307_dts$ sudo armbian-add-overlay i2c-ds1307.dts Compiling the overlay Copying the compiled overlay file to /boot/overlay-user/ Reboot is required to apply the changes

A first check of I2C buses, loaded kernel modules and rtc devices after the reboot was very encouraging.

opipc@orangepipc2:~$ ls -l /sys/bus/i2c/devices/ total 0 lrwxrwxrwx 1 root root 0 Mar 5 21:18 1-0068 -> ../../../devices/platform/soc/1c2b000.i2c/i2c-1/1-0068 lrwxrwxrwx 1 root root 0 Mar 5 21:18 3-0065 -> ../../../devices/platform/soc/1f02400.i2c/i2c-3/3-0065 lrwxrwxrwx 1 root root 0 Mar 5 21:18 i2c-1 -> ../../../devices/platform/soc/1c2b000.i2c/i2c-1 lrwxrwxrwx 1 root root 0 Mar 5 21:18 i2c-2 -> ../../../devices/platform/soc/1ee0000.hdmi/i2c-2 lrwxrwxrwx 1 root root 0 Mar 5 21:18 i2c-3 -> ../../../devices/platform/soc/1f02400.i2c/i2c-3 opipc@orangepipc2:~$ lsmod | grep ds1307 rtc_ds1307 32768 0 opipc@orangepipc2:~$ ls -l /dev/rtc* lrwxrwxrwx 1 root root 4 Mar 4 15:40 /dev/rtc -> rtc0 crw------- 1 root root 253, 0 Mar 4 15:40 /dev/rtc0 crw------- 1 root root 253, 1 Mar 4 15:40 /dev/rtc1

The following shows that the system utility hwclock can be used to read or set the time of both the external DS3231 real-time clock and the internal real-time clock.

opipc@orangepipc2:~$ sudo hwclock -D hwclock from util-linux 2.31.1 System Time: 1583350900.345862 Trying to open: /dev/rtc0 Using the rtc interface to the clock. Assuming hardware clock is kept in UTC time. Waiting for clock tick... ...got clock tick Time read from Hardware Clock: 2020/03/04 19:41:42 Hw clock time : 2020/03/04 19:41:42 = 1583350902 seconds since 1969 Time since last adjustment is 1583350902 seconds Calculated Hardware Clock drift is 0.000000 seconds 2020-03-04 15:41:40.143502-0400 opipc@orangepipc2:~$ sudo hwclock -f /dev/rtc1 -D hwclock from util-linux 2.31.1 System Time: 1583350951.574846 Using the rtc interface to the clock. Assuming hardware clock is kept in UTC time. Waiting for clock tick... ioctl(4, RTC_UIE_ON, 0): Invalid argument Waiting in loop for time from /dev/rtc1 to change ...got clock tick Time read from Hardware Clock: 2000/01/01 01:34:52 Hw clock time : 2000/01/01 01:34:52 = 946690492 seconds since 1969 Time since last adjustment is 946690492 seconds Calculated Hardware Clock drift is 0.000000 seconds 1999-12-31 21:34:50.992573-0400 opipc@orangepipc2:~$ sudo hwclock -f /dev/rtc1 --set --date "2020-03-03 13:52:00" -D hwclock from util-linux 2.31.1 System Time: 1583351018.357764 Using the rtc interface to the clock. Assuming hardware clock is kept in UTC time. 1583351018.857764 is close enough to 1583351018.857764 (0.000000 < 0.001000) Set RTC to 1583257920 (1583257920 + 0; refsystime = 1583351018.357764) Setting Hardware Clock to 17:52:00 = 1583257920 seconds since 1969 ioctl(RTC_SET_TIME) was successful. Not adjusting drift factor because the --update-drift option was not used. New /etc/adjtime data: 0.000000 1583257920 0.000000 1583257920 UTC opipc@orangepipc2:~$ date Wed Mar 4 16:08:18 AST 2020 opipc@orangepipc2:~$ sudo hwclock 2020-03-04 16:08:11.146445-0400 opipc@orangepipc2:~$ sudo hwclock -f /dev/rtc1 2020-03-03 14:16:54.798416-0400

As far as I know, armbian-add-overlay compiles i2c-ds1307.dts to /boot/overlay-user/i2c-ds1307.dtbo and added the user_overlays line in /boot/armbianEnv.txt.

opipc@orangepipc2:~$ ls -l /boot/overlay-user total 4 -rw-r--r-- 1 root root 640 Mar 4 15:39 i2c-ds1307.dtbo opipc@orangepipc2:~$ cat /boot/armbianEnv.txt verbosity=1 console=both overlay_prefix=sun50i-h5 rootdev=UUID=a948f949-ea06-4a76-9d5d-4c9da81e0efe rootfstype=ext4 overlays=i2c1 user_overlays=i2c-ds1307 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

So to remove the overlay, I deleted the compiled dtbo file, leaving an empty /boot/overlay-user/ directory, and I removed the user_overlays=i2c-ds1307 line in /boot/armbianEnv.txt file. After rebooting, /dev/rtc1 was gone.

The armbian-add-overlay compiler will not add the overlays=i2c1 to the configuration file on its own. This must be done manually as shown above.

<-ALSA and Bluetooth on the Orange Pi PC 2 with Armbian Bionic
<-A Second Look at the Orange Pi PC 2