DS1307 with Linux Kernel on Bootup for Raspberry Pi

To keep the RPI cost at the minimum,  RPI designer did not include a hardware RTC and if you are like me who normally work offline most of the time, the RPI Kernel system will always default to mid-night of 01 Jan 1970 which is the epoch or Unix time start date after each power down. Once the RPI is connected to the internet NTP protocol can be used to synchronize system time using the ntpd program. But for offline operation, I had a spare Maxim DS1307 pictured below, (salvaged from my  previous arduino projectDS1307+ Backup Battery mounted on a Sparkfun Micro SD Arduino shield) for use as the hwclock. DS1307 works over the I2C or TWI interface and generally RPI supports I2C  over GPIO so long as the Linux Kernel has been configured to support it and the driver is loaded. We will not be bit banging as we normally do on Atmel AVRs or other micro-controllers.

From the previous post  we saw how to compile a new Linux Kernel. To customize the Linux Kernel(version 3.2.27 all patches done to include support for bcm2708 machine), we need to include support for I2C and also DS1307 driver (included in the kernel source tree) by editing the make configuration file to include the following configurations:

CONFIG_I2C_BCM2708=y

CONFIG_I2C_BOARDINFO=y

CONFIG_I2C_COMPAT=y

CONFIG_I2C_CHARDEV=y

We did not select “m”(compile as modules) but instead we chose “y” because we want the drivers and I2C to be part of the kernel during booting and not to be loaded( LKM ) at a latter stage to add this functionality(using modprobe cmd).   When kernel boots it copies to RTC time into the system time(software clock which is calculated by the Linux kernel as the number of seconds since epoch or unix time start date)by executing a small program referred to as hctosys.c . The hctosys.c reads the hctosys_device, rtc0  and therefore we need to build the DS1307 driver into the kernel for this operation to be possible on startup . This is similarly done by configuring the config file follows:

CONFIG_RTC_CLASS=y

CONFIG_RTC_DRV_DS1307=y

We now need to tell the kernel that we have a device that is connected to I2C bus and it contains address 0×68 and its driver’s name is “rtc-1307” and its of type “ds1307” since this driver supports a range of Maxim RTC devices. This is achieved by defining the board information  in the arch/arm/mach-bcm2708/bcm2708.c.” file as shown below, a documentation on instantiating I2C devices is available in the Linux source documentation directory.

static struct i2c_board_info __initdata bcm2708_i2c_devices[] = {
{
I2C_BOARD_INFO("rtc-ds1307", 0x68),.type = "ds1307",
},};

Next we need to register the defined board  during processor’s initializing stage and that will be in the “void __init bcm2708_init(void)” function of arch/arm/mach-bcm2708/bcm2708.c.” file. The registration should be done after the processor is done registering core devices such as Broadcom Serial Controller, bcm2708_bscX . Note that the RPI has two I2C buses bcm2708_bsc0 and bcm2708_bsc1 and the DS1307 is connected to the 12C bus of bsc0 hence address 0 in the first parameter of the function below.

i2c_register_board_info(0,bcm2708_i2c_devices,ARRAY_SIZE(bcm2708_i2c_devices));

Save file and compile the kernel. After wiring up the DS1307 to the rpi as shown below(no need for pull resistor since the rpi has already 1.8 kilohm pulls up resistors on board for this pins), the system will print DS1307 registration logs on the console when the kernel starts-up , and also update the system time by reading the RTC using the hctosys.c program . That’s it ! I got my hardware RTC up and running….. Have fun with yours!

Advertisements

5 comments

  1. Bosstiger · · Reply

    Reblogged this on Gigable – Tech Blog.

  2. Hi, i have a doubt, i read that RPi GPIO lines are not 5v tolerant, in the picture above you are connecting the DS1307 directly to I2C lines on RPi, and powering the DS1307 with 5v supply, isn’t that damage RPi board? i’m asking this question bco i don’t have a Logic Level Convert and didn’t want to damage my board. 🙂

    Thanks
    plkumar

    1. Yes it has been stated that the RPi GPIO lines are not 5v tolerant, however my setup works and I have not experienced any breakdown with the two pins. You could add the Adafruits’ level translator or a less costly one from sparkfun

  3. Both the ds1307 SCL SDA and the pi SCL0 SDA0 are open drain ( they can only drive low)
    the pi has pullup resistors to 3.3v on its board. So the ds1307 driven at 5v and with no pull up resistors to 5v can only let the pi SCL0 SDa0 float via pull ups to 3.3v or drive it down to ground

  4. logic hi for the ds1307 is 2.2V to Vcc + 0.3V. With the 3.3V pullups on the rpi, that leaves 1.1V noise margin which is adequate. The ds1307 datasheet is here: http://datasheets.maximintegrated.com/en/ds/DS1307.pdf

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: