Tuesday, 24 January 2017

Adding a DS3231 Real Time Clock to UDOO NEO/QUAD

Its well know that the in-built RTC on the imx6 processor isn't the best in terms of battery life (performance).  Using an external RTC provides better battery life and fortunately the process isn't too complicated implement. The DS3231 is a popular RTC especially with the RPI community given ease of integration (via I2C) and accuracy. There's a few variations of the DS3231 for the RPI and the one I using is the one below which can be easily sourced.


In the image I have highlighted the pin out to simplify wiring. I'm going to take the UDOO NEO as a example and use I2C4 (alternatively you can use I2C2). For I2C4 wire SDA to pin 35 and SCL to pin 34 on header J5, 3.3v and GND are available on J7. On power up you can verify the DS3231 is visible by executing:

udooneo:~# i2cdetect 3

which should return the DS3231 at address 0x68.

WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-3.
I will probe address range 0x03-0x77.
Continue? [Y/n] Y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- UU --
20: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

                        
Next step is to enable kernel support by enabling the Dallas/Maxim DS1307 driver as below.


Build the kernel and modules (this is important). Lastly we need add the DS3231 to the device tree to I2C4, below is an example,

diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
index abbf0d8..2ffa6cb 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
@@ -298,6 +298,11 @@
                compatible = "fsl,fxas2100x";
                reg = <0x20>;
        };
+
+       rtc@68 {
+               compatible = "dallas,ds1307";
+               reg = <0x68>;
+       };
 };


Rebuild the relevant dtb file depending on your set-up. Deploy the newly generated kernel, modules and dtb to the NEO.

On power up the kernel output should include the following lines ( try dmesg | grep ds1307)

[    8.095963] rtc-ds1307 3-0068: rtc core: registered ds1307 as rtc0
[    8.095989] rtc-ds1307 3-0068: 56 bytes nvram


If all is ok we can query the clock for it current time by using the hwclock utility:

udooneo:~# hwclock -r
Tue 24 Jan 2017 12:32:25 PM UTC  -0.858087 seconds


We can sync with the ntp time:

udooneo:~# hwclock -s

On reboots the RTC time may become corrupt with the udooubuntu release to overcome this ntp service needs to be disabled with the following commands:

echo manual | sudo tee /etc/init/ntp.override
timedatectl set-ntp false

The timedatectl command is extremely useful as it provides a complete picture of the system and rtc times. For example to sync RTC with system time:

udooneo:~# timedatectl
      Local time: Fri 2016-01-01 01:18:06 UTC
  Universal time: Fri 2016-01-01 01:18:06 UTC
        RTC time: Tue 2017-01-24 12:40:36
        Timezone: Etc/UTC (UTC, +0000)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a
udooneo:~# hwclock -s
udooneo:~# timedatectl
      Local time: Tue 2017-01-24 12:42:03 UTC
  Universal time: Tue 2017-01-24 12:42:03 UTC
        RTC time: Tue 2017-01-24 12:42:03
        Timezone: Etc/UTC (UTC, +0000)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a


No comments:

Post a Comment