FreeBSD doesn't read RTC on boot

I am using external I2C RTC module (DS3231) with armv7 Orange Pi Zero board (which doesn't have RTC onboard, hardware is there but there is no RTC battery socket). Module is recognized and works (after patching device tree):

Code:
root@arm2:~ # sysctl dev.ds3231
dev.ds3231.0.32khz_enable: 1
dev.ds3231.0.sqw_mode: interrupt
dev.ds3231.0.sqw_freq: 1024
dev.ds3231.0.bbsqw: 0
dev.ds3231.0.temp_conv: 0
dev.ds3231.0.temperature: 30.0C
dev.ds3231.0.%parent: iicbus0
dev.ds3231.0.%pnpinfo: name=ds3231@68 compat=maxim,ds3231
dev.ds3231.0.%location: addr=0xd0
dev.ds3231.0.%driver: ds3231
dev.ds3231.0.%desc: Maxim DS3231 RTC
dev.ds3231.%parent:

Setting date works - system will have correct date until power is disconnected. After power is connected again, system time is not read from RTC.

After powercycle:
Code:
root@arm2:~ # date
Fri Jan  1 00:22:25 UTC 2010
root@arm2:~ # ./ds1307 -a 0x68 -r
09:37:59 12/08/2020

NTP is not used. ds1307 program is used to directly read registers from I2C module.
 
Current idea is that kernel uses onboard rtc (which doesn't have battery) and then external i2c module.
Code:
 dmesg | grep registered
FreeBSD is a registered trademark of The FreeBSD Foundation.
rtc0: registered as a time-of-day clock, resolution 1.000000s
ds32310: registered as a time-of-day clock, resolution 1.000000s

Disabling internal rtc (via device tree overlay) results in kernel panic & hang:
Code:
---<<BOOT>>---                                                                                                                                                                                
Copyright (c) 1992-2019 The FreeBSD Project.                                                                                                                                                  
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994                                                                                                                      
        The Regents of the University of California. All rights reserved.                                                                                                                     
FreeBSD is a registered trademark of The FreeBSD Foundation.                                                                                                                                  
FreeBSD 12.1-RELEASE r354233 GENERIC arm                                                                                                                                                      
FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)                                                                                                             
VT: init without driver.                                                                                                                                                                      
module_register: cannot register ofwbus/pcib from kernel; already loaded from kernel                                                                                                          
Module ofwbus/pcib failed to register: 17                                                      
module_register: cannot register simplebus/pcib from kernel; already loaded from kernel
Module simplebus/pcib failed to register: 17
CPU: ARM Cortex-A7 r0p5 (ECO: 0x00000000)
CPU Features:        
  Multiprocessing, Thumb2, Security, Virtualization, Generic Timer, VMSAv7,
  PXN, LPAE, Coherent Walk                                                                     
Optional instructions:                      
  SDIV/UDIV, UMULL, SMULL, SIMD(ext)
LoUU:2 LoC:3 LoUIS:2                                                                           
Cache level 1:                   
 32KB/64B 4-way data cache WB Read-Alloc Write-Alloc
 32KB/32B 2-way instruction cache Read-Alloc
Cache level 2:                                                                                 
 512KB/64B 8-way unified cache WB Read-Alloc Write-Alloc
real memory  = 536289280 (511 MB)        
avail memory = 509890560 (486 MB)
No PSCI/SMCCC call function found   
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
random: unblocking device.              
random: entropy device external interface
kbd0 at kbdmux0                                                                                
ofwbus0: <Open Firmware Device Tree> 
ofw_clkbus0: <OFW clocks bus> on ofwbus0
clk_fixed0: <Fixed clock> on ofw_clkbus0
clk_fixed1: <Fixed clock> on ofw_clkbus0
simplebus0: <Flattened device tree simple bus> on ofwbus0
regfix0: <Fixed Regulator> on ofwbus0
regfix1: <Fixed Regulator> on ofwbus0
regfix2: <Fixed Regulator> on ofwbus0
regfix3: <Fixed Regulator> on ofwbus0
ccu_h3ng0: <Allwinner H3/H5 Clock Control Unit NG> mem 0x1c20000-0x1c203ff on simplebus0
ccu_h3ng0: Clock apb2 have unknown parent: osc32k
ccu_h3ng0: Clock ahb1 have unknown parent: osc32k
ccu_h3ng0: Clock cpux have unknown parent: osc32k
panic: cannot finalize clkdom initialization

cpuid = 0
time = 1
Uptime: 1s
Automatic reboot in 15 seconds - press a key on the console to abort
Rebooting...
Reset: watchdog device has not been initialized
Reset failed!

Is it possible to tell kernel to use external RTC instead of internal?
 
I am using external I2C RTC module (DS3231) with armv7 Orange Pi Zero board (which doesn't have RTC onboard, hardware is there but there is no RTC battery socket). Module is recognized and works (after patching device tree):

Code:
root@arm2:~ # sysctl dev.ds3231
dev.ds3231.0.32khz_enable: 1
dev.ds3231.0.sqw_mode: interrupt
dev.ds3231.0.sqw_freq: 1024
dev.ds3231.0.bbsqw: 0
dev.ds3231.0.temp_conv: 0
dev.ds3231.0.temperature: 30.0C
dev.ds3231.0.%parent: iicbus0
dev.ds3231.0.%pnpinfo: name=ds3231@68 compat=maxim,ds3231
dev.ds3231.0.%location: addr=0xd0
dev.ds3231.0.%driver: ds3231
dev.ds3231.0.%desc: Maxim DS3231 RTC
dev.ds3231.%parent:

Setting date works - system will have correct date until power is disconnected. After power is connected again, system time is not read from RTC.

After powercycle:
Code:
root@arm2:~ # date
Fri Jan  1 00:22:25 UTC 2010
root@arm2:~ # ./ds1307 -a 0x68 -r
09:37:59 12/08/2020

NTP is not used. ds1307 program is used to directly read registers from I2C module.
Have you enabled i2c0 in efi.config.txt?
What was your dtc command?
 
Quite probably you need to compile a custom kernel with the aw_rtc device removed:
Code:
...
nodevice        aw_rtc            # Allwinner On-chip RTC
...
 
Have you enabled i2c0 in efi.config.txt?
What was your dtc command?
Do I need that file if I am not using EFI for booting?

DT files for enabling i2c0 (on which module is connected) and DS3231 module:
Code:
/dts-v1/;
/plugin/;

/ {
        compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2-plus";

        fragment@0 {
                target-path = "/aliases";
                __overlay__ {
                        i2c0 = "/soc/i2c@01c2ac00";
                };
        };

        fragment@1 {
                target = <&i2c0>;
                __overlay__ {
                        status = "okay";
                };
        };
};
Code:
/dts-v1/;
/plugin/;

/ {
        compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2-plus";

        fragment@0 {
                target = <&i2c0>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

                        ds3231: ds3231@68 {
                                                compatible = "maxim,ds3231";
                                                reg = <0x68>;
                                                status = "okay";
                        };
                };
        };

        __overrides__ {
                ds3231 = <&ds3231>,"status";
        };
};

Files are compiled with:
Code:
dtc -I dts -O dtb -@ -o /boot/dtb/overlays/ds3231.dtbo /opt/dtb/ds3231.dts
dtc -I dts -O dtb -@ -o /boot/dtb/overlays/sun8i-h3-i2c0.dtbo /opt/dtb/sun8i-h3-i2c0.dts

They are enabled in /boot/loader.conf:
Code:
fdt_overlays="sun8i-h3-sid.dtbo,sun8i-h3-ths.dtbo,sun8i-h3-i2c0.dtbo,sun8i-h3-i2c1.dtbo,ds3231.dtbo"

and loaded during boot:
Code:
/boot/dtb/overlays/sun8i-h3-i2c0.dtbo size=0x180                                                                                                                                             
/boot/dtb/overlays/sun8i-h3-i2c1.dtbo size=0x1a6                                                                                                                                            
/boot/dtb/overlays/ds3231.dtbo size=0x361                                                                                                                                                    
/boot/dtb/overlays/flash.dtbo size=0x284                                                                                                                                                     
Kernel entry at 0x55000180...
...

Quite probably you need to compile a custom kernel with the aw_rtc device removed:
Code:
...
nodevice        aw_rtc            # Allwinner On-chip RTC
...

Did not try that before, assumption was that driver is not active if there is not device tree to activate that driver.
Anyway, tried it now, -CURRENT kernel compiled on that board (not cross compile):
Code:
% cat usr/src/sys/arm/conf/MYKERNEL
include GENERIC
ident   MYKERNEL

nodevice        aw_rtc            # Allwinner On-chip RTC

Device tree overlay for disabling internal RTC is not enabled and after connecting serial console and booting that kernel:
Code:
...
simplebus0: <Flattened device tree simple bus> on ofwbus0                                                                                                                                     
regfix0: <Fixed Regulator> on ofwbus0                                                                                                                                                         
regfix1: <Fixed Regulator> on ofwbus0                                                                                                                                                         
regfix2: <Fixed Regulator> on ofwbus0                                                                                                                                                         
regfix3: <Fixed Regulator> on ofwbus0                                                                                                                                                         
ccu_h3ng0: <Allwinner H3/H5 Clock Control Unit NG> mem 0x1c20000-0x1c203ff on simplebus0
ccu_h3ng0: Clock apb2 have unknown parent: osc32k
ccu_h3ng0: Clock ahb1 have unknown parent: osc32k
ccu_h3ng0: Clock cpux have unknown parent: osc32k
panic: cannot finalize clkdom initialization
                      
cpuid = 0                                                                                                                                                                                     
time = 1  
KDB: stack backtrace:                                                                                                                                                                         
db_trace_self() at db_trace_self                                                                                                                                                              
         pc = 0xc0578934  lr = 0xc0079eb0 (db_trace_self_wrapper+0x30)                                                                                                                        
         sp = 0xc0d14b98  fp = 0xc0d14cb0                                                                                                                                                     
db_trace_self_wrapper() at db_trace_self_wrapper+0x30                                                                                                                                         
         pc = 0xc0079eb0  lr = 0xc02bf54c (vpanic+0x174)                                                                                                                                      
         sp = 0xc0d14cb8  fp = 0xc0d14cd8                                                                                                                                                     
         r4 = 0x00000100  r5 = 0xc0a42b20                                                                                                                                                     
         r6 = 0xc06a0af6  r7 = 0x00000000                                                                                                                                                     
vpanic() at vpanic+0x174                                                                                                                                                                      
         pc = 0xc02bf54c  lr = 0xc02bf308 (doadump)                                                                                                                                           
         sp = 0xc0d14ce0  fp = 0xc0d14ce4                                                                                                                                                     
         r4 = 0x000008c0  r5 = 0xd02f9800                                                                                                                                                     
         r6 = 0x00000071  r7 = 0xc0d14d18                                                                                                                                                     
         r8 = 0xc0d14d08  r9 = 0x00000001                                                                                                                                                     
        r10 = 0x00000000                                                                                                                                                                      
doadump() at doadump                                                                                                                                                                          
         pc = 0xc02bf308  lr = 0xc05be870 (aw_ccung_write_4)                                                                                                                                  
         sp = 0xc0d14cec  fp = 0xc0d14d50                                                                                                                                                     
         r4 = 0x00000000  r5 = 0xc0d14ce4                                                                                                                                                     
         r6 = 0xc02bf308 r10 = 0xc0d14cec                                                                                                                                                     
aw_ccung_write_4() at aw_ccung_write_4                                                                                                                                                        
         pc = 0xc05be870  lr = 0xc02fc1b8 (device_attach+0x50c)                                                                                                                               
         sp = 0xc0d14d58  fp = 0xc0d14da0                                                                                                                                                     
         r4 = 0x00000000  r5 = 0xc0ae30a4                                                                                                                                                     
         r6 = 0x80040001 r10 = 0x80000803                                                                                                                                                     
device_attach() at device_attach+0x50c                                                                                                                                                        
         pc = 0xc02fc1b8  lr = 0xc02fbc10 (device_probe_and_attach+0x8c)                                                                                                                      
         sp = 0xc0d14da8  fp = 0xc0d14dc0                                                                                                                                                     
         r4 = 0xd00de400  r5 = 0xc2471f80                                                                                                                                                     
         r6 = 0x5e4a6f28  r7 = 0x00000000                                                                                                                                                     
         r8 = 0xc0a615a8  r9 = 0xc0a615ac                                                                                                                                                     
        r10 = 0xc0a4278c                                                                                                                                                                      
device_probe_and_attach() at device_probe_and_attach+0x8c                                                                                                                                     
         pc = 0xc02fbc10  lr = 0xc02fdf5c (bus_generic_new_pass+0xb0)                                                                                                                         
         sp = 0xc0d14dc8  fp = 0xc0d14de0                                                                                                                                                     
         r4 = 0xd00de400  r5 = 0xc0848ef8                                                                                                                                                     
         r6 = 0xc088cba0 r10 = 0xc0a4278c                                                                                                                                                     
bus_generic_new_pass() at bus_generic_new_pass+0xb0                                                                                                                                           
         pc = 0xc02fdf5c  lr = 0xc02fdfa8 (bus_generic_new_pass+0xfc)                                                                                                                         
         sp = 0xc0d14de8  fp = 0xc0d14e00                                                                                                                                                     
         r4 = 0xd00df980  r5 = 0xc0848ef8                                                                                                                                                     
         r6 = 0xd00e0000  r7 = 0x00000000                                                                                                                                                     
         r8 = 0xc0a615a8 r10 = 0xc0a4278c 
bus_generic_new_pass() at bus_generic_new_pass+0xfc                                                                                                                                           
         pc = 0xc02fdfa8  lr = 0xc02fdfa8 (bus_generic_new_pass+0xfc)                                                                                                                         
         sp = 0xc0d14e08  fp = 0xc0d14e20                                                                                                                                                     
         r4 = 0xd00dfc00  r5 = 0xc0848ef8                                                                                                                                                     
         r6 = 0xd00e0000  r7 = 0x00000000                                                                                                                                                     
         r8 = 0xc0a615a8 r10 = 0xc0a4278c                                                                                                                                                     
bus_generic_new_pass() at bus_generic_new_pass+0xfc                                                                                                                                           
         pc = 0xc02fdfa8  lr = 0xc02fdfa8 (bus_generic_new_pass+0xfc)                                                                                                                         
         sp = 0xc0d14e28  fp = 0xc0d14e40                                                                                                                                                     
         r4 = 0xd00dfc80  r5 = 0xc0848ef8                                                                                                                                                     
         r6 = 0xd00e0000  r7 = 0x00000000                                                                                                                                                     
         r8 = 0xc0a615a8 r10 = 0xc0a4278c                                                                                                                                                     
bus_generic_new_pass() at bus_generic_new_pass+0xfc                                                                                                                                           
         pc = 0xc02fdfa8  lr = 0xc02f9490 (bus_set_pass+0x54)                                                                                                                                 
         sp = 0xc0d14e48  fp = 0xc0d14e60                                                                                                                                                     
         r4 = 0xd00e78a0  r5 = 0xc0848ef8                                                                                                                                                     
         r6 = 0xd00e0000  r7 = 0xc0a615a8                                                                                                                                                     
         r8 = 0x7fffffff r10 = 0xc0a4278c                                                                                                                                                     
bus_set_pass() at bus_set_pass+0x54                                                                                                                                                           
         pc = 0xc02f9490  lr = 0xc0255904 (mi_startup+0x2a4)                                                                                                                                  
         sp = 0xc0d14e68  fp = 0xc0d14e90                                                                                                                                                     
         r4 = 0xc08a48b4  r5 = 0xc0a42788
         r6 = 0x00800001  r7 = 0x00000000
         r8 = 0x03800000  r9 = 0xc0a42794
mi_startup() at mi_startup+0x2a4
         pc = 0xc0255904  lr = 0xc00002c4 (_start+0x144)
         sp = 0xc0d14e98  fp = 0x00000000
         r4 = 0xc00003f8  r5 = 0xc0b1c000
         r6 = 0x00000000  r7 = 0x00c52078
         r8 = 0xc0cdd000  r9 = 0x5af1e780
        r10 = 0x00000000
_start() at _start+0x144
         pc = 0xc00002c4  lr = 0xc00002c4 (_start+0x144)
         sp = 0xc0d14e98  fp = 0x00000000
KDB: enter: panic
[ thread pid 0 tid 100000 ]
Stopped at      kdb_enter+0x58: ldrb    r15, [r15, r15, ror r15]!
 
Do I need that file if I am not using EFI for booting?

Sorry, I don't know the Orange Pi but I was assuming if it uses the term "Pi" it's emulating/copying the boot of the Raspberry Pi. My mistake.

If you're saying that the ds1307 program is reading that address correctly on the i2c then I have to suspect it's your RTC.

Is the battery up to voltage? What's the name of the breakout with the DS3231 on it?
 
Last edited:
...
Did not try that before, assumption was that driver is not active if there is not device tree to activate that driver.
Anyway, tried it now, -CURRENT kernel compiled on that board (not cross compile):
Code:
% cat usr/src/sys/arm/conf/MYKERNEL
include GENERIC
ident   MYKERNEL

nodevice        aw_rtc            # Allwinner On-chip RTC

Device tree overlay for disabling internal RTC is not enabled and after connecting serial console and booting that kernel:
Code:
...
ccu_h3ng0: <Allwinner H3/H5 Clock Control Unit NG> mem 0x1c20000-0x1c203ff on simplebus0
ccu_h3ng0: Clock apb2 have unknown parent: osc32k
ccu_h3ng0: Clock ahb1 have unknown parent: osc32k
ccu_h3ng0: Clock cpux have unknown parent: osc32k
panic: cannot finalize clkdom initialization
...

Well, I see now, that there are more than one Allwinner RTC drivers in the kernel sources, and man /usr/src/share/man/man4/man4.arm/aw_rtc.4 is not the driver for <Allwinner H3/H5 Clock Control Unit NG> chips, but for different devices, and now I see that removing this driver from the kernel would of course make no difference, it wasn’t used anyway - sorry for the fake news.

The driver for the ccu_h3ng device is not mentioned in the kernel configuration file. Instead it is referred to here:
/usr/src/sys/arm/allwinner/h3/files.h3

The actual source of the driver is here:
/usr/src/sys/arm/allwinner/clkng/ccu_h3.c

Emanual Vadot (manu) seems to be (have/had) working on all this AW RTCs. He is quite active on the ARM mailing list - https://lists.freebsd.org/mailman/listinfo/freebsd-arm

Perhaps it might be worth to remove the entry of clkng/ccu_h3.c from h3/files.h3 and then try building the kernel once again. In parallel, you want to describe your issue on said mailing list, and probably receive a quick hint or even solution from Emanuel.

Note, I have the DS3231 module running on a Beaglebone Black, and there it simply does its job. I had only an issue with a time offset of 20 h upon restart, but this has been resolved very quickly thanks to Ian Lepore.

 
Reporting back:
Asked on mail list
Workaround can be running userland program which reads RTC early in the boot procedure and sets system time:

Apply device tree overlays from post #6 in this thread

ds3231.sh
Code:
#!/bin/sh

OUTPUT=$(/opt/ds1307 -a 0x68 -r)

DATE=$(echo $OUTPUT | awk '{print $2}')
TIME=$(echo $OUTPUT | awk '{print $1}')

YEAR=$(echo $DATE | cut -d '/' -f 3)
MONTH=$(echo $DATE | cut -d '/' -f 2)
DAY=$(echo $DATE | cut -d '/' -f 1)

HOUR=$(echo $TIME | cut -d ':' -f 1)
MIN=$(echo $TIME | cut -d ':' -f 2)
SEC=$(echo $TIME | cut -d ':' -f 3)

echo "----------------------------------------------------------------------"
echo "Current system time: $(date)"
echo "Current I2C time: $OUTPUT"

date $YEAR$MONTH$DAY$HOUR$MIN.$SEC

echo "----------------------------------------------------------------------"
echo "New system time: $(date)"

C program which reads time:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dev/iicbus/iic.h>
#include <time.h>

#define READ 1
#define WRITE 0


static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }


