RockPi 4B external RTC


Marko Buršič
 Share

1 1

Recommended Posts

I have compiled  Armbian buster with Linux 5.4.32-rockchip64 with additional option in RTC clock and enabled DS1307. Everything is fine, the board can communicate with DS1307, but I am unable to use this /dev/rtc1 as the main hwclock instead on /dev/rtc (it points at /dev/rtc0 which is built in RTC). I have read many forums on Raspberry, this forum but it doesn work. I did:

 

https://forum.armbian.com/topic/5346-rtc-ds1307-i2c-for-tinkerboard/

 

1) Add "echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-7/new_device" to /etc/rc.local, above the "exit 0" line at the bottom
2) In   /lib/udev/hwclock-set comment out the lines below 

if [ -e /run/systemd/system ]; then 
    exit 0
fi 
if [ -e /run/udev/hwclock-set ]; then
exit 0
fi

then change the HCTOSYS_DEVICE=rtc0 line to be HCTOSYS_DEVICE=rtc1

 

3) In /lib/udev/rules.d/50-udev-default.rules change the SUBSYSTEM=="rtc" line to:
SUBSYSTEM=="rtc", KERNEL=="rtc1", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
4) In your hwclock udev rule make sure you have (/lib/udev/rules.d/85-hwclock.rules):

KERNEL=="rtc1", RUN+="/lib/udev/hwclock-set $root/$name"

 

When the board starts the system time is taken from rtc0 (default value year 2013,...) then loads drivers for DS1307 and links it to rtc1. Is there any clean tutroial for Linux, Debian,...Armbian on how to make this simple feature to work correctly.

 

It has to:

-at startup: read from rtc1 (battery backed) and sync to system 

-if at any time the clock is set by means of ntp it has to adjust the rtc1

 

I think that this is all it has to do, but it does all others than that.

 

 

 

Link to post
Share on other sites

Armbian is a community driven open source project. Do you like to contribute your code?

As you are rebuilding the kernel anyway, set the DS1307 option to "build in" (y) and the onboard RTC option to "module" (m). This way the DS1307 gets  initialized as early as possible (rtc0) and the onbord RTC is still available as rtc1 if the module is loaded. No further modification for rootfs is required.

Link to post
Share on other sites

12 hours ago, usual user said:

As you are rebuilding the kernel anyway, set the DS1307 option to "build in" (y) and the onboard RTC option to "module" (m). This way the DS1307 gets  initialized as early as possible (rtc0) and the onbord RTC is still available as rtc1 if the module is loaded. No further modification for rootfs is required.

 

@Marko Buršič
And if this works for you, contribute back that know-how is not lost https://docs.armbian.com/Process_Contribute/

Link to post
Share on other sites

Well, tried as you said, but unfortunately it doesn't work.  

 

root@rockpi-4b:~# dmesg | grep rtc
[   55.118141] hctosys: unable to open rtc device (rtc0)
[   55.345382] rk808-rtc rk808-rtc: registered as rtc0
[   56.365297] [drm] Cannot find any crtc or sizes
[   57.377581] [drm] Cannot find any crtc or sizes

You can see that rk808-rtc is still registered as rtc0 and ds1307 isn't registered at all.
 

 

1st - how to tell the compiler that my DS-1307 has an address of 68 and it is connected to I2c-7 ?

2nd - how to enable I2C-7 in compiler without device tree overlay?

3rd - how to tell the compiler that DS-1307 is the rtc0?

Link to post
Share on other sites

I did a new overlay

 

nano /boot/dtb-5.4.33-rockchip64/rockchip/overlay/ds1307.dts

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3399";
    
    fragment@0 {
        target = <&i2c7>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            ds1307@68 {
                compatible = "dallas,ds1307";
                reg = <0x68>;
                status = "okay";
            };
        };
    };
};

Compile the overlay:

 

 dtc -O dtb -I dts -o rockchip-ds1307.dtbo ds1307.dts

edit the armbianEnv.txt:

 

nano /boot/armbianEnv.txt


Add the overlay, store and exit:

 

overlays=i2c7 ds1307
 

Result:

 dmesg | grep rtc
[   54.358163] rtc-ds1307 7-0068: registered as rtc0
[   55.518913] rtc-ds1307 7-0068: setting system clock to 2020-04-20T12:58:31 UTC (1587387511)
[   55.759178] rk808-rtc rk808-rtc: registered as rtc1
[   57.790975] [drm] Cannot find any crtc or sizes
[   58.822993] [drm] Cannot find any crtc or sizes


 

 

Link to post
Share on other sites

After some tests I have found out that this works OK with a kernel that has the ds1307 enabled as default in .config . Currently 5.4.44-rockchip64 has this rtc enabled by default (it is back again, thankfully) and it compiled as module, rk808 is compiled as device. When using above mentined .dtbo the system recognises the ds1307 at boot and then it links as /dev/rtc0, so no kernel built from trunk is needed anymore. 

Link to post
Share on other sites

A RTC driver that is created as a module can be loaded late in the startup process and the user area has been running for some time. If you want the system time to be correct from the beginning, you want to set up the battery-powered RTC as early as possible. If the driver is build-in the rtc is available before userspace starts.
If you have multiple rtc, the module initialization order is not guaranteed. It may change depending on hardware timing between boots. Having the battery-powered RTC driver as only build-in prevents this. Unfortunately, the mainline kernel does not have a framework to prioritize rtcs.
If you can tolerate some time jumps during boot or possibly changing the rtc hardware, using modules only is a valid solution.

Link to post
Share on other sites

Hi,

I found myself in a similar situation, (on OrangePi Zero, but method described here should also apply here) where my I2C based DS3231 was detected last (rtc1) and the SoC's RTC detected first (rtc0). Looks like all kernel and userspace processes & tools use first detected RTC only (11 minute sync), timedatectl, ntp[sec]d. Tried some udev rules to rename the devices based on their DEVPATH, but this did not work. I also did not want to start renaming device nodes or do some symbolic link cooking to get it to work.

 

What did work (for my OrangePi Zero): Add an overlay where the SoC's RTC is aliased to rtc1 and the I2C based one is aliased as rtc0:

 

/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 I2C0 on H2+ (TWI0 on PA11 + PA12)
         * 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@1c2ac00/ds3231@68";
                };
        };

        fragment@1 {
                target = <&i2c0>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ds3231@68 {
                                compatible = "dallas,ds3232";
                                reg = <0x68>;
                                status = "okay";
                        };
                };
        };

        fragment@2 {
                target-path = "/aliases";
                __overlay__ {
                        rtc1 = "/soc/rtc@1f00000";
                };
        };

        fragment@3 {
                target = <&rtc>;
                __overlay__ {
                        rtc@1f00000 {
                                status = "disabled";
                        };
                };
        };
};

 

The SoC's RTC location should be matched to your SoC in fragments 2 and 3 (or remove fragmet 3 altogether).

Also, the 'compatible' line should be modified to match your SoC's/board's DT as well.

 

The overlay is based on the one available here. Modified the ds1307 to ds3232 after reading this post. Added the fragments 2 and 3 to alias the SoC's RTC to rtc1, the 'disable' part is not working.

 

Hope this helps for you as well:

Groetjes,

Edited by djurny
modified comments in the overlay to remove confusion
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

1 1