lib

Fork of DS1338 by Stéphane Cachat

ds1338.cpp

Committer:
scachat
Date:
2015-03-04
Revision:
0:0ffb7046206a
Child:
1:e77d69913c46

File content as of revision 0:0ffb7046206a:

#include "mbed.h"
#include "ds1338.h"

/*
 * Constructor, initialize the ds1338 on i2c interface.
 * @param sda : sda i2c pin (PinName)
 * @param scl : scl i2c pin (PinName)
*/
DS1338::DS1338(PinName sda, PinName scl): _i2c(sda, scl) {
    _i2c.frequency(400000);
    buffer[0]=0x07;
    _i2c.write(DS1338_ADR,buffer,1,true);
    _i2c.read(DS1338_ADR,buffer,1);
    if (buffer[0]&0x20){
       buffer[0]=0x07;
       buffer[1]=0xB0;//do not erase error condition !
    }else{
       buffer[0]=0x07;
       buffer[1]=0x90;
    }
    _i2c.write(DS1338_ADR,buffer,1+1);
}
/**
 * read bytes from nvram (55 bytes available)
 * @param adr the start address (starts at 0)
 * @param count number of byte to read
 * @param data where to put the bytes
 * @return the byte
 */
void DS1338::read(unsigned char adr,unsigned char count,char * data) {
    if (count>DS1338_BUFFER_SIZE) {
        count=DS1338_BUFFER_SIZE;
    }
    buffer[0]=9+adr;
    _i2c.write(DS1338_ADR,&(buffer[0]),1,true);
    _i2c.read(DS1338_ADR,data,count);
}
/**
 * write bytes to nvram (55 bytes available)
 * @param adr the start address (starts at 0)
 * @param count number of byte to write
 * @param data to be written
 * @return the byte
 */
void DS1338::write(unsigned char adr,unsigned char count,char * data) {
    if (count>DS1338_BUFFER_SIZE-1) {
        count=DS1338_BUFFER_SIZE-1;
    }
    buffer[0]=9+adr;
    for (unsigned char i=0; i<count; i++) {
        buffer[1+i]=*(data+i);
    }
    _i2c.write(DS1338_ADR,buffer,1+count);
}
/**
 * read the current time
 * @param x the time;
 */
void DS1338::readTime(tm * time) {
    buffer[0]=0;
    _i2c.write(DS1338_ADR,&(buffer[0]),1,true);
    _i2c.read(DS1338_ADR,buffer,9);
    time->tm_sec=((buffer[0]>>4)&0x07)*10+(buffer[0]&0x0F);
    time->tm_min=((buffer[1]>>4)&0x07)*10+(buffer[1]&0x0F);
    time->tm_hour=((buffer[2]>>4)&0x03)*10+(buffer[2]&0x0F);
    time->tm_mday=((buffer[4]>>4)&0x03)*10+(buffer[4]&0x0F);
    time->tm_mon=((buffer[5]>>4)&0x01)*10+(buffer[5]&0x0F)-1;
    time->tm_year=((buffer[6]>>4)&0x0F)*10+(buffer[6]&0x0F);
    if (time->tm_year<70){
       time->tm_year+=100;
    }
    time->tm_wday=buffer[3]&0x07;
    time->tm_yday=0;
    time->tm_isdst=0;
    if (time->tm_sec>=60||
        time->tm_min>=60||
        time->tm_hour>=24||
        time->tm_mday>31 || time->tm_mday<1||
        time->tm_mon>11||
        time->tm_wday>=7||
        buffer[0x08]!=0xCA||//checksum
        (buffer[0x07]&0x20)!=0){//error condition
          time->tm_sec=0;
          time->tm_min=0;
          time->tm_hour=0;
          time->tm_mday=1;
          time->tm_mon=0;
          time->tm_year=70;
          time->tm_wday=1;
          time->tm_yday=0;
          time->tm_isdst=0;
          writeTime(time);
        }
}
/**
 * write the current time
 * @param time the time;
 */
void DS1338::writeTime(tm * time) {
   buffer[0]=0;
   buffer[1]=(((time->tm_sec/10)<<4)+(time->tm_sec%10))&0x7F;//clock not halted
   buffer[2]=(((time->tm_min/10)<<4)+(time->tm_min%10))&0x7F;
   buffer[3]=(((time->tm_hour/10)<<4)+(time->tm_hour%10))&0x3F;//mode 24h
   buffer[4]=(time->tm_wday)&0x03;
   buffer[5]=(((time->tm_mday/10)<<4)+(time->tm_mday%10))&0x3F;
   buffer[6]=(((time->tm_mon/10)<<4)+(time->tm_mon%10))&0x1F;
   buffer[7]=((((time->tm_year%100)/10)<<4)+(time->tm_year%10))&0xFF;
   buffer[8]=0x90;//1Hz, erase error cond
   buffer[9]=0xCA;
   _i2c.write(DS1338_ADR,buffer,1+9);
}