time-y wimey... stuff

it's more like a big ball of wibbly wobbly... time-y wimey... stuff

In which we get a Dallas Semiconductor real time clock (RTC) working on the Beagle Bone Black over the I2C bus under Arch Linux Arm.

The Beagle Bone Black has a real time clock (RTC from now on); however, the RTC does not have a battery to allow it to maintain the time when the board is powered off.  This will generally not pose a problem if your board is always connected to the Internet over the wired interface, but may be a stumbling block otherwise.  Luckily for you, it is easy enough to add a RTC.

Arch Linux Arm has the I2C bus enabled by default, and Arch Linux Arm has the driver for the DS1307 compiled into the kernel as can be seen below in the screenshot of the config file.  This may not be absolutely critical but should prevent any timing issues others have experienced when loading kernel modules at boot.

One great thing about the DS1307 driver is that the driver actually works with several different RTCs.  The below screenshot shows the RTCs listed in the driver source.  This tutorial uses the ChronoDot based on the DS3231; however, you should be able to use any listed.

More information on the ChronoDot can be found at [1], and it was purchased from [2].  It is essentially a break out board for the DS3231, an extremely accurate real time clock.

Connecting the ChronoDot to the Beagle Bone Black requires just four wires.  All you need to do is connect GND, Vcc, SCL, and SDA.  By default you can find all the pins needed on expansion header P9.

GND    pin 1 or 2
Vcc      pin 3 or 4
SCL      pin 19 (I2C2)
SDA     pin 20 (I2C2)

You will want to use the I2C2 bus as I2C1 is used by the board itself.

Power off your board and connect the corresponding pins on the ChronoDot to the pins on the Beagle Bone Black as listed above.  You can safely ignore the other pins on the ChronoDot as they are not needed for adding a RTC to the Beagle Bone Black.

Power on the Beagle Bone Black and you are almost done.

Optional
If you would like to verify that your Beagle Bone Black can see the ChronoDot, you can install the I2C-tools package with
pacman -S i2c-tools
Once installed, you can issue the following command
i2cdetect –y –r  1
This will scan I2C bus 1 (bus 1 in software corresponds to I2C2 on the hardware) for connected devices.  If you have connected the ChronoDot correctly, you should see an entry for 68 as in the image below.  68 is the bus address of the DS3231.  If you do not see a 68, verify your connections and/or the location of the I2C2 bus pins as they can be changed in software.


 

In order to register the new I2C RTC, you need to issue the command

echo ds3231 0x68 >/sys/bus/i2c/devices/i2c-1/new_device

After this you should see an entry for /dev/rtc1 as well as /sys/class/rtc/rtc1 – both point to the same device.

To verify you have the right rtc, check the name with

cat /sys/class/rtc/rtc1/name

and to check the time

cat /sys/class/rtc/rtc1/time

Most likely the time is wrong, and you should correct it before proceeding.  The easiest way to do this is to update the system time using ntpd and then synchronize the RTC.

If ntpd is running, you can either wait for it to eventually update the system time or stop it and force an update with

systemctl stop ntpd
ntpd –dqg

Once the system time is correct, synchronize the RTC with

hwclock -f /dev/rtc1 –w

Notice we are specifying the hwclock to use in the command above.

Now that the RTC has been set to the correct time, we can use it at boot to set our system time.

The first thing you need to do is create a script to recreate the I2C RTC device at boot and synchronize the system clock with it.  Once that is done, you can configure the system to run the script at boot.

Create the script with

nano /usr/lib/systemd/scripts/rtc

and type or copy and paste the following into the script

#!/bin/bash
echo ds3231 0x68 >/sys/bus/i2c/devices/i2c-1/new_device
hwclock -f /dev/rtc1 –s

As promised, this will recreate the I2C RTC and synchronize the system clock to it.

Next you will need to make the script executable with

chmod 755 /usr/lib/systemd/scripts/rtc

Now to make it run at boot.

Create the systemd file with

nano /etc/systemd/system/rtc.service

and type or copy and paste the following into the script

[Unit]
Description=RTC clock
Before=netctl-auto@wlan0.service
[Type]
Type=oneshot

[Service]
ExecStart=/usr/lib/systemd/scripts/rtc

[Install]
WantedBy=multi-user.target

Test it out by issuing

systemctl start rtc

If you receive no errors, you can enable this to run at boot with

systemctl enable rtc

Otherwise review the error messages to determine the issue.

You might have noticed the line Before=netctl-auto@wlan0.service in the systemd file. This instructs systemd  to bring up the RTC before starting the wireless LAN adapter.  This should prevent any wpasupplicant issues concerning timestamp validation.