void usage ( char *pname )  {
  
  printf( "Usage: %s -r [-a <addr>] [-f <iic-dev>]\n", pname );
  printf( "       %s -s [-a <addr>] [-f <iic-dev>]\n", pname );
  exit(1);
}


char i2c_read ( int fd, uint16_t slave, uint8_t offset, uint8_t *buf )  {

  struct iic_msg msg[2];
  struct iic_rdwr_data rdwr;

  msg[0].slave = slave << 1 | !IIC_M_RD;
  msg[0].flags = !IIC_M_RD;
  msg[0].len = sizeof( uint8_t );
  msg[0].buf = &offset;

  msg[1].slave = slave << 1 | IIC_M_RD;
  msg[1].flags = IIC_M_RD;
  msg[1].len = sizeof( uint8_t );
  msg[1].buf = buf;

  rdwr.msgs = msg;
  rdwr.nmsgs = 2;

  if ( ioctl(fd, I2CRDWR, &rdwr) < 0 )  {
    perror("I2CRDWR");
    return(-1);
  }
  
  return(0);
}


char i2c_write ( int fd, uint16_t slave, uint8_t offset, uint8_t val )  {

  uint8_t buf[2];
  struct iic_msg msg;
  struct iic_rdwr_data rdwr;

  buf[0] = offset;
  buf[1] = val;
  msg.slave = slave << 1 | !IIC_M_RD;
  msg.flags = !IIC_M_RD;
  msg.len = 2*sizeof( uint8_t );
  msg.buf = buf;

  rdwr.msgs = &msg;
  rdwr.nmsgs = 1;

  if ( ioctl(fd, I2CRDWR, &rdwr) < 0 )  {
    perror("I2CRDWR");
    return(-1);
  }
  
  return(0);
}


