This post contains instructions on how to connect a real-time clock and EEPROM module to the Raspberry Pi running Raspberry Pi OS using a hardware or software I²C bus. The large chip on the module is the DS3231 which is the real-time clock, and the much smaller 8-pin chip is a 32K bit (4K bytes) AT24C32 EEPROM. This post is actually a rewrite of a post first put up in February. There are differences between Raspberry Pi OS and Raspbian Buster even if both are based on Debian 10 and the 4.19 Linux kernel. The major difference for our purposes is that in Buster, loading the real-time clock driver automatically enabled the I²C controller and this is no longer the case in the new version of the Raspberry operating system. I would speculate that the instructions contained here would therefore apply if Raspbian is still being used on the Raspberry Pi.
There are some teething problems with the new distribution. The device tree overlay for the software I²C controller is not functional. The problem has already been solved but the new overlay must be loaded manually as explained below. This step will not be necessary with the next release of the Raspberry Pi OS.
Table of content
- I²C on the Raspberry Pi
- Useful Software
- Using the Hardware Clock Connected to the Hardware I²C Bus
- Using the Flash Memory Connected to the Hardware I²C Bus
- Using the Hardware Clock Connected to a Software I²C Bus
- Using the Flash Memory Connected to the Software I²C Bus
- Multiples I²C Buses
- Compute Module and Raspberry Pi 4
- The Second Hardware I²C Bus
- Reading the DS3231 Temperature Sensor
- RTC/EEPROM Module Backup Power
I²C (Inter-Integrated Circuit or TWI - Two Wire Interface) is a serial communication protocol frequently used to connect many devices such as clocks, displays, EEPROM memories, and sensors to a micro-controller. The communication, which is not very fast, is done using two signals and a connection to ground.
- SDA - Serial Data Line
- SCL - Serial Clock Line
All Raspberry Pi models have a hardware I²C bus on pins 3 (SDA) and 5 (SCL) of GPIO connector which has 26 or 40 pins depending on the model. However, the bus is not enabled by default and until it is activated pins 3 and 5 are general I/O pins. If the GPIO connector of the Raspberry Pi has 40 pins, there is a second I²C hardware bus which is assigned to the identification of the extension cards (so called HATs) using pins 27 (ID_SD) and 28 (ID_SC). Unfortunately, use of this bus is not recommended even in the absence of a HAT. However, additional software I²C buses can be created by adding kernel modules.
While several devices can be connected to the I²C bus simultaneously,
only two devices can exchange data at any given time. The device that
initiates the connection is the master, the recipient is the slave. There can
be more than one master on the bus, but data exchange between masters is
impossible, as well as between slaves. In addition, a slave cannot initiate
communication with a master. See Understanding
the I²C Bus, Texas Instruments Application Report SLVA704, p. 3. by Jonathan Valdez and Jared Becker (juin 2015).
In principle, a device can be master or slave; never both simultaneously.
In practice, most simpler devices are only slaves and only micro-controllers
have the possibility of being a slave in addition to being a master, but this
is not always the case. Indeed, it seems that the Raspberry Pi is not able
to put its I²C bus in slave mode.
As one would expect in Linux, an I²C bus is
represented by a file in the device directory /dev. As an
example, there are three I²C buses activated on an Orange Pi PC 2.
opipc@orangepipc2:~$ ls -l /dev/i2*
crw-rw---- 1 root i2c 89, 0 Feb 16 04:02 /dev/i2c-0
crw-rw---- 1 root i2c 89, 1 Feb 16 04:02 /dev/i2c-1
crw-rw---- 1 root i2c 89, 2 Feb 16 04:02 /dev/i2c-2
Here is the list of I²C devices on a Raspberry Pi 3 B whose hardware I²C
bus has been enabled.
woopi@goldserver:~ $ ls -l /dev/i2c*
crw-rw---- 1 root i2c 89, 1 Feb 10 22:17 /dev/i2c-1
Even though this model has a 40 pin header and the hardware I²C bus for HAT identification is enabled, a device linked to the bus is not made available by the system.
Three software utilities are used below. There are i2cdetect
and ic2get which are contained in the package
i2c-tools. The first displays the address of the devices
connected to an I²C bus. The second can read the registers of an I²C slave.
Installing the package i2c-tools is very simple.
woopi@goldserver:~ $ sudo apt install -y i2c-tools
To make life easier, I added the default user on the Pi to the i2c group. Otherwise it will be necessary to obtain root privileges when executing any utility in that package. In other words, whenever i2cdetect and i2cget are invoked, it will be necessary to use the sudo prefix if the user is not part of the i2c group. Adding the default user is not complex at all.
woopi@goldserver:~ $ sudo adduser $USER i2c
Adding user `woopi' to group `i2c' ...
Adding user woopi to group i2c
Done.
However, you will need to restart the session (by logging out and then back in) to update the user permissions.
Installing the program eeprog that can write to and read
from EEPROM is a little more complex. The utility must be compiled from the
source code. In addition, several versions of eeprog are
available on the Web. The only ones that work are based on the "tear" fork of
eeprog developed by Kris Rusocki among which the version by Ján Sáreník on
GitHub.
woopi@goldserver:~ $ 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]
woopi@goldserver:~ $ unzip master.zip
...
woopi@goldserver:~ $ mv eeprog-master eeprog
woopi@goldserver:~ $ cd eeprog
woopi@goldserver:~/eeprog $ make
...
The problem with the original versions of eeprog is that in
writing they use too high a frequency. It has to be slowed down. The I²C
frequency of the AT24C32 EEPROM depends on the voltage. It may be
possible to save data to the EEPROM if running at 5 volts using the original version of
eeprog. The synchronization signal (SCL) of the EEPROM can reach
400 KHz. However, the memory is connected to 3.3 volts to be compatible
with Raspberry Pi GPIO that. The I²C operating frequency of the EEPROM decreases
rapidly when the voltage is reduced. I don't know the exact value of this
frequency at 3.3 volts, but at 2.7 volts the maximum frequency is reduced to
100 KHz.
Neither i2c-tools nor eeprog are needed for
normal operation of the clock and flash memory. We can therefore eliminate
everything later if desired. Here's how.
woopi@goldserver:~/some_dir/or_other $ cd ~
woopi@goldserver:~ $ rm eeprog-0.7.7_master.zip
woopi@goldserver:~ $ rm -r eeprog
woopi@goldserver:~ $ sudo apt purge i2c-tools -y
The connection of the module is easy since the connections are clearly labelled
on the board. At a minimum, it is necessary to connect four
pins from the latter to the corresponding pins of the Raspberry Pi GPIO
connector: the power and ground (VCC and GND) and the data and
synchronization signals (SDA and SCL) of the I²C bus.
At this point, I did not install a battery, for reasons explained later.

