I believe, the issue is that there is no driver module for DS-xxxx in:
/usr/lib/modules/–your-kernel-version–/kernel/drivers/rtc
I checked Debian Buster images, there’s no even “rtc” folder.
DietPi (Bullseye version) has a lot of modules in that folder, maybe copying one of them could work (if the module is just a port to i2c-tools).
Otherwise, if you manage to get i2c-tools to detect your DSxxxx module, the solution could be just to write a bash script, which reads the rtc-chip data via i2cget and then sets the system time via sudo date --set …
Try:
i2cdump -y 1 0x68
Where: -y means “answer yes”, 1 means number of i2c line (try 0 or 1), 0x68 is the address of common rtc-chips.
If i2cdump outputs changing data, you’re half way there - it means, you can read the time! Then it’s just about reading the right bytes via i2cget and shuffling them around
Anyway… I’ve ordered a bunch of DS1307 modules, when they arrive I’ll try to play with them and make a couple of bash-scripts to get/set the data.
UPDATE:
Found this implementation in Python for Raspberry Pi:
github(dot)com / switchdoclabs / RTC_SDL_DS1307
(See the test.py file)
It does exactly what I mean, just in python. I will try it on Rock Pi S.
Then, you can just setup a cron job, which runs a Python script every 6 hours to sync the clock.
Not exactly a driver, but can get the job done.
UPDATE 2:
Found this script on EEVBlog forums:
- The script is here: eevblog (dot) com /forum/testgear/hacking-the-dso2x1x/350/
- (Edited out, because it was for kernel-mode)
The guy at EEVBlog used the script as custom service, in kernel mode (we don’t need to dig so deep).
UPDATE 3 - working bash script
This script was tested on a fresh Debian Buster install, kernel version 4.4.143-69.
The chip was DS1307, should work on other chips with the same memory structure.
Step 1: Add I2C overlay to /boot/uEnv.txt
Example:
overlays=rk3308-uart0 rk3308-i2c1
Step 2: Install i2c-tools
apt-get install i2c-tools
Step 3: Use this script whenever you need to sync the time - add it to the cron, if you want.
#!/bin/bash
I2C_ADDR="68"
RTC_REG="0x00"
I2C_GET="i2cget -y 1 0x$I2C_ADDR"
I2C_SET="i2cset -y 1 0x$I2C_ADDR"
I2C_DETECT="i2cdetect -y 1 0x$I2C_ADDR 0x$I2C_ADDR"
DATE_CHECK="^[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) ([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$";
MYNAMEIS="$(basename $0)"
read_rtc () {
NEW=""; for NN in {0..6}; do NEW="$NEW $($I2C_GET $(($RTC_REG + $NN)) b)"; done
NEW="$(echo $NEW | awk '{printf "20%02X-%02X-%02X %02X:%02X:%02X", $7, $6, $5, $3, $2, $1}')"
echo "RTC time data: $NEW"
if [[ $NEW =~ $DATE_CHECK ]]; then
echo "Setting system time, please wait (10 sec.) ..."
timedatectl set-ntp 0
sleep 5
timedatectl set-time "$NEW"
if [ $? -ne 0 ]; then echo "FAILED: timedatectl (Setting too often?)"; fi
sleep 5
timedatectl set-ntp 1
echo "Finished."
else
echo "RTC time is not correct. (Maybe battery replaced?)"
echo "Try resetting RTC first by running: $MYNAMEIS reset-rtc"
echo "Nothing changed."
fi
}
write_rtc () {
NEW="$(date +'0x%02S 0x%02M 0x%02H 0x%02u 0x%02d 0x%02m 0x%02y')"
echo "Sending data to RTC: $NEW"
echo " sec. min. hour wkday day mnth year"
$I2C_SET $RTC_REG $NEW i
if [ $? -ne 0 ]; then echo "FAILED: i2cset (Some epic fail?)"; fi
echo "Giving it a sec, then reading back ..."
sleep 1
NEW=""; for NN in {0..6}; do NEW="$NEW $($I2C_GET $(($RTC_REG + $NN)) b)"; done
NEW="$(echo $NEW | awk '{printf "20%02X-%02X-%02X %02X:%02X:%02X", $7, $6, $5, $3, $2, $1}')"
echo "RTC time data: $NEW"
}
if [ -z "$($I2C_DETECT | grep " $I2C_ADDR ")" ]; then
echo "RTC not detected, exiting."
exit 1
fi
if [[ $# -gt 0 ]]; then
if [ $1 == 'reset-rtc' ]; then
echo "Resetting RTC with current system time ..."
write_rtc
exit 0
fi
fi
if [ -z "$(timedatectl status | sed -n 's/.*System clock synchronized[^a-zA-Z]*\(yes\).*/\1/Ip')" ]; then
echo "NTP time is NOT syncronised, getting RTC-time ..."
read_rtc
else
echo "NTP time is syncronised, overwriting RTC-time ..."
write_rtc
fi