Angel David Yaguana Hernandez / DS1307

Dependents:   Proyect_Patric_electronic_door_MSC_Ok_ESP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ds1307.cpp Source File

ds1307.cpp

00001 #include "ds1307.h"
00002 
00003 DS1307::DS1307(PinName sda, PinName scl ) : ds1307i2c(sda,scl)
00004 {
00005     ds1307i2c.frequency(DS1307_freq);
00006 }
00007 
00008 DS1307::~DS1307()
00009 {
00010 }
00011 
00012 int DS1307::read( int addr, int quantity, char *data)
00013 {
00014     // note the char array at data must contain 63 locations or unpredictable behavior will happen
00015     // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access
00016     // quantity must be 1 - 63 as the 64th ram location is clobered in this method of access
00017     int test = 0 ;
00018     char temp_data[65];
00019 
00020     if (addr > DS1307_lastram) return (1);  // fail because address greater then what chip has to read from
00021     if (addr < 0 ) return (1);     // fail because address less then 0 is not available
00022     if (quantity > DS1307_lastreg) return (1);  // fail because quantity greater then what can be read
00023     if ((addr + quantity) > DS1307_lastreg ) return (1);    // fail because cant read past reg 63
00024     if ( quantity == 0 ) return (1);    // fail because zero quantity wanted
00025     temp_data[0] = DS1307_lastreg ;  // note this ram location is used to set the addressing pointer in DS1307
00026     temp_data[1] = 0;    // just junk to clober this address with
00027     test = ds1307i2c.write(DS1307_addr,temp_data,2);
00028     if (test == 1) return (1);  // the write operation failed
00029     //ds1307i2c.stop();   // now the DS1307 is pointing to the first register
00030     if ( addr != 0 ) test = ds1307i2c.read(DS1307_addr,temp_data,addr);  // now the DS1307 address pointer is pointing to correct address
00031     if (test == 1) return (1);  // the read operation failed
00032     test = ds1307i2c.read(DS1307_addr,data,quantity);   // read the DS1307 registers now
00033     if (test == 1) return (1);  // read operation failed
00034     return(0);  // looks like the data read was good
00035 }
00036 
00037 void DS1307::stop()
00038 {
00039 
00040 }
00041 
00042 int DS1307::read(int addr, int *data)
00043 {
00044     // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access
00045     int test = 0;
00046     char temp_data[65];
00047     test = DS1307::read(addr, 1, &temp_data[0]);
00048     if (test == 1) return(1);   // fail because read to DS1307 failed
00049     *data = (int)temp_data[0];      // returing the read data by pointer
00050     return (0);                     // the single read is successfull
00051 }
00052 
00053 int DS1307::write( int addr, int quantity, char *data)
00054 {
00055     // note the char array at data must contain 63 locations or unpredictable behavior will happen
00056     // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access
00057     // quantity must be 1 - 63 as the 64th ram location is clobered in this method of access
00058     int test = 0 ;
00059     char temp_data[65] ;
00060     int loop = 0;
00061 
00062     if (addr > DS1307_lastram) return (1);      // fail because address greater then what chip has to read from
00063     if (addr < 0 ) return (1);      // fail because address less then 0 is not available
00064     if (quantity > DS1307_lastreg) return (1);  // fail because quantity greater then what can be read
00065     if (quantity == 0) return (1);  // fail because zero quantity is wanted
00066     if ((addr + quantity) > DS1307_lastreg ) return (1);    // fail because cant read past reg 63
00067 
00068     temp_data[0] = (char)addr;
00069     for ( ; loop < quantity ; loop++ ) {
00070         temp_data[loop+1] = *(data + loop);
00071     }
00072     test = ds1307i2c.write(DS1307_addr, temp_data, (quantity + 1));
00073     //ds1307i2c.stop();
00074     return(test);   // 0 for success 1 for failure to write
00075 }
00076 
00077 int DS1307::write( int addr, int data )
00078 {
00079     // addr must be 0 - 62 as the 64th(or 63rd as indexed from 0) ram location is clobered in this method of access
00080     int test = 0 ;
00081     char temp_data[2] ;
00082 
00083     temp_data[0] = (char)addr;
00084     temp_data[1] = (char)data;
00085     if (addr > DS1307_lastram) return (1);      // fail because address greater then what chip has to read from
00086     if (addr < 0 ) return (1);      // fail because address less then 0 is not available
00087     test = ds1307i2c.write(DS1307_addr, temp_data, 2);
00088     //ds1307i2c.stop();
00089     return(test);
00090 }
00091 
00092 int DS1307::start_clock(void)             // start the clock
00093 {
00094     int test = 0;
00095     int junk = 0;
00096 
00097     test = DS1307::read(DS1307_sec, &junk);
00098     if (test == 1) return(1);       // fail because read to DS1307 failed
00099     junk = ( 0x7F & junk);              // basicaly i mask bit 8 to set it to zero
00100     test = DS1307::write(DS1307_sec,junk);        // now write the seconds back to register and because bit 8 is zero this starts clock.
00101     if (test == 1) return(1);        // fail because read to DS1307 failed
00102     return(test);                        //
00103 }
00104 
00105 int DS1307::stop_clock(void)             // stop clock
00106 {
00107     int test = 0;
00108     int junk = 0;
00109 
00110     test = DS1307::read(DS1307_sec, &junk);
00111     if (test == 1) return(1);        // fail because read to DS1307 failed
00112     junk = ( 0x7F & junk);              // basicaly i mask bit 8 to set it to zero but keep all other bits
00113     junk = ( 0x80 | junk);              // basicaly i mask bit 8 to set it to one
00114     test = DS1307::write(DS1307_sec,junk);        // now write the seconds back to register and because bit 8 is one this starts clock.
00115     if (test == 1) return(1);        // fail because read to DS1307 failed
00116     return(test);                        //
00117 }
00118 
00119 int DS1307::twelve_hour(void)             // set 12 hour mode
00120 {
00121     int test = 0;
00122     int junk = 0;
00123 
00124     test = DS1307::read(DS1307_hour, &junk);
00125     if (test == 1) return(1);       // fail because read to DS1307 failed
00126     if ((junk & 0x40) == 0x40) return(0);         // return because 12 mode is active now all done!
00127 
00128     junk = ( junk & 0x3F);              // only use 24 hour time values
00129     if (junk == 0x00)
00130         junk = 0x12;
00131     else if (junk >= 0x13)
00132         if (junk < 0x20) {
00133             junk = junk - 0x12;
00134             junk = (junk | 0x20);   // add back the pm indicator
00135         } else
00136             switch (junk) {
00137                 case 0x20:
00138                     junk = 0x28;
00139                     break;
00140                 case 0x21:
00141                     junk = 0x29;
00142                     break;
00143                 case 0x22:
00144                     junk = 0x30;
00145                     break;
00146                 case 0x23:
00147                     junk = 0x31;
00148                     break;
00149             }
00150 
00151     test = DS1307::write(DS1307_hour,(0x40 | junk));    // set bit 6 with the new 12 hour time converted from the 24 hour time
00152     if (test == 1) return(1);       // fail because read to DS1307 failed
00153 
00154     return(0);
00155 }
00156 
00157 int DS1307::twentyfour_hour(void)       // set 24 hour mode
00158 {
00159     int test = 0;
00160     int junk = 0;
00161 
00162     test = DS1307::read(DS1307_hour, &junk);
00163     if (test == 1) return(1);       // fail because read to DS1307 failed
00164     if ((junk & 0x40) == 0) return(0);         // return because 24 mode is active now all done!
00165 
00166     junk = (junk &  0xBF);              // get value bits and am/pm indicator bit but drop 12/24 hour bit
00167 
00168     if (junk > 0x12)
00169         if ( junk <= 0x27 )
00170             junk = junk - 0x0E;
00171         else
00172             junk = junk - 0x08;
00173 
00174     test = DS1307::write(DS1307_hour,( 0xBF & junk));   // clear bit 6 and set the new 24 hour time converted from 12 hour time
00175     if (test == 1) return(1);       // fail because read to DS1307 failed
00176 
00177     return(0);
00178 }
00179 
00180 int DS1307::settime(int sec, int min, int hour, int day, int date, int month, int year)          // to set the current time and start clock
00181 {
00182     // sec = 0 to 59, min = 0 to 59, hours = 0 to 23 ( 24 hour mode only ), day = 1 to 7 ( day of week ), date = 1 to 31, month = 1 to 12, year 0 to 99 ( this is for 2000 to 2099)
00183     DS1307::stop_clock();
00184 
00185     if (1 == DS1307::hilow_check( 59, 0, sec)) {
00186         return(1);    // failed because recieved value is not in bounds
00187     } else {
00188         if (1 == (DS1307::write(DS1307_sec,DS1307::dectobcd(sec)))) return(1);    // failed to write for some reason
00189     }
00190 
00191     if (1 == DS1307::hilow_check( 59, 0, min)) {
00192         return(1);    // failed because recieved value is not in bounds
00193     } else {
00194         if (1 == (DS1307::write(DS1307_min,DS1307::dectobcd(min)))) return(1);    // failed to write for some reason
00195     }
00196 
00197     if (1 == DS1307::twentyfour_hour()) return(1);                                      // failed to set 24 hour format
00198     if (1 == DS1307::hilow_check( 23, 0, hour)) {                                       // note setting 24 hour mode befor and after writing the hour value ensures 24 hour mode is set
00199         return(1);    // failed because recieved value is not in bounds
00200     } else {
00201         if (1 == (DS1307::write(DS1307_hour,DS1307::dectobcd(hour)))) return(1);    // failed to write for some reason
00202     }
00203     if (1 == DS1307::twentyfour_hour()) return(1);                                      // failed to set 24 hour format
00204 
00205     if (1 == DS1307::hilow_check( 7, 1, day)) {
00206         return(1);    // failed because recieved value is not in bounds
00207     } else {
00208         if (1 == (DS1307::write(DS1307_day,DS1307::dectobcd(day)))) return(1);    // failed to write for some reason
00209     }
00210 
00211     if (1 == DS1307::hilow_check( 31, 1, date)) {
00212         return(1);    // failed because recieved value is not in bounds
00213     } else {
00214         if (1 == (DS1307::write(DS1307_date,DS1307::dectobcd(date)))) return(1);    // failed to write for some reason
00215     }
00216 
00217     if (1 == DS1307::hilow_check( 12, 1, month)) {
00218         return(1);    // failed because recieved value is not in bounds
00219     } else {
00220         if (1 == (DS1307::write(DS1307_month,DS1307::dectobcd(month)))) return(1);    // failed to write for some reason
00221     }
00222 
00223     if (1 == DS1307::hilow_check( 99, 0, year)) {
00224         return(1);    // failed because recieved value is not in bounds
00225     } else {
00226         if (1 == (DS1307::write(DS1307_year,DS1307::dectobcd(year)))) return(1);    // failed to write for some reason
00227     }
00228 
00229     DS1307::start_clock();
00230     return (0);             // time is now set
00231 }
00232 
00233 int DS1307::gettime(int *sec, int *min, int *hour, int *day, int *date, int *month, int *year)   // to get the current time information
00234 {
00235     // sec = 0 to 59, min = 0 to 59, hours = 0 to 23 ( 24 hour mode only ), day = 1 to 7 ( day of week ), date = 1 to 31, month = 1 to 12, year 0 to 99 ( this is for 2000 to 2099)
00236     if (1 == DS1307::read(DS1307_sec,sec)) return(1);       // failed to read for some reason
00237     *sec = (*sec & 0x7F );                                  // drop the clock start stop bit
00238     *sec = DS1307::bcdtodec( *sec);                         // bcd is now dec value
00239 
00240     if (1 == DS1307::read(DS1307_min,min)) return(1);       // failed to read for some reason
00241     *min = (*min & 0x7F );                                  // drop bit 7 because it should be 0 anyways
00242     *min = DS1307::bcdtodec( *min);                         // bcd is now dec value
00243 
00244     if (1 == DS1307::read(DS1307_hour,hour)) return(1);     // failed to read for some reason
00245     if ((*hour & 0x40) == 0x40) {                           // if true then 12 hour mode is set currently  so change to 24 hour, read value, and return to 12 hour mode
00246         if (1 == DS1307::twentyfour_hour()) return(1);          // failed to set 24 hour mode for some reason
00247         if (1 == DS1307::read(DS1307_hour,hour)) return(1);     // failed to read for some reason
00248         *hour = (*hour & 0x3F );                                // drop bit 7 & 6 they are not used for 24 hour mode reading
00249         *hour = DS1307::bcdtodec( *hour);                       // bcd is now dec value
00250         if (1 == DS1307::twelve_hour()) return(1);              // failed to return to 12 hour mode for some reason
00251     } else {                                                     // in 24 hour mode already so just read the hour value
00252         if (1 == DS1307::read(DS1307_hour,hour)) return(1);    // failed to read for some reason
00253         *hour = (*hour & 0x3F );                                // drop bit 7 & 6 they are not used for 24 hour mode reading
00254         *hour = DS1307::bcdtodec( *hour);                       // bcd is now dec value
00255     }
00256 
00257     if (1 == DS1307::read(DS1307_day,day)) return(1);       // failed to read for some reason
00258     *day = (*day & 0x07 );                                  // drop the non used bits
00259     *day = DS1307::bcdtodec( *day);                         // bcd is now dec value
00260 
00261     if (1 == DS1307::read(DS1307_date,date)) return(1);     // failed to read for some reason
00262     *date = (*date & 0x3F );                                // drop bit 6 and 7 not used for date value
00263     *date = DS1307::bcdtodec( *date);                       // bcd is now dec value
00264 
00265     if (1 == DS1307::read(DS1307_month,month)) return(1);   // failed to read for some reason
00266     *month = (*month & 0x1F );                              // drop bit 5, 6 and 7 not used for month value
00267     *month = DS1307::bcdtodec( *month);                     // bcd is now dec value
00268 
00269     if (1 == DS1307::read(DS1307_year,year)) return(1);     // failed to read for some reason
00270     *year = DS1307::bcdtodec( *year);                       // bcd is now dec value
00271 
00272     return (0);                                             // data returned is valid
00273 }
00274 
00275 
00276 int DS1307::dectobcd( int dec)
00277 {
00278     int low = 0;
00279     int high = 0;
00280 
00281     high = dec / 10;                // this gives the high nibble value
00282     low = dec - (high * 10);        // this gives the lower nibble value
00283     return ((high *16) + low);      // this is the final bcd value but in interger format
00284 }
00285 
00286 int DS1307::bcdtodec( int bcd)
00287 {
00288     int low = 0;
00289     int high = 0;
00290 
00291     high = bcd / 16;
00292     low = bcd - (high * 16);
00293     return ((high * 10) + low);
00294 
00295 }
00296 
00297 int DS1307::hilow_check( int hi, int low, int value)
00298 {
00299     if ((value >= low)&(value <= hi))
00300         return(0);              // value is equal to or inbetween hi and low
00301     else
00302         return(1);              // value is not equal to or inbetween hi and low
00303 }