/**************************************************************************************************
*
*  Real Time Clock
*
*   Version:      1.0.0 - January 2009
*   Author:       Etienne Ribeiro    / tutorial assistant caad      /  eribeiro[at]ethz.ch
*                 (based on Code from Maurice Ribble)
*                 (http://www.glacialwanderer.com/hobbyrobotics)
*   Supervisor:   Christoph Wartmann / chair for caad - ETH Zürich  /  wartmann[at].arch.ethz.ch
*
*   Desc:         This Module can be used to plug a Real Time Clock to your project. Connect the
*                 clock to your I2C-Pins (SCL, SDA).
*
*   Methodes:     void iniWire ()
*                    Initializes wire. Must be called in setup().
*                 void setDate(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
*                    Set date. Not needed to call, if clock has already be ajusted.
*                 void getDate(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year)
*                    Get date. Parameters are return parameters. They must be called with &var1, & var2,...
*
***************************************************************************************************/




#include <TwoWire.h>
#define DS1307_I2C_ADDRESS 0x68



// Starts Wire. Must be called in setup
void iniWire () {

        Wire.begin();

}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDate(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {

        Wire.beginTransmission(DS1307_I2C_ADDRESS);
        Wire.send(0);
        Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
        Wire.send(decToBcd(minute));
        Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
        // bit 6 (also need to change readDateDs1307)
        Wire.send(decToBcd(dayOfWeek));
        Wire.send(decToBcd(dayOfMonth));
        Wire.send(decToBcd(month));
        Wire.send(decToBcd(year));
        Wire.endTransmission();

}


// Gets the date and time from the ds1307
void getDate(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
        // Reset the register pointer
        Wire.beginTransmission(DS1307_I2C_ADDRESS);
        Wire.send(0);
        Wire.endTransmission();

        Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

        // A few of these need masks because certain bits are control bits
        *second     = bcdToDec(Wire.receive() & 0x7f);
        *minute     = bcdToDec(Wire.receive());
        *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
        *dayOfWeek  = bcdToDec(Wire.receive());
        *dayOfMonth = bcdToDec(Wire.receive());
        *month      = bcdToDec(Wire.receive());
        *year       = bcdToDec(Wire.receive());

}


// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x80);
Wire.endTransmission();
}*/



// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {
        return ( (val/10*16) + (val%10) );
}


// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
        return ( (val/16*10) + (val%16) );
}