int main ( int argc, char *argv[] )  {

  int i, ch, fd, fl;
  int ss, mm, hh, wd, d, m, y;
  char dev[] = "/dev/iic0";
  uint8_t buf;
  uint16_t slave = 0x68;
  time_t tloc;
  struct tm *ptm;


  if ( argc == 1 )  usage(argv[0]);

  while ( (ch = getopt(argc, argv, "hrsa:f:")) != -1 )  {
    switch (ch)  {
      case 'r': fl = READ;
                break;
      case 's': fl = WRITE;
                break;
      case 'a': sscanf( optarg, "%hX", &slave );
                break;
      case 'f': strcpy( dev, optarg );
                break;
      case 'h':
      default:  usage(argv[0]);
    }
  }
  
  if ( (fd = open(dev, O_RDWR)) < 0 )  {
    perror("open");
    exit(-1);
  }

  if ( fl == WRITE )  {

    tloc = time( &tloc );
    ptm = localtime( &tloc );

    i2c_write( fd, slave, 0, bin2bcd(ptm->tm_sec) );
    i2c_write( fd, slave, 1, bin2bcd(ptm->tm_min) );
    i2c_write( fd, slave, 2, bin2bcd(ptm->tm_hour) );
    i2c_write( fd, slave, 3, bin2bcd(ptm->tm_wday+1) );
    i2c_write( fd, slave, 4, bin2bcd(ptm->tm_mday) );
    i2c_write( fd, slave, 5, bin2bcd(ptm->tm_mon+1) );
    i2c_write( fd, slave, 6, bin2bcd(ptm->tm_year-100) );

    exit(0);
  }

  if ( fl == READ )  {

    i2c_read( fd, slave, 0, &buf );
    ss = bcd2bin(buf & 0x7F);

    i2c_read( fd, slave, 1, &buf );
    mm = bcd2bin(buf & 0x7F);

    i2c_read( fd, slave, 2, &buf );
    hh = bcd2bin(buf & 0x3F);

    i2c_read( fd, slave, 3, &buf );
    wd = bcd2bin((buf & 0x07) - 1);

    i2c_read( fd, slave, 4, &buf );
    d = bcd2bin(buf & 0x3F);

    i2c_read( fd, slave, 5, &buf );
    m = bcd2bin(buf & 0x1F);

    i2c_read( fd, slave, 6, &buf );
    y = 2000 + bcd2bin(buf);

    printf("%.2d:%.2d:%.2d %.2d/%.2d/%.4d\n", hh, mm, ss, d, m, y );
    
    exit(0);
  }

  exit(0);

}