You should now have a working battery backed RTC on your Beagle Bone Black.

[1] docs.macetech.com/doku.php/chronodot_v2.0
[2] www.evilmadscientist.com

Comments (8) -

Hi,

thank you very much for the clean and very understandable instructions how to
set up the DS3231 with the beaglebone black.
Unfortunately I  got a strange error with my beaglebone black when connecting the
ChronoDot v21 to it.
I use the LCD7 cape (A2) together with the beaglebone black (hdmi and emmc disabled as recommended).
The LCD7 uses PIN19/PIN20 as follows:
pin 19 (44e1084c): gpio_keys.12 (GPIO UNCLAIMED) function pinmux_bone_lcd7_cape_keys_00A2_pins group pinmux_bone_lcd7_cape_keys_00A2_pins
pin 20 (44e10850): rstctl.3 (GPIO UNCLAIMED) function pinmux_rstctl_pins group pinmux_rstctl_pins

What happens is:
Everything works as described above (for now I left off the scripting part, I want to
solve the problems first. I am using Gentoo). When I insert the battery into the RTC,
the beaglebone hangs in the boot process (kernel does not start).
Since a RTC without a battery is like no RTC......;)

Is there a way to use the ChronoDot with the Beaglebone Black?
What can I do to make the Beaglebone Black boot WITH a powered RTC?

Thank you very much in advance for any help!
Best regards,
mcc

Reply

Hi mcc,

Unfortunately I do not have the LCD7 cape to test with and do not use Gentoo, but let's see if we can walk through some troubleshooting steps.

First, if you connect just the ChronoDot to the BeagleBone Black with HDMI enabled, does the Black boot?  If not, verify the battery is installed properly and the connections are correct.  If the battery is installed correctly and the connections are correct, try switching out the wires you used for connecting the ChronoDot to the Black in case one has a short.  If it still does not work, it is likely your ChronoDot is damaged.

If the above worked, then it is a good bet the ChronoDot is working.  The next thing I would do is install Arch Linux Arm to an SD card and try the steps from the article.  If the board boots properly, then there is something in the way the Gentoo boot process discovers devices that is hanging, and I would check with the Gentoo folks.

Finally, if the above didn't work, I would look into whether or not you need to populate the resistors on the ChronoDot or re-enable them on the Black.  I2C requires pullup resistors from SDA and SCL to VCC.  The ChronoDot has locations for resistors to be soldered in if need.  They have been left off by default as many buses already have them, but disabling HDMI might be disabling the pull-up resistors.

I hope the above helps.  Please let me know how you resolve the issue when you are up and running.

Cheers,
Matthew

Reply

Will this procedure and hardware work with Angstrom?

Reply

Ken,

This should work with Angstrom; however, if you need to install i2c-tools, you will need to use Angstrom's package manager instead of pacman.  I believe this is opkg.  Other than that, you should be good to go.  If you run into any difficulties, post back.



Reply

If the BBB already has a RTC, why not only add a battery to the BBB?
Adding a separate RTC adds costs ($15) and uses pins/space.
(Probably because the full board gets powered and not only RTC?)

Reply

DaanP,

The problem with simply adding a battery to the BBB is that the software does not support placing the BBB into a low power state that keeps the RTC powered.  When you turn off the BBB either by issuing the shutdown command from the OS or using the power button, it powers off everything.  This has been confirmed here https://groups.google.com/forum/#!topic/beagleboard/vnu8sC9fgYo

While the external RTC used here does use several I/O pins, it is on the I2C bus.  If you have other I2C devices, those devices can share the same pins and you have not lost anything.

As to the price, it does seem a bit remarkable given the cost of the BBB, but that probably has to do with economies of scale.  At the end of the day you have to decide if you need an RTC and how accurate it needs to be.  Other options like fake-hwclock (https://github.com/xanmanning/alarm-fake-hwclock) might be a better fit for your use case/budget.

Reply

Thank you for your reply Lemoneer.
If I read the reply by 'Gerald' it will indeed not work, but due to software: "So. add the battery and you will see that the RTC function, does not work. You will need to add that support to the SW". I'm probably not able to figure that out myself (guessing if it was 'that' easy people would already done it, right?).
Also thank you for the fake-hwclock tip, that will come in handy.

Reply

thanks, nice guide. helped a lot getting my DS1307 on arch/RasPi up and running. you might want to add this to the dependencies in the rtc.service file to avoid unpredictable behaviour because the echo-command encounters "no such device"..

    [Unit]
    Requires=systemd-modules-load.service
    After=systemd-modules-load.service

Reply

Add comment

biuquote
  • Comment
  • Preview
Loading