Motoo Tanaka / RTC8564

Dependents:   testRTC8564

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RTC8564.cpp Source File

RTC8564.cpp

00001 #include "mbed.h"
00002 #include "RTC8564.h"
00003 
00004 /* Register Definitions */
00005 #define REG_CONTROL1         0x00
00006 #define REG_CONTROL2         0x01
00007 #define REG_SECONDS          0x02
00008 #define REG_MINUTES          0x03
00009 #define REG_HOURS            0x04
00010 #define REG_DAYS             0x05
00011 #define REG_WEEKDAYS         0x06
00012 #define REG_MONTHS           0x07
00013 #define REG_YEARS            0x08
00014 #define REG_MINUTE_ALARM     0x09
00015 #define REG_HOUR_ALARM       0x0A
00016 #define REG_DAY_ALARM        0x0B
00017 #define REG_WEEKDAY_ALARM    0x0C
00018 #define REG_CLKOUT_FREQUENCY 0x0D
00019 #define REG_TIMER_CONTROL    0x0E
00020 #define REG_TIMER            0x0F
00021 
00022 /* Register bit masks */
00023 /* REG_CONTROL1 (0x00) */
00024 #define STOP_BIT             0x20
00025 
00026 /* REG_CONTROL2 (0x01) */
00027 #define TI_TP_BIT            0x10
00028 #define AF_BIT               0x08
00029 #define TF_BIT               0x04
00030 #define AIE_BIT              0x02
00031 #define TIE_BIT              0x01
00032 
00033 /* REG_SECONDS (0x02) */
00034 #define VL_BIT               0x80
00035 #define SECONDS_MASK         0x7F
00036 
00037 /* REG_MINUTES (0x03) */
00038 #define MINUTES_MASK         0x7F
00039 
00040 /* REG_HOURS (0x04) */
00041 #define HOURS_MASK           0x3F
00042 
00043 /* REG_DAYS (0x05) */
00044 #define DAYS_MASK            0x3F
00045 
00046 /* REG_WEEKDAYS (0x06) */
00047 #define WEEKDAYS_MASK        0x07
00048 
00049 /* REG_MONTHS (0x07) */
00050 #define CENTURY_BIT          0x80
00051 #define MONTHS_MASK          0x1F
00052 
00053 /* REG_YEARS (0x08) */
00054 #define YEARS_MASK           0xFF
00055 
00056 /* REG_MINUTE_ALARM (0x09)  */
00057 #define AE_BIT               0x80
00058 #define MINUTE_ALARM_MASK    0x7F
00059 
00060 /* REG_HOUR_ALARM (0x0A)   */
00061 // #define AE_BIT            0x80 (already defined)
00062 #define HOUR_ALARM_MASK     0x3F
00063 
00064 /* REG_DAY_ALARM (0x0B) */
00065 // #define AE_BIT            0x80 (already defined)
00066 #define DAY_ALARM_MASK      0x3F
00067 
00068 /* REG_WEEKDAY_ALARM (0x0C) */
00069 // #define AE_BIT            0x80 (already defined)
00070 #define WEEKDAY_ALARM_MASK  0x07
00071 
00072 /* REG_CLKOUT_FREQUENCY (0x0D) */
00073 #define FE_BIT              0x80
00074 #define FD1_BIT             0x02
00075 #define FD0_BIT             0x01
00076 
00077 /* REG_TIMER_CONTROL (0x0E) */
00078 #define TE_BIT              0x80
00079 #define TD1_BIT             0x02
00080 #define TD0_BIT             0x01
00081 
00082 /* REG_TIMER (0x0F) */
00083 /* bit values, 128, 64, 32, 16, 8, 4, 2, 1 (so what?) */
00084 
00085 static int VL = 0 ; /* POR or LVD bit */
00086 static int Century = 0 ; /* dawn of the new Century */
00087 
00088 static uint8_t i2bcd(uint8_t ival) 
00089 {
00090     uint8_t bcd = 0 ;
00091     bcd = ((ival / 10)<<4) | (ival % 10) ;
00092     return(bcd) ;    
00093 }
00094 
00095 static uint8_t bcd2i(uint8_t bcd) 
00096 {
00097     uint8_t ival ;
00098     ival = ((bcd >> 4)*10)+(bcd & 0x0F) ;
00099     return(ival) ;
00100 }
00101 
00102 RTC8564::RTC8564(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
00103     // activate the peripheral
00104     wait(1) ; /* 1 sec required for the clock to be stable */
00105 }
00106 
00107 RTC8564::~RTC8564() { }
00108 
00109 void RTC8564::readRegs(int addr, uint8_t * data, int len) {
00110     char t[1] = {addr} ;
00111     m_i2c.write(m_addr, t, 1, true) ;
00112     m_i2c.read(m_addr, (char*)data, len) ;
00113     wait_us(100) ;
00114 }
00115 
00116 void RTC8564::writeRegs(uint8_t * data, int len) {
00117    m_i2c.write(m_addr, (char *)data, len) ;
00118    wait_us(100) ;
00119 }
00120 
00121 /* mutators */
00122 void RTC8564::setReg(int addr, uint8_t value) 
00123 {
00124     uint8_t data[2] ;
00125     data[0] = addr ;
00126     data[1] = value ;
00127     writeRegs(data, 2) ;
00128 }
00129 
00130 void RTC8564::setAll(uint8_t value[])
00131 {
00132     uint8_t *data ;
00133     data = new uint8_t[17] ;
00134     data[0] = 0x00 ;
00135     for (int i = 0 ; i < 0x10 ; i++ ) {
00136         data[i+1] = value[i] ;
00137     }
00138     writeRegs(data, 17) ;
00139     delete data ;
00140 }
00141 
00142 void RTC8564::setControl1(uint8_t data) 
00143 { 
00144     setReg(REG_CONTROL1, data) ; 
00145 }
00146 
00147 void RTC8564::setControl2(uint8_t data) 
00148 { 
00149     setReg(REG_CONTROL2, data) ; 
00150 }
00151 
00152 void RTC8564::setSeconds(uint8_t value) 
00153 {
00154     uint8_t bcd ;
00155     value %= 60 ; /* sec is 0..59 */
00156     bcd = i2bcd(value) ;
00157     setReg(REG_SECONDS, bcd) ;
00158 }
00159 
00160 void RTC8564::setMinutes(uint8_t data) 
00161 {
00162     uint8_t bcd ;
00163     data %= 60 ; /* minute is 0 .. 59 */
00164     bcd = i2bcd(data) ;
00165     setReg(REG_MINUTES, bcd) ;
00166 }
00167 
00168 void RTC8564::setHours(uint8_t data) 
00169 {
00170     uint8_t bcd ;
00171     data %= 24 ; /* hour is 0 .. 23 */
00172     bcd = i2bcd(data) ;
00173     setReg(REG_HOURS, bcd) ;
00174 }
00175 
00176 void RTC8564::setDays(uint8_t data) 
00177 {
00178     uint8_t bcd ;
00179     if (data == 0) { data = 1 ; } 
00180     data %= 32 ; /* day is 1 .. 31 */
00181     bcd = i2bcd(data) ;
00182     setReg(REG_DAYS, bcd) ;
00183 }
00184 
00185 void RTC8564::setWeekdays(uint8_t data) 
00186 {
00187     data %= 7 ; /* weekday is 0 to 7 */
00188     setReg(REG_WEEKDAYS, data) ;   
00189 }
00190 
00191 void RTC8564::setMonths(uint8_t data) 
00192 {
00193     uint8_t bcd ;
00194     data = ((data - 1)%12) + 1 ; /* month is 1 .. 12 */
00195     bcd = i2bcd(data) ;
00196     setReg(REG_MONTHS, bcd) ;
00197 }
00198 
00199 void RTC8564::setYears(uint8_t data) 
00200 {
00201     uint8_t bcd ;
00202     data %= 100 ; /* year is 0 .. 99 */
00203     bcd = i2bcd(data) ;
00204     setReg(REG_YEARS, bcd) ;
00205 }
00206 
00207 void RTC8564::setMinuteAlarm(uint8_t data) 
00208 {
00209 //    data &= (AE_BIT | MINUTE_ALARM_MASK ) ; /* all 8bit is valid */
00210     setReg(REG_MINUTE_ALARM, data) ;
00211 }
00212 
00213 void RTC8564::setHourAlarm(uint8_t data) 
00214 {
00215     data &= (AE_BIT | HOUR_ALARM_MASK ) ;
00216     setReg(REG_HOUR_ALARM, data) ;
00217 }
00218 
00219 void RTC8564::setDayAlarm(uint8_t data) 
00220 {
00221     data &= (AE_BIT | DAY_ALARM_MASK) ;
00222     setReg(REG_DAY_ALARM, data) ;
00223 }
00224 
00225 void RTC8564::setWeekdayAlarm(uint8_t data) 
00226 {
00227     data &= (AE_BIT | WEEKDAY_ALARM_MASK) ;
00228     setReg(REG_WEEKDAY_ALARM, data) ;
00229 }
00230 
00231 void RTC8564::setCLKOUTFrequency(uint8_t data) 
00232 {
00233     data &= (FE_BIT | FD1_BIT | FD0_BIT) ;
00234     setReg(REG_CLKOUT_FREQUENCY, data) ;
00235 }
00236 
00237 void RTC8564::setTimerControl(uint8_t data) 
00238 {
00239     data &= (TE_BIT | TD1_BIT | TD0_BIT ) ;
00240     setReg(REG_TIMER_CONTROL, data) ;
00241 }
00242 
00243 void RTC8564::setTimer(uint8_t data) 
00244 {
00245     setReg(REG_TIMER, data) ;
00246 }
00247 
00248 /* inspectors */
00249 uint8_t RTC8564::getReg(int addr) 
00250 {
00251     uint8_t data ;
00252     readRegs(addr, &data, 1) ;
00253     return( data ) ;
00254 }
00255 
00256 void    RTC8564::getAll(uint8_t data[]) 
00257 {
00258     readRegs(0x00, data, 16) ;
00259 }
00260 
00261 uint8_t RTC8564::getControl1(void) 
00262 {
00263     uint8_t data ;
00264     data = getReg(REG_CONTROL1) ;
00265     return( data ) ;
00266 }
00267 
00268 uint8_t RTC8564::getControl2(void) 
00269 {
00270     uint8_t data ;
00271     data = getReg(REG_CONTROL2) ;
00272     return( data ) ;
00273 }
00274 
00275 uint8_t RTC8564::getSeconds(void) 
00276 {
00277     uint8_t bcd, ival ;
00278     bcd = getReg(REG_SECONDS) ;
00279     if (bcd & VL_BIT) {
00280         VL = 1 ;
00281     } else {
00282         VL = 0 ;
00283     }
00284     bcd &= SECONDS_MASK ;
00285     ival = bcd2i(bcd) ;
00286     return( ival ) ;
00287 }
00288 
00289 uint8_t RTC8564::getMinutes(void) 
00290 {
00291     uint8_t bcd, ival ;
00292     bcd = getReg(REG_MINUTES) ;
00293     bcd &= MINUTES_MASK ;
00294     ival = bcd2i(bcd) ;
00295     return( ival ) ;
00296 }
00297 
00298 uint8_t RTC8564::getHours(void) 
00299 {
00300     uint8_t bcd, ival ;
00301     bcd = getReg(REG_HOURS) ;
00302     bcd &= HOURS_MASK ;
00303     ival = bcd2i(bcd) ;
00304     return( ival ) ;       
00305 }
00306 
00307 uint8_t RTC8564::getDays(void) 
00308 {
00309     uint8_t bcd, ival ;
00310     bcd = getReg(REG_DAYS) ;
00311     bcd &= DAYS_MASK ;
00312     ival = bcd2i(bcd) ;
00313     return( ival ) ;     
00314 }
00315 
00316 uint8_t RTC8564::getWeekdays(void) 
00317 {
00318     uint8_t bcd, ival ;
00319     bcd = getReg(REG_WEEKDAYS) ;
00320     bcd &= WEEKDAYS_MASK ;
00321     ival = bcd2i(bcd) ;
00322     return( ival ) ;
00323 }
00324 
00325 uint8_t RTC8564::getMonths(void) 
00326 {
00327     uint8_t bcd, ival ;
00328     bcd = getReg(REG_MONTHS) ;
00329     if (bcd & CENTURY_BIT) {
00330         Century = 1 ; /* We are now in the year 2100! (so what?) */
00331     }
00332     bcd &= WEEKDAYS_MASK ; /* Sorry, I don't care about year 2100 */
00333     ival = bcd2i(bcd) ;
00334     return( ival ) ;
00335 }
00336 
00337 uint8_t RTC8564::getYears(void) 
00338 {
00339     uint8_t bcd, ival ;
00340     bcd = getReg(REG_YEARS) ;
00341     ival = bcd2i(bcd) ;
00342     return( ival ) ;
00343 }
00344 
00345 uint8_t RTC8564::getMinuteAlarm(void) 
00346 {
00347     return( getReg(REG_MINUTE_ALARM) ) ;
00348 }
00349 
00350 uint8_t RTC8564::getHourAlarm(void) 
00351 {
00352     uint8_t data ;
00353     data = getReg(REG_HOUR_ALARM) ;
00354     data &= (AE_BIT | HOUR_ALARM_MASK) ;
00355     return( data ) ;
00356 }
00357 
00358 uint8_t RTC8564::getDayAlarm(void) 
00359 {
00360     uint8_t data ;
00361     data = getReg(REG_DAY_ALARM) ;
00362     data &= (AE_BIT | DAY_ALARM_MASK) ;
00363     return( data ) ;
00364 }
00365 
00366 uint8_t RTC8564::getWeekdayAlarm(void) 
00367 {
00368     uint8_t data ;
00369     data = getReg(REG_WEEKDAY_ALARM) ;
00370     data &= (AE_BIT | WEEKDAY_ALARM_MASK) ;
00371     return( data ) ;
00372 }
00373 
00374 uint8_t RTC8564::getCLKOUTFrequency(void) 
00375 {
00376     uint8_t data ;
00377     data = getReg(REG_CLKOUT_FREQUENCY) ;
00378     data &= (FE_BIT | FD1_BIT | FD0_BIT) ;
00379     return( data ) ;
00380 }
00381 
00382 uint8_t RTC8564::getTimerControl(void) 
00383 {
00384     uint8_t data ;
00385     data = getReg(REG_TIMER_CONTROL) ;
00386     data &= (TE_BIT | TD1_BIT | TD0_BIT) ;
00387     return( data ) ;
00388 }
00389 
00390 uint8_t RTC8564::getTimer(void) 
00391 {
00392     return( getReg(REG_TIMER) ) ;
00393 }
00394 
00395 void RTC8564::start(void)
00396 {
00397     setReg(REG_CONTROL1, 0x00) ;
00398 }
00399 
00400 void RTC8564::stop(void)
00401 {
00402     setReg(REG_CONTROL1, 0x01) ;
00403 }