Compile it on ARM board with:
Code:
cc ds1307.c -o /opt/ds1307

And then run it early in boot procedure - put "/opt/ds3231.sh" somewhere in /etc/rc file. Forget correct line, didn't make backup and SD card is repurposed but it was working reliably :)
All this fuss could be avoided if Orange Pi Zero board creators routed out battery connector for internal RTC
 
Greetings All,

I had the same problem. I bought an RTC board from ABElectronics in the UK:

https://www.abelectronics.co.uk/

They claimed to have tested their RTC with ALL Orange Pi's. However, mine didn't work.

They then admitted they did not actually run it on a OPZ2. So, they bought one and helped me configure it.

THis is the correspondence from Andrew @ ABEelectronics:

==========================================================================================================================================================================

The Orange Pi Zero 2 arrived this morning and I have managed to get the RTC Pi working on the board using Debian Linux. I can see why you have problems using “orangepi-config” as it appears to be missing a lot of sections found on the other Orange Pi models.

These are the steps I used to get the RTC Pi working.

I started with a fresh install of Debian 4.9.170 from Orange Pi’s website at

https://drive.google.com/drive/folders/1Xk7b1jOMg-rftowFLExynLg0CyuQ7kCM

First, I updated the firmware on the Orange Pi.

sudo orangepi-config

