Posts: 32
Joined: Sat Mar 14, 2015 11:18 am
Location: South Yorkshire, England

Writing system date/time to I2C RTC

Sun Jan 01, 2017 7:03 pm

Within my C program, the user needs to change the system date and time. It cannot be done in the shell in this instance as the user will not have access to a terminal command line.

(for info, within my program I change the system time to that as wanted by the user by setting the time values in struct timeval tv and to then set the RPi (3) internal system date/time I call settimeofday(&tv, 0); This works fine and the RPI system date and time alter correctly.)

I need to save this system time to the attached I2C hardware RTC so that on reboot (when there is no internet access) the RPI can get the new date and time from the attached RTC. To do this I use the system() func: system("sudo hwclock -w"); to emulate a command from a terminal.

This works fine and will set the system date into the RTC and on reboot, if there is no internet access, the RTC is initially read. It works every time.

However, the problem I have is this:
If I access an attached i2c DAC module (in C using bcm2835 lib funcs, eg bcm2835_i2c_begin() bcm2835_i2c_setSlaveAddress(); bcm2835_i2c_set_baudrate(); bcm2835_i2c_write() ) you cannot then read or write to the hardware RTC in either the C code or even on a command line.

If you did a sudo hwclock -r, which is to read the RTC clock using the RPi driver, it will now hang the RPi for many minutes. Eventually it will read the clock and display the value. If you then repeat the command, it will display immediately. It is as though the hwclock driver gets stuck but once it has cleared itself it will work fine.

If I do not make any attempt to access the i2c DAC all RTC accesses (using sudo hwclock -r) will always work fine everytime, but it will stop working the moment I do one simple access to the DAC to output a value (which incidentally works OK)

Additionally, if I was to change the i2c i/o pins (SDA = GPIO P3, SCL = GPIO P5), to standard GPIO and then back again as inputs this will also stop the sudo hwclock -r.

My question is:
Once the i2c i/o has been touched by either another call to another i2c device or by accessing either pin, is there a method to 'reset' the 'built-in' RPi hwclock driver back to its initial and working state so that it can be used again without it hanging the RPi for up to 10 mins.

Has anyone come across this problem and know of a fix or any pointers?

I have tried this on different sets of new hardware and the problem remains the same and it is perfectly repeatable. All works fine up until there is another i2c access to another device or if the i2c GPIO pins are accessed.

In the RTC setup, I followed the supplier and forum instructions (eg using dtoverlay=i2c-rtc,ds1307, etc) and the RTC works fine every time and brings in the relevant clock driver which then uses address 0x68 (which is the RTC i2c address) and it will display a UU at that address (when using a probe, sudo i2cdetect -y 1), which shows a device is attached to it and probing was skipped because that device has its own (RPi) driver.

Return to “C/C++”