Library for DS1307 Real Time Clock

All it has more is the geek factore :stuck_out_tongue: It also has a slightly different register layout. This mostly affected the stop/start functions. Also the ds1337 come in a (C) version which has a built in xtal, which can be practical.

As for setting it, sure that's what I though to, but you can't really send bytes through screen. As for epoch, I have some plan on adding NTP... which will deliver the time using an epoch stamp. What ever, that's all just playing with numbers :wink:

Here's what the port looks like.

extern "C" {
      #include <Wire/Wire.h>
      #include <avr/pgmspace.h>
}

#include "DS1337.h"
#include "programStrings.h"

DS1337::DS1337()
{
      Wire.begin();
}

DS1337 RTC=DS1337();

// PRIVATE FUNCTIONS

// Aquire data from the RTC chip in BCD format
// refresh the buffer
void DS1337::read(void)
{
// use the Wire lib to connect to tho rtc
// reset the resgiter pointer to zero
      Wire.beginTransmission(DS1337_CTRL_ID);
      Wire.send(0x00);
      Wire.endTransmission();

// request the 7 bytes of data    (secs, min, hr, dow, date. mth, yr) 
      Wire.requestFrom(DS1337_CTRL_ID, 7);
      for(int i=0; i<7; i++)
      {
      // store data in raw bcd format
            if (Wire.available())
                  rtc_bcd[i]=Wire.receive();
      }
}

// update the data on the IC from the bcd formatted data in the buffer
void DS1337::save(void)
{
      Wire.beginTransmission(DS1337_CTRL_ID);
      Wire.send(0x00); // reset register pointer
      for(int i=0; i<7; i++)
      {
            Wire.send(rtc_bcd[i]);
      }
      Wire.endTransmission();
}

unsigned char DS1337::getRegister(unsigned char registerNumber)
{
      Wire.beginTransmission(DS1337_CTRL_ID);
      Wire.send(registerNumber);
      Wire.endTransmission();

      Wire.requestFrom(DS1337_CTRL_ID, 1);
      
      return Wire.receive();
}

void DS1337::setRegister(unsigned char registerNumber, unsigned char registerMask)
{
      Wire.beginTransmission(DS1337_CTRL_ID);
      Wire.send(registerNumber); // reset register pointer
      
      Wire.send(registerMask);
      
      Wire.endTransmission();
}

void DS1337::unsetRegister(unsigned char registerNumber, unsigned char registerMask)
{
      setRegister(registerNumber, (getRegister(registerNumber) & ~registerNumber));
}

// PUBLIC FUNCTIONS
void DS1337::get(int *rtc, boolean refresh)   // Aquire data from buffer and convert to int, refresh buffer if required
{
      if(refresh) read();
      for(int i=0;i<7;i++)  // cycle through each component, create array of data
      {
            rtc[i]=get(i, 0);
      }
}

int DS1337::get(int c, boolean refresh)  // aquire individual RTC item from buffer, return as int, refresh buffer if required
{
      if(refresh) read();
      int v=-1;
      switch(c)
      {
            case DS1337_SEC:
            v=(10*((rtc_bcd[DS1337_SEC] & DS1337_HI_SEC)>>4))+(rtc_bcd[DS1337_SEC] & DS1337_LO_BCD);
            break;
            case DS1337_MIN:
            v=(10*((rtc_bcd[DS1337_MIN] & DS1337_HI_MIN)>>4))+(rtc_bcd[DS1337_MIN] & DS1337_LO_BCD);
            break;
            case DS1337_HR:
            v=(10*((rtc_bcd[DS1337_HR] & DS1337_HI_HR)>>4))+(rtc_bcd[DS1337_HR] & DS1337_LO_BCD);
            break;
            case DS1337_DOW:
            v=rtc_bcd[DS1337_DOW] & DS1337_LO_DOW;
            break;
            case DS1337_DATE:
            v=(10*((rtc_bcd[DS1337_DATE] & DS1337_HI_DATE)>>4))+(rtc_bcd[DS1337_DATE] & DS1337_LO_BCD);
            break;
            case DS1337_MTH:
            v=(10*((rtc_bcd[DS1337_MTH] & DS1337_HI_MTH)>>4))+(rtc_bcd[DS1337_MTH] & DS1337_LO_BCD);
            break;
            case DS1337_YR:
            v=(10*((rtc_bcd[DS1337_YR] & DS1337_HI_YR)>>4))+(rtc_bcd[DS1337_YR] & DS1337_LO_BCD)+DS1337_BASE_YR;
            break; 
      } // end switch
      return v;
} 

void DS1337::set(int c, int v)  // Update buffer, then update the chip
{
      switch(c)
      {
            case DS1337_SEC:
            if(v<60 && v>-1)
            {
            //preserve existing clock state (running/stopped)
                  int state=rtc_bcd[DS1337_SEC] & DS1337_CLOCKHALT;
                  rtc_bcd[DS1337_SEC]=state | ((v / 10)<<4) + (v % 10);
            }
            break; 
            case DS1337_MIN:
            if(v<60 && v>-1)
            {
                  rtc_bcd[DS1337_MIN]=((v / 10)<<4) + (v % 10);
            }
            break;
            case DS1337_HR:
            // TODO : AM/PM  12HR/24HR
            if(v<24 && v>-1)
            {
                  rtc_bcd[DS1337_HR]=((v / 10)<<4) + (v % 10);
            }
            break;
            case DS1337_DOW: 
            if(v<8 && v>-1)
            {
                  rtc_bcd[DS1337_DOW]=v;
            }
            break;
            case DS1337_DATE:
            if(v<31 && v>-1)
            {
                  rtc_bcd[DS1337_DATE]=((v / 10)<<4) + (v % 10);
            }
            break;
            case DS1337_MTH:
            if(v<13 && v>-1)
            {
                  rtc_bcd[DS1337_MTH]=((v / 10)<<4) + (v % 10);
            }
            break;
            case DS1337_YR:
            if(v<13 && v>-1)
            {
                  rtc_bcd[DS1337_YR]=((v / 10)<<4) + (v % 10);
            }
            break;
      } // end switch
      save();
}

void DS1337::stop(void)
{
      setRegister(DS1337_SP, DS1337_SP_EOSC);
}

void DS1337::start(void)
{
      unsetRegister(DS1337_SP, DS1337_SP_EOSC);
}