Select System / Firmware / Yes to “Do you want to update board firmware?

Reboot linux.

Next I ran sudo apt update and sudo apt upgrade

i2c-tools is not installed by default so I installed that next.

sudo apt install i2c-tools

According to the manual the I2C bus on the GPIO pins is i2c3 so I tried running i2c-detect.

sudo i2cdetect -y 3

It came back with the following results showing the RTC Pi on address 0x68.

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --


It appears that on a clean install of Debian the i2c bus is enabled by default. To check if the RTC was working I used the i2cdump tool to read the contents of the RTC memory.

sudo i2cdump -y 3 0x68 i

This what it returned.

0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 12 15 07 05 15 06 13 03 00 00 00 00 00 00 00 00 ????????........
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
40: 12 15 07 05 15 06 13 03 00 00 00 00 00 00 00 00 ????????........
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
80: 12 15 07 05 15 06 13 03 00 00 00 00 00 00 00 00 ????????........
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 12 15 07 05 15 06 13 03 00 00 00 00 00 00 00 00 ????????........
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................


The numbers at the first two addresses which hold the seconds and minutes changed each time I ran the command which means the RTC was running.

If you want to use the RTC Pi with your own applications, for example in a python script, you should be ready with the steps I used above as this will give you direct access to the RTC hardware through the I2C bus. If you want to use the RTC as a hardware clock that Linux can use to keep time when the network is disconnected there are a few extra steps.