Initially, the I²C and the clock drivers can be
installed temporarily. Two commands are needed to carry out these two
tasks. Then, it is a simple matter to check that the devices have been
created.
woopi@goldserver:~ $ sudo dtparam i2c_arm=on
woopi@goldserver:~ $ sudo dtoverlay i2c-rtc ds3231
woopi@goldserver:~ $ ls -l /dev/i2c* /dev/rt*
crw-rw---- 1 root i2c 89, 1 Jun 21 20:00 /dev/i2c-1
lrwxrwxrwx 1 root root 4 Jun 21 20:01 /dev/rtc -> rtc0
crw------- 1 root root 253, 0 Jun 21 20:01 /dev/rtc0
The i2c-1 device (also called an I²C controller) was
created, as well as the rtc0 device which communicates with the
clock via the i2c-1 controller. The command
i2cdetect displays the addresses of the I²C devices connected to
the hardware bus.
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
Two devices were found. The first is flash memory (EEPROM) at address
0x57 and the second is the clock at address 0x68. The UU
displayed instead of the address 68 is an indication that a
driver is handling the device.
woopi@goldserver:~ $ sudo hwclock -v
hwclock from util-linux 2.33.1
System Time: 1592780697.147276
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(3, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2020/06/21 23:04:58
Hw clock time : 2020/06/21 23:04:58 = 1592780698 seconds since 1969
Time since last adjustment is 1592780698 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2020-06-21 20:04:57.641349-03:00
Clearly the hardware clock is working. It may be surprising to see that
the time is correct in the absence of a battery. The explanation is simple.
The operating system, or more precisely the component
systemd-timesync, obtains the current time from an SNTP
reference server on the Web when the Raspberry Pi starts. As soon as the
i2c-rtc module is installed, the system adjusts the hardware
clock.
Since everything works, the I²C real-time clock can be added to the system permanently
by adding the dtparam command to enable the I²C controller and the dtoverlay command
to load the real-time driver in the operating system configuration file.
woopi@goldserver:~ $ sudo nano /boot/config.txt
...
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# For access to I2C RTC and other I2C devices on hardware I2C bus (SDA on GPIO2, SCL on GPIO3)
dtoverlay=i2c-rtc,ds3231
...
It is not necessary to activate the I²C protocol with the raspi-config
utility. Previously, I said that we also had to modify the script that
adjusts the time of the hardware clock when the i2c-rtc module is
loaded. Here's how.
woopi@goldserver:~ $ sudo nano /lib/udev/hwclock-set
Normally the script does nothing, because its execution is stopped by the
initial test, at least in distributions using systemd including
Raspberry Pi OS. It is necessary to remove this test or to
disable it by adding leading "#" at the start of the lines which transform
them into comments.
#!/bin/sh
# Reset the System Clock to UTC if the hardware clock from which it
# was copied by the kernel was in localtime.
dev=$1
#if [ -e /run/systemd/system ] ; then
# exit 0
#fi
...
If you installed the clock as described in the previous section, you can immediately check that it is possible to write and read the AT24C32 EEPROM . Otherwise, the I²C bus is not yet enabled.
woopi@goldserver:~ $ i2cdetect -l
woopi@goldserver:~ $ ls /dev/i2*
ls: cannot access '/dev/i2*': No such file or directory
The temporary installation of the i2c1 module that implements the hardware I²C bus on GPIO pins 2 and 3 is very simple.
woopi@goldserver:~ $ sudo dtparam i2c_arm=on
woopi@goldserver:~ $ ls -l /dev/i2c*
crw-rw---- 1 root i2c 89, 1 Jun 21 20:52 /dev/i2c-1
If the addresses of the I²C devices connected to bus 1 are displayed when the bus is controlled by i2c1, at least two are observed.
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Address 0x57 is used by the AT24C32 EEPROM (in reality it is a default address that can be modified with some soldering). Address 0x68 is that of the hardware clock. Because only the I²C bus is activated and because there is no driver for the clock, i2detect shows the latter's address, 0x68 and not UU as in the previous section or below.
If the i2c-rtc module was installed rather than i2c1, then i2cdetect displays UU
instead of 0x68 indicating that the clock driver is loaded.
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Since the I²C bus is enabled and the address of the EEPROM is known, one can write a string in the memory and then read it to make sure that access is possible.
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-1 0x57 -r 0:29 -f
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 29 bytes from offset 0, Output file: <stdout>
Reading 29 bytes from 0x0
Lorem ipsum dolor si...
woopi@goldserver:~ $ echo "This is working!" | 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
.................
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-1 0x57 -r 0:18 -f
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 18 bytes from offset 0, Output file: <stdout>
Reading 18 bytes from 0x0
This is working!
Older Rapsberry Pi models have only one readily available I²C hardware bus; the exceptions are the Pi model 4 and the Compute module. If GPIO pin 2 or 3 is used for other purposes, a software I²C bus can be created with the module i2c-rtc-gpio to which the RTC can be connected using different GPIO pins.
woopi@goldserver:~ $ sudo dtoverlay -h i2c-rtc-gpio
Name: i2c-rtc-gpio
Info: Adds support for a number of I2C Real Time Clock devices
using the software i2c controller
Usage: dtoverlay=i2c-rtc-gpio,<param>=<val>
Params: abx80x Select one of the ABx80x family:
AB0801, AB0803, AB0804, AB0805,
AB1801, AB1803, AB1804, AB1805
ds1307 Select the DS1307 device
ds1339 Select the DS1339 device
ds3231 Select the DS3231 device
m41t62 Select the M41T62 device
mcp7940x Select the MCP7940x device
mcp7941x Select the MCP7941x device
pcf2127 Select the PCF2127 device
pcf2129 Select the PCF2129 device
pcf8523 Select the PCF8523 device
pcf8563 Select the PCF8563 device
rv3028 Select the Micro Crystal RV3028 device
addr Sets the address for the RTC. Note that the
device must be configured to use the specified
address.
trickle-diode-type Diode type for trickle charge - "standard" or
"schottky" (ABx80x only)
trickle-resistor-ohms Resistor value for trickle charge (DS1339,
ABx80x, RV3028)
wakeup-source Specify that the RTC can be used as a wakeup
source
backup-switchover-mode Backup power supply switch mode. Must be 0 for
off or 1 for Vdd < VBackup (RV3028 only)
i2c_gpio_sda GPIO used for I2C data (default "23")
i2c_gpio_scl GPIO used for I2C clock (default "24")
i2c_gpio_delay_us Clock delay in microseconds
(default "2" = ~100kHz)
As you can see, GPIO23 and GPIO24 will be used for the SDA and SCL signals respectively. If the i2c-rtc module had been added to the configuration file /boot/config.txt, it must be removed and the Pi must be restarted. If the module had been temporarily loaded, it can be removed with dtoverlay. As soon as you know there is no more device for the clock, you can install i2c-rtc-gpio.
woopi@goldserver:~ $ sudo dtoverlay -l
Overlays (in load order):
0: dtparam i2c_arm=on
woopi@goldserver:~ $ sudo dtoverlay -r 0
woopi@goldserver:~ $ ls /dev/rtc
ls: cannot access '/dev/rtc': No such file or directory
woopi@goldserver:~ $ sudo dtoverlay i2c-rtc-gpio ds3231
woopi@goldserver:~ $ woopi@goldserver:~ $ ls -l /dev/rt*
ls: cannot access '/dev/rt*': No such file or directory
Just as in Raspbian Buster the overlay could not be loaded at runtime, but at least
it was not necessary to reboot because of a segmentation fault. It can be loaded at boot time if the system configuration file is modified.
woopi@goldserver:~ $ sudo nano /boot/config.txt
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
...
# For access to I2C RTC and other I2C devices on software I2C bus (SDA on GPIO23, SCL on GPIO24 by default)
dtoverlay=i2c-rtc-gpio,ds3231
...
After a reboot, the software I²C bus and the clock device are installed correctly.
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c i2c-gpio-rtc@0 I2C adapter
woopi@goldserver:~ $ i2cdetect -y 3
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
woopi@goldserver:~ $ sudo hwclock -v
hwclock from util-linux 2.33.1
System Time: 1592785094.391213
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(3, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2020/06/22 00:18:15
Hw clock time : 2020/06/22 00:18:15 = 1592785095 seconds since 1969
Time since last adjustment is 1592785095 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2020-06-21 21:18:14.868625-03:00
If the i2c-rtc-gpio module has been installed as explained in the previous section, then you can communicate with flash memory at address 0x57 on device i2c-3. If the module has flash memory but no hardware clock, then add the i2c-gpio module instead.
woopi@goldserver:~ $ dtoverlay -h i2c-gpio
Name: i2c-gpio
Info: Adds support for software i2c controller on gpio pins
Usage: dtoverlay=i2c-gpio,<param>=<val>
Params: i2c_gpio_sda GPIO used for I2C data (default "23")
i2c_gpio_scl GPIO used for I2C clock (default "24")
i2c_gpio_delay_us Clock delay in microseconds
(default "2" = ~100kHz)
bus Set to a unique, non-zero value if wanting
multiple i2c-gpio busses. If set, will be used
as the preferred bus number (/dev/i2c-<n>). If
not set, the default value is 0, but the bus
number will be dynamically assigned - probably
3.
Perhaps not surprisingly, the i2c-rtc-gpio module could not be loaded at runtime.
woopi@goldserver:~ $ sudo dtoverlay i2c-gpio
* Failed to apply overlay '0_i2c-gpio' (kernel)
Even worse, the Pi would not boot if the configuration file was modified to load the overlay at boot time by inserting the following line.
# for access to I2C devices on software I2C bus (SDA on GPIO23, SCL on GPIO24 by default)
dtoverlay=i2c-gpio
woopi@goldserver:~ $ sudo reboot
[ 690.133676] reboot: Restarting system
The Pi would just hang at this point. I removed the SD card, inserted it into the destkop SD card reader and removed the offending dtoverlay=i2c-gpio line from the /boot/config.txt file with a text editor. It was then possible to boot the Pi again from the corrected SD card.
This problem has been fixed but not yet integrated into the distribution. Following the indications by PhilE, here is how to get around the problem.
woopi@goldserver:~ $ sudo mv /boot/overlays/i2c-gpio.dtbo /boot/overlays/i2c-gpio.dtbo-bad
woopi@goldserver:~ $ sudo wget https://github.com/raspberrypi/firmware/raw/master/boot/overlays/i2c-gpio.dtbo -O /boot/overlays/i2c-gpio.dtbo
--2020-06-22 04:37:58-- https://github.com/raspberrypi/firmware/raw/master/boot/overlays/i2c-gpio.dtbo
...
Length: 1055 (1.0K) [application/octet-stream]
...
woopi@goldserver:~ $ sudo dtoverlay i2c-gpio
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c ffffffff.i2c I2C adapter
woopi@goldserver:~ $ i2cdetect -y 3
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: -- -- -- -- -- -- -- --
As can be seen, the new overlay (which will be part of the 5.4 kernel) can be loaded at run-time without problem. The 0x68 address will not be shown if there is no I²C clock. The EEPROM can be accessed as before but the I²C bus must be adjusted; it is now i2c-3.
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-3 0x57 -r 0:29 -f
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-3, Address: 0x57, Mode: 16bit
Operation: read 29 bytes from offset 0, Output file: <stdout>
Reading 29 bytes from 0x0
Lorem ipsum dolor si...
woopi@goldserver:~ $ echo "* A new EEPROM *" | eeprog/eeprog -f -16 -w 0x00 -t 2 /dev/i2c-3 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-3, Address: 0x57, Mode: 16bit
Operation: write at offset 0, Input file: <stdin>
Write cycle time: 2 milliseconds
Writing <stdin> starting at address 0x0
.................
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-3 0x57 -r 0:18 -f
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-3, Address: 0x57, Mode: 16bit
Operation: read 18 bytes from offset 0, Output file: <stdout>
Reading 18 bytes from 0x0
* A new EEPROM *
it is possible to enable more than one I²C bus, even on the first models of the Raspberry Pi. As a first example, the hardware bus and the software bus described above will be enabled simultaneously. Here is the relevant part of the /boot/config.txt file that creates these two serial communication channels.
...
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# For access to I2C RTCand other I2C devices on hardware I2C bus (SDA on GPIO2, SCL on GPIO3)
dtoverlay=i2c-rtc,ds3231
# For access to I2C devices other than RTC on software i2c bus (SDA on GPIO23, SCL on GPIO24 by default)
dtoverlay=i2c-gpio
...

woopi@goldserver:~ $ ls /dev/i2c*
/dev/i2c-1 /dev/i2c-3
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c ffffffff.i2c I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
woopi@goldserver:~ $ i2cdetect -y 3
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: -- -- -- -- -- -- -- --
woopi@goldserver:~ $ sudo hwclock -v
hwclock from util-linux 2.33.1
System Time: 1580420342.707524
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Last drift adjustment done at 1580060171 seconds after 1969
Last calibration done at 1580060171 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(3, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2020/01/30 21:39:04
Hw clock time : 2020/01/30 21:39:04 = 1580420344 seconds since 1969
Time since last adjustment is 360173 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2020-01-30 17:39:03.151299-04:00
woopi@goldserver:~ $ echo "Hardware I2C bus" | 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
.................
woopi@goldserver:~ $ echo "Software I2C bus" | eeprog/eeprog -f -16 -w 0x00 -t 2 /dev/i2c-3 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-3, Address: 0x57, Mode: 16bit
Operation: write at offset 0, Input file: <stdin>
Write cycle time: 2 milliseconds
Writing <stdin> starting at address 0x0
.................
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-1 0x57 -r 0:18 -f
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 18 bytes from offset 0, Output file: <stdout>
Reading 18 bytes from 0x0
Hardware I2C bus
4woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-3 0x57 -r 0:18 -f
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-3, Address: 0x57, Mode: 16bit
Operation: read 18 bytes from offset 0, Output file: <stdout>
Reading 18 bytes from 0x0
Software I2C bus
It is not necessary to install the real-time clock on the hardware bus. With the following configuration, the clock on the software bus will be activated
...
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# For access to I2C RTC and other I2C devices on hardware I2C bus (SDA on GPIO2, SCL on GPIO3)
dtoverlay=i2c-rtc-gpio,ds3231
...
The usual commands can be issued after rebooting to confirm that the two RTC-EEPROM modules are available on the two I²C busses and that the RTC driver is using the real-time clock connected to the software bus.
woopi@goldserver:~ $ ls /dev/i2c*
/dev/i2c-1 /dev/i2c-3
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
woopi@goldserver:~ $ i2cdetect -y 3
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
On the Raspberry Pi 3 B, the i2c-rtc-gpio will create bus 3 or else the software controller will not be installed. To be more precise, if the overlays are in the following order in /boot/config.txt
dtoverlay=i2c-gpio,bus=3
dtoverlay=i2c-rtc-gpio,ds3231
then the RTC driver is loaded and it uses the software I²C controller on bus 3 and the i2c-gpio overlay cannot install the software I²C controller because of the bus number conflict.
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c i2c-gpio-rtc@0 I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
woopi@goldserver:~ $ dmesg | grep i2c
[ 2.944681] i2c /dev entries driver
[ 4.120751] gpio-23 (i2c-gpio-rtc@0): enforced open drain please flag it properly in DT/ACPI DSDT/board file
[ 4.120828] gpio-24 (i2c-gpio-rtc@0): enforced open drain please flag it properly in DT/ACPI DSDT/board file
[ 4.121708] i2c-gpio i2c-gpio-rtc@0: using lines 23 (SDA) and 24 (SCL)
[ 4.121946] i2c-gpio 3.i2c: error trying to get descriptor: -16
[ 4.121971] i2c-gpio: probe of 3.i2c failed with error -16
If the overlays are in the following order in /boot/config.txt
dtoverlay=i2c-rtc-gpio,ds3231
dtoverlay=i2c-gpio,bus=3
then the RTC driver is not loaded.
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c 3.i2c I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
woopi@goldserver:~ $ dmesg | grep i2c
[ 2.858077] i2c /dev entries driver
[ 4.054726] i2c-gpio 3.i2c: using lines 23 (SDA) and 24 (SCL)
[ 4.054966] i2c-gpio i2c-gpio-rtc@0: error trying to get descriptor: -16
[ 4.054990] i2c-gpio: probe of i2c-gpio-rtc@0 failed with error -16
Contrary to comments read on the forums, there does not seem to be any constraints on the I²C bus number or on the bus creation sequence.
...
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
dtoverlay=i2c-gpio,bus=6,i2c_gpio_sda=27,i2c_gpio_scl=22
# For access to I2C RTCand other I2C devices on hardware I2C bus (SDA on GPIO2, SCL on GPIO3)
dtoverlay=i2c-rtc,ds3231
# For access to I2C devices other than RTC on software i2c bus (SDA on GPIO23, SCL on GPIO24 by defa$
dtoverlay=i2c-gpio,bus
...
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c ffffffff.i2c I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
i2c-6 i2c 6.i2c I2C adapter
...
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# For access to I2C devices other than RTC on software i2c bus (SDA on GPIO23, SCL on GPIO24 by default)
dtoverlay=i2c-gpio
# For access to I2C RTCand other I2C devices on hardware I2C bus (SDA on GPIO2, SCL on GPIO3)
dtoverlay=i2c-rtc,ds3231
dtoverlay=i2c-gpio,bus=9,i2c_gpio_sda=27,i2c_gpio_scl=22
...
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c ffffffff.i2c I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
i2c-9 i2c 9.i2c I2C adapter
The only constraint is that there must not be any conflict in the bus number. It is even possible to create load software I²C controller on bus 1
if the hardware I²C bus is not enable.
...
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# for access to I2C devices on software I2C bus (SDA on GPIO23, SCL on GPIO24 by default)
dtoverlay=i2c-gpio
# Create software I2C bus 1
dtoverlay=i2c-gpio,bus=1,i2c_gpio_sda=27,i2c_gpio_scl=22
...
woopi@goldserver:~ $ i2cdetect -l
i2c-3 i2c ffffffff.i2c I2C adapter
i2c-1 i2c 1.i2c I2C adapter
Also it seems that bus 0 and 2 are reserved by the system.
I have neither a Compute Module nor a Raspberry Pi 4, so what I am about to say is not based on experience and it may therefore be completely wrong. It seems very clear that there are more than 2 hardware I²C buses on these devices. Look at the list of device tree overlays related to I²C that are available.
woopi@goldserver:~ $ dtoverlay -a | grep i2c
bmp085_i2c-sensor
i2c-bcm2708
i2c-gpio
i2c-mux
i2c-pwm-pca9685a
i2c-rtc
i2c-rtc-gpio
i2c-sensor
i2c0
i2c0-bcm2708
i2c1
i2c1-bcm2708
i2c3
i2c4
i2c5
i2c6
sc16is750-i2c
sc16is752-i2c
Most maps of the Raspberry Pi GPIO connector only show the default function of the I/O pins. Hardware buses 3 to 6, do not show up on those maps because they only appear as so called "alternate" functions of some I/O pins. One exception is the Raspberry Pi 4 Model B Default GPIO Pinout with PoE Header by Element 14 which as a well laid out yet compact map of the 6 alternate functions of all 30 I/O pins of the 40 pin GPIO header (the other 10 pins are power and ground connections). Unfortunately, the map is an image so a text search for say SDA3 can't be performed to find out on which pins it is available. There is another map on the Raspberry Pi Forums by clicky that clearly differentiates the additional I²C buses available on the Model 4 only. The authoritative source for mere mortals, may be the PDF document entitled BCM2711 ARM Peripherals Version 1, 5th February 2020, by Raspberry Pi (Trading) Ltd. Look at pages 98 to 100 of Section 5.3. Alternative Function Assignments of Chapter 5. General Purpose I/O (GPIO).
When looking at the documentation for some of these hardware I²C controllers, there was a mention of "combined transactions" which puzzled me.
woopi@goldserver:~ $ dtoverlay -h i2c0
Name: i2c0
Info: Change i2c0 pin usage. Not all pin combinations are usable on all
platforms - platforms other then Compute Modules can only use this
to disable transaction combining.
Usage: dtoverlay=i2c0,<param>=<val>
Params: pins_0_1 Use pins 0 and 1 (default)
pins_28_29 Use pins 28 and 29
pins_44_45 Use pins 44 and 45
pins_46_47 Use pins 46 and 47
combine Allow transactions to be combined (default
"yes")
The following reply by Phil Elwell (pelwell) to an issue entitled smbus read_i2c_block_data Fails on Latest Kernel #828
My theory is that the I2C device you are trying to control does not support repeated starts. If you find that everything springs into life with the old driver, try repeating your test after turning on the "combined" module parameter ...
makes me think that when transactions are not combined a block of bytes is sent one byte at a time with an address byte preceding each data byte. A combined transaction would have a single address byte preceding the block of data bytes. See also
Transaction format in the I²C page on
Wikipedia.
One thing that has become obvious from reading about I²C connexion problems especially with the alternate I²C buses is that care must be exercised with the termination of the SDA and SCL lines. This is not a problem with the module that is used here, One can plainly see the bank of pull-up resistors near the EEPROM chip. Howver, if a device without such pull-ups is being used, then it seems that the internal pull-ups of the Raspberry Pi may not be sufficient (i.e. may have too high a value to be able to pull the lines to 3.3 volts when neither the slave nor master is asserting the line low).
If the Raspberry Pi GPIO connector has 40 pins, there is a second hardware I²C bus which identifies expansion cards (HAT) using pins 27 (ID_SD) and 28 (ID_SC). In principle, this bus should not be used. There are many warnings about this. The Raspberry Foundation says it not once but twice in its instructions on designing expansion cards. In the paragraphs entitled GPIO Requirements and ID EEPROM there is the same passage:
Within the set of pins available on the GPIO header, ID_SC and ID_SD (GPIO0/SCL and GPIO1/SDA) are reserved for board detection / identification. The only allowed connections to the ID_ pins are an ID EEPROM plus 3.9K pull up resistors. Do not connect anything else to these pins!
The same warning is on the schematics of the various models. In a tutorial on the I²C protocol, Sparkfun adds "It's only there to talk to EEPROMs at addresses 0x50 during boot time. User access at runtime is problematic. If you want a general purpose I²C bus on the B +, you'll need to use I2C-1, on pins 3 and 5 of the 40-pin connector ”. However, the tutorial continues with the procedure for using the bus. It requires i2c_vc module that can be loaded with the dtparam utility. Before installing it, let's see the information that the utility displays about this module.
woopi@goldserver:~ $ sudo dtparam -h i2c_vc
i2c_vc Set to "on" to enable the i2c interface
usually reserved for the VideoCore processor
(default "off")
woopi@goldserver:~ $ sudo dtparam i2c_vc=on
woopi@goldserver:~ $ ls /dev/i2*
/dev/i2c-0
Since the device is in place, I took the chance to connect the clock module with flash memory to pins 27 (SDA) and 28 (SCL) of the second I²C bus (and also to ground and to 3.3 volts of course) taking care to turn off the power before proceeding. After that it was easy to verify that it was possible to use flash memory.
woopi@goldserver:~ $ 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: -- -- -- -- -- -- -- --
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-0 0x57 -r 0:29 -f
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 29 bytes from offset 0, Output file: <stdout>
Reading 29 bytes from 0x0
Lorem ipsum dolor si...
woopi@goldserver:~ $ 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
.................
woopi@goldserver:~ $ eeprog/eeprog -16 /dev/i2c-0 0x57 -r 0:18 -f
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 18 bytes from offset 0, Output file: <stdout>
Reading 18 bytes from 0x0
eeprom on i2c-0
There does not seem to be a module that supports the clock with this I²C bus. However, I was able to verify that it is possible to access the DS3231 chip with a Python script which is described in more detail in another post.
woopi@goldserver:~ $ ve rtcpy
(rtcpy) woopi@goldserver:~ $ ./rtc -i 0
-bash: ./rtc: No such file or directory
(rtcpy) woopi@goldserver:~ $ rtcpy/rtc -i 0
Sat Feb 22 20:53:42 2020
(rtcpy) woopi@goldserver:~ $ rtcpy/rtc -i 0 -u -s "2138-12-09 12:13:14"
(rtcpy) woopi@goldserver:~ $ rtcpy/rtc -i 0
Tue Dec 9 12:13:27 2138
To install a controller for this hardware I²C bus permanently, add a line in the configuration file.
woopi@goldserver:~ $ sudo nano /boot/config.txt
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
dtparam=i2c_vc=on
I have not tested the use of this bus with the other hardware I²C bus or other software buses, but I think it should work. That said, it is definitely not recommended and may not even be possible to use the i2c0 controller. As indicated at the end of the general help command of the dtparam utility, there could be a conflict with the Pi camera.
woopi@goldserver:~ $ sudo dtparam -h
...
N.B. It is recommended to only enable those interfaces that are needed.
Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc
interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.)
Similarly, it is very likely that there would be a conflict with any I²C device connected to this bus if it uses address 0x50.
Contrary to what I thought initially, there is support for an I²C clock on this hardware bus after all. Many thanks to
Jürgen Bellin who kindly provided information on this in June 17 email from which the following is quoted.
I²C bus 0 must be activated [in the /boot/config.txt file] with
dtparam=i2c_vc=on
or
dtparam=i2c0=on
Then an RTC can easily be connected to this bus by specifying an additional parameter to dtoverlay [again in the /boot/config.txt file]:
dtoverlay=i2c-rtc,ds3231,i2c0,addr=0x68
The trick is the
i2c0 parameter which selects the bus. I [Jürgen Bellin] must admit that I use a mcp79410 chip (which does a better job than
the Dallas-chips). But the idea should carry.
Almost at the same time, Seamus de Mora provided the same information in more detail in a new "recipe" entitled Move your Real-Time Clock (RTC) from channel I2C1 to I2C0 on his PiFormulae GitHub page.
Clearly I should revisit this whole topic and run tests with the newest Raspberry Pi OS, an RTC, flash memory and a Raspberry Pi Camera.
To ensure accuracy, the DS3231 chip protects against variations caused by temperature changes. Therefore, it incorporates a temperature sensor which can be accessed. The temperature of the chip is in registers 0x11 and 0x12 which can be read with the i2cget utility .
woopi@goldserver:~ $ i2cget -y 1 0x68 0x11
Error: Could not open file `/dev/i2c-1' or `/dev/i2c/1': No such file or directory
woopi@goldserver:~ $ i2cget -y 1 0x68 0x11
Error: Could not set address to 0x68: Device or resource busy
The problem is that the rtc0 device which owns ic2-1. The device module is named rtc_ds1307.
woopi@goldserver:~ $ lsmod | grep rtc
rtc_ds1307 24576 0
hwmon 16384 2 rtc_ds1307,raspberrypi_hwmon
Removing that module will give access to the DS3231 through I²C bus.
woopi@goldserver:~ $ sudo rmmod rtc_ds1307
woopi@goldserver:~ $ i2cget -y 1 0x68 0x11
0x14
woopi@goldserver:~ $ i2cget -y 1 0x68 0x12
0x40
Register 0x11 contains the integer part of the temperature in degrees Celsius, while the two most significant bits of register 0x12 contain the fractional part of the temperature in quarters of a degree Celsius. Now 0x40 = 01000000 of which the two most significant bits are 01. So the temperature is 20 + 1 * (1/4) = 20.25 °C which was reasonable.
The rtc_ds1307 module can be reinstalled and the clock will work again.
woopi@goldserver:~ $ sudo modprobe rtc_ds1307
woopi@goldserver:~ $ sudo hwclock -v
hwclock from util-linux 2.33.1
System Time: 1580085041.982210
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Last drift adjustment done at 1580060171 seconds after 1969
Last calibration done at 1580060171 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
ioctl(3, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2020/01/27 00:30:43
Hw clock time : 2020/01/27 00:30:43 = 1580085043 seconds since 1969
Time since last adjustment is 24872 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2020-01-26 20:30:42.444318-04:00
The module includes support for a button battery cell whose function is to keep the clock running when there's no power. There is a rather basic circuit to constantly charge the battery when power is supplied to the module. Initially the rechargeable LIR2032 was supplied with these modules. Unsurprisingly, the modules I got from two vendors lately didn't have batteries included. The new regulations regarding the transportation of lithium-ion batteries are much more severe so that sellers avoid shipping them.

There is an Arduino Forum discussion about the backup battery which begins in November 2014 and which remains active. Let me sum up this long debate.
- The LIR2032 is a rechargeable battery with a nominal voltage of 3.6 / 3.7 volts which must be charged at 4.2 volts.
- Some believe that the voltage will be too high if 5 volts supply the module. Others do clever calculations to conclude that the effective voltage after the diode and the resistor is close to 4.2 volts.
- There is no consensus on the true charging voltage when attempts are made to measure it.
- Some believe that the charging circuit will do nothing if the module is powered at 3.3 volts
- A Li-ion battery at its maximum admissible voltage (4.2 volts for the LIR2032) must not be charged. "It is important to note that Li-Ion cells will not tolerate trickle charging at all after they are fully charged. If current is continuously forced into a fully charged Li-Ion cell (even a very minute current) the cell will be damaged. For this reason, Li-Ion cells are charged using constant voltage (CV) chargers, and not constant current (CC) chargers". (Texas Instruments Characteristics of Rechargeable Batteries).
For these reasons, at least one dealer removes the 200 ohm resistor to deactivate the circuit and recommends the use of a non-rechargeable CR2032 lithium battery. Since it is difficult to find the LIR2032 locally at a reasonable price and since I highly doubt the efficacy of the circuit to charge the battery when the module is supplied at 3.3 volts, I followed the dealer lead with the modules in my possession.