Activate Real Time Clock on Zynthian v5.1 kit with ORAM-2504.1

Hi,

After a lot of trying, searching, reading etc. I finally managed to get the real time clock operational on my Zynthian v5.1 kit.

In hindsight it’s pretty simple, but it took me a while to find out.

The problem with the Raspberry Pi 5 it that it contains an onboard RTC. The kernel always addresses the onboard clock as /dev/rtc0 (there seems te be no way around this). The RTC on the Zynthian main board (the RV-3018, that is powered by the CR2032 battery) is addressed as /dev/rtc1.

On startup the system time is synchronized using the onboard RTC (rtc0). But that has no battery backup so after a power down it defaults to 1970.
There is a connector for a battery on the RPi board, but that is not accessible as it is completely covered by the large thermal block.

So, we have a clock that is used by the kernel but without a battery, and a clock that is battery powered (and operational in oram-2504.1) that is not used by the kernel.

A solution is to sync the system time/date with rtc1 on startup, but only when no network is available. That way, when the Zynthian is running stand-alone (it is a musical instrument), it still has the right date/time so if you record something the file date/time is correct.

This can be done by adding a few lines to /etc/rc.local.

But first check if everything is correctly set up:

  1. Check if the main board clock is recognized and a driver is active:
 (venv) root@zynthian:~# i2cdetect -y 1
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:                         -- -- -- -- -- -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 20: 20 21 -- -- -- -- -- -- -- -- -- -- -- -- -- --
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- UU -- -- UU -- --
 50: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
 60: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- -- --

If position 52 shows UU everything is ok. Otherwise check /boot/firmware/config.txt if dtoverlay=i2c-rtc,rv3028 is set.

  1. Check if the rtc1 clock has the right time:
  (venv) root@zynthian:~# hwclock -r -f /dev/rtc1
  2025-05-28 20:24:11.693684+02:00

Now add the following to /etc/rc.local:

# Check for an IP address
_IP=$(hostname -I) || true

if [ "$_IP" ]; then
    # Network is up, update rtc1 (on the main board) to reflect the system time.
    printf "\nSetting RTC1 to system time\n"
    /sbin/hwclock -wu -f /dev/rtc1
else
    # No network available, use rtc1 (on the main board) to set the system time
    printf "\nUsing RTC1 to set system time\n"
    /sbin/hwclock -s -f /dev/rtc1
fi

After a reboot the system now always runs with the correct time.

If everything works, you can remove the fake-hwclock but some people claim that it’s better to keep that in place.

It took some puzzling to find this solution, so I hope it saves others some time.

Kind regards,

Hans.

ps. Don’t forget the battery :wink:

Hi @HansR !!

Thanks for focusing on this subject. I would like to fix it in the next stable release.
Do you think this could be a better way?

https://unix.stackexchange.com/questions/246605/how-can-the-link-target-of-dev-rtc-be-changed

Regards,

I just created this udev rule file:

root@zynthian:/etc/udev/rules.d# cat 99-rtc1.rules 
KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="rtc-rv3028 1-0052", SYMLINK="rtc", MODE="0666"

After restarting the system, the /dev/rtc soft link is changed to point to /dev/rtc1.

Regards,

1 Like

I don’t know.

There are a lot of references to this topic, most are giving problems sooner or later.

The problem is that rtc0 is hard coded in the kernel and it pops up at unexpected moments. The only way to change that is to recompile the kernel. And that is a route I’d rather not follow.

The solutions in the link are rather obscure. As a developer I would vote against it. It looks very hacky and unmaintainable.

The solution in the startup script may be low tech, but it is simple and understandable. At my age that is important :wink:

For how long?

And does that work if the kernel addresses rtc0 in stead of rtc?

Forever. It’s changed and kept like this on every boot, while “/dev/rtc1” does exist and it’s the chip from the zynthian’s V5 mainboard. We could release the last condition, but i considered is OK like this. We want to target the RTC clock from the V5 mainboard and anything else.

Probably not, but let’s try and see how it work. I couldn’t find harcoded references to “/dev/rtc0” in the kernel source and if this link (/dev/rtc) does exist it’s for a reason. Perhaps it’s not the kernel but the hwclock tool that uses by default the /dev/rtc0.

Anyway, if this does not work, we could swap the device names using udev rules too :wink:

Regards,

1 Like

If it can be solved with one (or two) udev rules then that would be very elegant. I’ll look into it later.

Hi @jofemodo

It’s far simpler than we thought.

No need to mess around with udev rules, no startup scripts.

Add:

 dtparam=rtc=off

to /boot/firmware/config.txt and your done.

Now Linux enumerates the rv3028 as rtc0 and uses that as default clock:

May 29 18:48:57 zynthian kernel: rtc-rv3028 1-0052: registered as rtc0
May 29 18:48:57 zynthian kernel: rtc-rv3028 1-0052: setting system clock to 2025-05-29T16:48:56 UTC (1748537336)

Problem solved I think?

Kind regards,

Hans.

2 Likes

OK! I buy this solution :wink:
It’s already implemented in oram (staging) & vangelis (testing) branches.

Thanks a lot!

1 Like

:scream:
Now you disable the Pi5 internal RTC for all V5? So a DIY Zynthian will have no RTC if the V5.1 RTC is not built and the internal RTC had been used intentionally?
I see there is still the problem with upside-down touch on an HDMI screen if Wiring Layout is set to V5 in order to make the homebuilt LED keypad light up correctly.
I have still this hack in my zynthian_custom_config.sh that checks the multitouch.py for the invert functionality and patches it if necessary, to overcome this problem and still not overwrite multitouch.py on every reboot:

#!/bin/bash
grep 'self._invert_x = invert_x_axis' /zynthian/zynthian-ui/zyngui/multitouch.py && sed -i 's/self._invert_x = invert_x_axis/self._invert_x = False/;s/self._invert_y = invert_y_axis/self._invert_y = False/' /zynthian/zynthian-ui/zyngui/multitouch.py

Will it now be necesary to add another hack to protect the config.txt from the RTC disabling via dtparam?
Where will your new code place the dtparam? at the very end of config.txt, so that there is no chance to overwrite it with a Custom Boot Command

dtparam=rtc=on

Anyway, this command is not specified and could be useless.

We are disabling the Pi5 RTC when the Kit V5 is selected (detected), aka, you have a V5 mainboard with the RV3028 soldered on.

If you have a DIY zynthian, this is not a Kit V5 and you have to select “custom Kit” and configure your hardware by hand.

Regards,

2 Likes

Thank you for clarifying this. :heart:
I’ve seen if the commit it will depend on if [[ ( $ZYNTHIAN_KIT_VERSION == "V5"* ) || ( $ZYNTHIAN_KIT_VERSION == "Z2"* ) ]]; then

It would be nice if zynthian_gui.py in line 168 check for the Kit instead of the Wiring Layout to invert the touch. :upside_down_face:

Then there would be a chance to have a V5-style LED keypad in a DIY without rotated touch problem.

Done! Now this depends only of DISPLAY_ROTATION variable that can be configured from display config panel (webconf). This is pushed to Oram (staging) and vangelis (testing).

Regards,

3 Likes