It took a while to find out how to enable the RTC Pi as a hardware clock but I eventually found it in the official Orange Pi Zero 2 user manual on the Orange Pi website

https://drive.google.com/drive/folders/1ToDjWZQptABxfiRwaeYW1WzQILM5iwpb

On page 172 it give instructions on using the DS1307 RTC module which is used on the RTC Pi.

You need to create a dts overlay which is used to load the RTC module. Create a new file called i2c-ds1307.dts

sudo nano i2c-ds1307.dts

In the file paste the following:

/dts-v1/;
/plugin/;
/{
compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
fragment@1 {
target = <&i2c3>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
ds1307@68 {
compatible = "dallas,ds1307";
reg = <0x68>;
status = "okay";
};
};
};
};

Save the file and run the following command to install the overlay

sudo orangepi-add-overlay i2c-ds1307.dts

Edit /boot/orangepiEnv.txt and add the following two lines

overlays=i2c3
user_overlays=i2c-ds1307


My /boot/orangepiEnv.txt file looks like this:

verbosity=1
console=both
disp_mode=1080p60
fb0_width=1920
fb0_height=1080
debug_uart=ttyS0
rootdev=UUID=c310ed9a-2899-4a7b-80c6-efe4d6118443
rootfstype=ext4
overlays=i2c3
user_overlays=i2c-ds1307
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u


Save and reboot

Once rebooted you can check if the RTC is being used as the hardware clock by running the following command.

sudo hwclock -r -f /dev/rtc1

It should return the current date and time: 2023-06-16 11:56:39.445141+00:00

Hopefully you can use the steps above to get the RTC Pi working on your Orange Pi. If you are currently getting UU instead of 68 when you run i2cdetect that could mean the ds-1307 module is being loaded at boot. Check the /boot/orangepiEnv.txt file to see if it contains "user_overlays=i2c-ds1307". If it does, removing this and rebooting should allow the RTC Pi to appear in i2cdetect as 0x68 again.

If you have any problems after going through the steps above, please let me know. If you have a spare SD card it may be worth setting up a clean install of Debian to test with to check that the RTC Pi is working correctly.

Best regards

Andrew

==============================================================================================================================================================================

Hi George

On my Orange Pi Zero 2 it has the same issue as yours where after a reboot it changes the RTC Pi to RTC0.

After a bit of searching around various forums and tutorials I found a solution that should work to make the RTC Pi the default hardware clock.

Edit /etc/rc.local

Add the following line:

hwclock --hctosys -f /dev/rtc0

Save the file and reboot. Try running the "date" command.

Hopefully it should show the correct date from the RTC Pi.

To set the time on the RTC Pi you can use the following command.

sudo hwclock --set --date '2023-06-28 13:23:00' -f /dev/rtc0

You will need to either reboot or run " sudo hwclock -s --hctosys -f /dev/rtc0" to copy the date from the RTC Pi to linux.

Hopefully this will work on your Orange Pi. If you have any problems please let me know.

Best regards

Andrew


IMG_2657.jpeg
 
Back
Top