RX-8025NB Real Time Clock Module by EPSON
Dependents: TYBLE16_simple_data_logger Check_external_RTC
RX8025NB.cpp@5:e8e8b1b6c103, 2017-08-22 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Aug 22 10:16:48 2017 +0000
- Revision:
- 5:e8e8b1b6c103
- Parent:
- 4:d8ce59684dfa
- Child:
- 6:414dbeb77add
countermeasure for NonCopyable
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:cdf2921959b4 | 1 | /* |
kenjiArai | 0:cdf2921959b4 | 2 | * mbed library program |
kenjiArai | 0:cdf2921959b4 | 3 | * Control RX-8025NB Real Time Clock Module |
kenjiArai | 0:cdf2921959b4 | 4 | * EPSON |
kenjiArai | 0:cdf2921959b4 | 5 | * |
kenjiArai | 5:e8e8b1b6c103 | 6 | * Copyright (c) 2015,'16,'17 Kenji Arai / JH1PJL |
kenjiArai | 0:cdf2921959b4 | 7 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:cdf2921959b4 | 8 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:cdf2921959b4 | 9 | * Created: June 3rd, 2015 |
kenjiArai | 5:e8e8b1b6c103 | 10 | * Revised: August 21st, 2017 |
kenjiArai | 0:cdf2921959b4 | 11 | */ |
kenjiArai | 0:cdf2921959b4 | 12 | |
kenjiArai | 0:cdf2921959b4 | 13 | #include "mbed.h" |
kenjiArai | 0:cdf2921959b4 | 14 | #include "RX8025NB.h" |
kenjiArai | 0:cdf2921959b4 | 15 | |
kenjiArai | 5:e8e8b1b6c103 | 16 | RX8025::RX8025 (PinName p_sda, PinName p_scl) : |
kenjiArai | 5:e8e8b1b6c103 | 17 | _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) |
kenjiArai | 5:e8e8b1b6c103 | 18 | { |
kenjiArai | 0:cdf2921959b4 | 19 | RX8025_addr = RX8025ADDR; |
kenjiArai | 1:817e81048235 | 20 | init(); |
kenjiArai | 0:cdf2921959b4 | 21 | } |
kenjiArai | 0:cdf2921959b4 | 22 | |
kenjiArai | 3:d59c12d14ca9 | 23 | RX8025::RX8025 (I2C& p_i2c) : _i2c(p_i2c){ |
kenjiArai | 0:cdf2921959b4 | 24 | RX8025_addr = RX8025ADDR; |
kenjiArai | 1:817e81048235 | 25 | init(); |
kenjiArai | 1:817e81048235 | 26 | } |
kenjiArai | 1:817e81048235 | 27 | |
kenjiArai | 1:817e81048235 | 28 | /////////////// Initialize //////////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 29 | void RX8025::init(){ |
kenjiArai | 2:ce49c4ba4c02 | 30 | tm t; |
kenjiArai | 2:ce49c4ba4c02 | 31 | char dt; |
kenjiArai | 1:817e81048235 | 32 | |
kenjiArai | 1:817e81048235 | 33 | _i2c.frequency(400000); |
kenjiArai | 2:ce49c4ba4c02 | 34 | dt = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 2:ce49c4ba4c02 | 35 | if (dt & 0x10){ // Power on reset |
kenjiArai | 2:ce49c4ba4c02 | 36 | dt = write_reg_byte(RX8025_REG_CONTL2, 0); // all clear |
kenjiArai | 2:ce49c4ba4c02 | 37 | // Set 24H |
kenjiArai | 2:ce49c4ba4c02 | 38 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 2:ce49c4ba4c02 | 39 | dt |= 0x20; |
kenjiArai | 2:ce49c4ba4c02 | 40 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 41 | // set January 1st,2016 1am as a default |
kenjiArai | 2:ce49c4ba4c02 | 42 | t.tm_sec = 0; |
kenjiArai | 2:ce49c4ba4c02 | 43 | t.tm_min = 0; |
kenjiArai | 2:ce49c4ba4c02 | 44 | t.tm_hour = 1; |
kenjiArai | 2:ce49c4ba4c02 | 45 | t.tm_mday = 1; |
kenjiArai | 2:ce49c4ba4c02 | 46 | t.tm_wday = 0; |
kenjiArai | 2:ce49c4ba4c02 | 47 | t.tm_mon = 0; |
kenjiArai | 2:ce49c4ba4c02 | 48 | t.tm_year = 116; |
kenjiArai | 2:ce49c4ba4c02 | 49 | write_rtc_std(&t); |
kenjiArai | 2:ce49c4ba4c02 | 50 | } else { |
kenjiArai | 2:ce49c4ba4c02 | 51 | // Set 24H |
kenjiArai | 2:ce49c4ba4c02 | 52 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 2:ce49c4ba4c02 | 53 | dt |= 0x20; |
kenjiArai | 2:ce49c4ba4c02 | 54 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 55 | } |
kenjiArai | 0:cdf2921959b4 | 56 | } |
kenjiArai | 0:cdf2921959b4 | 57 | |
kenjiArai | 0:cdf2921959b4 | 58 | /////////////// Read RTC data ///////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 59 | void RX8025::get_time_rtc (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 60 | read_rtc_std(t); |
kenjiArai | 0:cdf2921959b4 | 61 | } |
kenjiArai | 0:cdf2921959b4 | 62 | |
kenjiArai | 3:d59c12d14ca9 | 63 | void RX8025::read_rtc_std (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 64 | rtc_time time; |
kenjiArai | 0:cdf2921959b4 | 65 | |
kenjiArai | 0:cdf2921959b4 | 66 | read_rtc_direct(&time); |
kenjiArai | 0:cdf2921959b4 | 67 | t->tm_sec = time.rtc_seconds; |
kenjiArai | 0:cdf2921959b4 | 68 | t->tm_min = time.rtc_minutes; |
kenjiArai | 0:cdf2921959b4 | 69 | t->tm_hour = time.rtc_hours; |
kenjiArai | 0:cdf2921959b4 | 70 | t->tm_mday = time.rtc_date; |
kenjiArai | 0:cdf2921959b4 | 71 | if ( time.rtc_weekday == RTC_Wk_Sunday) { |
kenjiArai | 0:cdf2921959b4 | 72 | t->tm_wday = 0; // Sun is not 7 but 0 |
kenjiArai | 0:cdf2921959b4 | 73 | } else { |
kenjiArai | 0:cdf2921959b4 | 74 | t->tm_wday = time.rtc_weekday; |
kenjiArai | 0:cdf2921959b4 | 75 | } |
kenjiArai | 0:cdf2921959b4 | 76 | t->tm_mon = time.rtc_month - 1; |
kenjiArai | 0:cdf2921959b4 | 77 | t->tm_year = time.rtc_year_raw + 100; |
kenjiArai | 0:cdf2921959b4 | 78 | t->tm_isdst= 0; |
kenjiArai | 0:cdf2921959b4 | 79 | } |
kenjiArai | 0:cdf2921959b4 | 80 | |
kenjiArai | 0:cdf2921959b4 | 81 | /////////////// Write data to RTC ///////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 82 | void RX8025::set_time_rtc (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 83 | write_rtc_std(t); |
kenjiArai | 0:cdf2921959b4 | 84 | } |
kenjiArai | 0:cdf2921959b4 | 85 | |
kenjiArai | 3:d59c12d14ca9 | 86 | void RX8025::write_rtc_std (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 87 | rtc_time time; |
kenjiArai | 0:cdf2921959b4 | 88 | |
kenjiArai | 0:cdf2921959b4 | 89 | time.rtc_seconds = t->tm_sec; |
kenjiArai | 0:cdf2921959b4 | 90 | time.rtc_minutes = t->tm_min; |
kenjiArai | 0:cdf2921959b4 | 91 | time.rtc_hours = t->tm_hour; |
kenjiArai | 0:cdf2921959b4 | 92 | time.rtc_date = t->tm_mday; |
kenjiArai | 0:cdf2921959b4 | 93 | if ( t->tm_wday == 0) { |
kenjiArai | 0:cdf2921959b4 | 94 | time.rtc_weekday = RTC_Wk_Sunday; |
kenjiArai | 0:cdf2921959b4 | 95 | } else { |
kenjiArai | 0:cdf2921959b4 | 96 | time.rtc_weekday = t->tm_wday; |
kenjiArai | 0:cdf2921959b4 | 97 | } |
kenjiArai | 0:cdf2921959b4 | 98 | time.rtc_month = t->tm_mon + 1; |
kenjiArai | 0:cdf2921959b4 | 99 | time.rtc_year_raw = t->tm_year - 100; |
kenjiArai | 0:cdf2921959b4 | 100 | write_rtc_direct(&time); |
kenjiArai | 0:cdf2921959b4 | 101 | } |
kenjiArai | 0:cdf2921959b4 | 102 | |
kenjiArai | 2:ce49c4ba4c02 | 103 | /////////////// Set Alarm-D / INTA //////////////////////// |
kenjiArai | 4:d8ce59684dfa | 104 | uint8_t RX8025::set_alarmD_reg (uint16_t time){ |
kenjiArai | 2:ce49c4ba4c02 | 105 | tm t; |
kenjiArai | 2:ce49c4ba4c02 | 106 | char dt; |
kenjiArai | 3:d59c12d14ca9 | 107 | uint8_t m, h; |
kenjiArai | 4:d8ce59684dfa | 108 | uint16_t set, real; |
kenjiArai | 2:ce49c4ba4c02 | 109 | |
kenjiArai | 2:ce49c4ba4c02 | 110 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 3:d59c12d14ca9 | 111 | dt &= ~0x40; // DALE = 0 |
kenjiArai | 2:ce49c4ba4c02 | 112 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 113 | read_rtc_std(&t); // read current time |
kenjiArai | 4:d8ce59684dfa | 114 | real = t.tm_hour * 60 + t.tm_min; |
kenjiArai | 4:d8ce59684dfa | 115 | set = real + time; |
kenjiArai | 4:d8ce59684dfa | 116 | m = t.tm_min + (uint8_t)(time % 60); |
kenjiArai | 4:d8ce59684dfa | 117 | h = t.tm_hour; |
kenjiArai | 3:d59c12d14ca9 | 118 | if (m >= 60){ |
kenjiArai | 3:d59c12d14ca9 | 119 | m -= 60; |
kenjiArai | 3:d59c12d14ca9 | 120 | h += 1; |
kenjiArai | 3:d59c12d14ca9 | 121 | } |
kenjiArai | 4:d8ce59684dfa | 122 | h += (uint8_t)(time / 60); |
kenjiArai | 3:d59c12d14ca9 | 123 | if (h >= 24){ |
kenjiArai | 3:d59c12d14ca9 | 124 | h -= 24; |
kenjiArai | 3:d59c12d14ca9 | 125 | } |
kenjiArai | 3:d59c12d14ca9 | 126 | rtc_buf[2] = bin2bcd(h); |
kenjiArai | 3:d59c12d14ca9 | 127 | rtc_buf[1] = bin2bcd(m); |
kenjiArai | 2:ce49c4ba4c02 | 128 | rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4; |
kenjiArai | 2:ce49c4ba4c02 | 129 | _i2c.write(RX8025_addr, rtc_buf, 3, false); |
kenjiArai | 2:ce49c4ba4c02 | 130 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 3:d59c12d14ca9 | 131 | dt |= 0x40; // DALE = 1 |
kenjiArai | 2:ce49c4ba4c02 | 132 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 4:d8ce59684dfa | 133 | real = bcd2bin(read_reg_byte(RX8025_REG_ALARMD_MIN)); |
kenjiArai | 4:d8ce59684dfa | 134 | real += (bcd2bin(read_reg_byte(RX8025_REG_ALARMD_HOUR)) * 60); |
kenjiArai | 4:d8ce59684dfa | 135 | if (set == real) { |
kenjiArai | 4:d8ce59684dfa | 136 | read_rtc_std(&t); // read current time |
kenjiArai | 4:d8ce59684dfa | 137 | real = t.tm_hour * 60 + t.tm_min; |
kenjiArai | 4:d8ce59684dfa | 138 | if (set > real){ |
kenjiArai | 4:d8ce59684dfa | 139 | return 1; |
kenjiArai | 4:d8ce59684dfa | 140 | } else { |
kenjiArai | 4:d8ce59684dfa | 141 | return 0; |
kenjiArai | 4:d8ce59684dfa | 142 | } |
kenjiArai | 4:d8ce59684dfa | 143 | } else { |
kenjiArai | 4:d8ce59684dfa | 144 | return 0; |
kenjiArai | 4:d8ce59684dfa | 145 | } |
kenjiArai | 4:d8ce59684dfa | 146 | } |
kenjiArai | 4:d8ce59684dfa | 147 | |
kenjiArai | 4:d8ce59684dfa | 148 | void RX8025::set_next_alarmD_INTA (uint16_t time){ |
kenjiArai | 4:d8ce59684dfa | 149 | uint8_t ret; |
kenjiArai | 4:d8ce59684dfa | 150 | uint16_t t; |
kenjiArai | 4:d8ce59684dfa | 151 | |
kenjiArai | 4:d8ce59684dfa | 152 | if (time < 2){ |
kenjiArai | 4:d8ce59684dfa | 153 | // Alarm does not check seconds digit. |
kenjiArai | 4:d8ce59684dfa | 154 | // If 59 to 0 is occured during setting here, 1 minute will have a trouble. |
kenjiArai | 4:d8ce59684dfa | 155 | t = 2; |
kenjiArai | 4:d8ce59684dfa | 156 | } else if (time > 1440){ // Less than 24 hours |
kenjiArai | 4:d8ce59684dfa | 157 | t = 1440; |
kenjiArai | 4:d8ce59684dfa | 158 | } else { |
kenjiArai | 4:d8ce59684dfa | 159 | t = time; |
kenjiArai | 4:d8ce59684dfa | 160 | } |
kenjiArai | 4:d8ce59684dfa | 161 | do{ |
kenjiArai | 4:d8ce59684dfa | 162 | ret = set_alarmD_reg(t); |
kenjiArai | 4:d8ce59684dfa | 163 | } while(ret == 0); |
kenjiArai | 2:ce49c4ba4c02 | 164 | } |
kenjiArai | 2:ce49c4ba4c02 | 165 | |
kenjiArai | 2:ce49c4ba4c02 | 166 | /////////////// Clear Alarm-D / INTA interrupt //////////// |
kenjiArai | 3:d59c12d14ca9 | 167 | void RX8025::clear_alarmD_INTA (){ |
kenjiArai | 3:d59c12d14ca9 | 168 | char dt, reg; |
kenjiArai | 3:d59c12d14ca9 | 169 | reg = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 3:d59c12d14ca9 | 170 | do { // make sure to set Hi-imp state |
kenjiArai | 3:d59c12d14ca9 | 171 | dt = reg & 0xfe; |
kenjiArai | 3:d59c12d14ca9 | 172 | write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 3:d59c12d14ca9 | 173 | reg = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 4:d8ce59684dfa | 174 | } while (reg & 0x01); |
kenjiArai | 2:ce49c4ba4c02 | 175 | } |
kenjiArai | 2:ce49c4ba4c02 | 176 | |
kenjiArai | 0:cdf2921959b4 | 177 | /////////////// Read/Write specific register ////////////// |
kenjiArai | 3:d59c12d14ca9 | 178 | uint8_t RX8025::read_reg_byte(uint8_t reg){ |
kenjiArai | 2:ce49c4ba4c02 | 179 | rtc_buf[0] = reg << 4; |
kenjiArai | 2:ce49c4ba4c02 | 180 | _i2c.write(RX8025_addr, rtc_buf, 1, true); |
kenjiArai | 2:ce49c4ba4c02 | 181 | _i2c.read(RX8025_addr, rtc_buf, 1, false); |
kenjiArai | 2:ce49c4ba4c02 | 182 | return rtc_buf[0]; |
kenjiArai | 0:cdf2921959b4 | 183 | } |
kenjiArai | 0:cdf2921959b4 | 184 | |
kenjiArai | 3:d59c12d14ca9 | 185 | uint8_t RX8025::write_reg_byte(uint8_t reg, uint8_t data){ |
kenjiArai | 2:ce49c4ba4c02 | 186 | rtc_buf[0] = reg << 4; |
kenjiArai | 2:ce49c4ba4c02 | 187 | rtc_buf[1] = data; |
kenjiArai | 2:ce49c4ba4c02 | 188 | _i2c.write(RX8025_addr, rtc_buf, 2, false); |
kenjiArai | 2:ce49c4ba4c02 | 189 | return read_reg_byte(reg); |
kenjiArai | 0:cdf2921959b4 | 190 | } |
kenjiArai | 0:cdf2921959b4 | 191 | |
kenjiArai | 0:cdf2921959b4 | 192 | /////////////// I2C Freq. ///////////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 193 | void RX8025::frequency(int hz){ |
kenjiArai | 0:cdf2921959b4 | 194 | _i2c.frequency(hz); |
kenjiArai | 0:cdf2921959b4 | 195 | } |
kenjiArai | 0:cdf2921959b4 | 196 | |
kenjiArai | 0:cdf2921959b4 | 197 | /////////////// Read/Write RTC another format ///////////// |
kenjiArai | 3:d59c12d14ca9 | 198 | void RX8025::read_rtc_direct (rtc_time *tm){ |
kenjiArai | 2:ce49c4ba4c02 | 199 | rtc_buf[0] = RX8025_REG_SEC << 4; |
kenjiArai | 2:ce49c4ba4c02 | 200 | _i2c.write(RX8025_addr, rtc_buf, 1, true); |
kenjiArai | 2:ce49c4ba4c02 | 201 | _i2c.read(RX8025_addr, rtc_buf, 10, false); |
kenjiArai | 0:cdf2921959b4 | 202 | tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f); |
kenjiArai | 0:cdf2921959b4 | 203 | tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f); |
kenjiArai | 0:cdf2921959b4 | 204 | tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f); |
kenjiArai | 0:cdf2921959b4 | 205 | tm->rtc_date = bcd2bin(rtc_buf[RX8025_REG_DAY] & 0x3f); |
kenjiArai | 0:cdf2921959b4 | 206 | tm->rtc_weekday = rtc_buf[RX8025_REG_WDAY] & 0x07; |
kenjiArai | 0:cdf2921959b4 | 207 | tm->rtc_month = bcd2bin(rtc_buf[RX8025_REG_MON] & 0x1f); |
kenjiArai | 0:cdf2921959b4 | 208 | tm->rtc_year_raw= bcd2bin(rtc_buf[RX8025_REG_YEAR]); |
kenjiArai | 0:cdf2921959b4 | 209 | tm->rtc_year = tm->rtc_year_raw + 100 + 1900; |
kenjiArai | 0:cdf2921959b4 | 210 | } |
kenjiArai | 0:cdf2921959b4 | 211 | |
kenjiArai | 4:d8ce59684dfa | 212 | void RX8025::write_rtc_direct (rtc_time *tm){ |
kenjiArai | 0:cdf2921959b4 | 213 | rtc_buf[RX8025_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw); |
kenjiArai | 2:ce49c4ba4c02 | 214 | rtc_buf[RX8025_REG_MON + 1] = bin2bcd(tm->rtc_month); |
kenjiArai | 0:cdf2921959b4 | 215 | rtc_buf[RX8025_REG_WDAY + 1] = (tm->rtc_weekday & 0x07); |
kenjiArai | 2:ce49c4ba4c02 | 216 | rtc_buf[RX8025_REG_DAY + 1] = bin2bcd(tm->rtc_date); |
kenjiArai | 0:cdf2921959b4 | 217 | rtc_buf[RX8025_REG_HOUR + 1] = bin2bcd(tm->rtc_hours); |
kenjiArai | 2:ce49c4ba4c02 | 218 | rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes); |
kenjiArai | 2:ce49c4ba4c02 | 219 | rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds); |
kenjiArai | 2:ce49c4ba4c02 | 220 | rtc_buf[0] = RX8025_REG_SEC << 4; |
kenjiArai | 2:ce49c4ba4c02 | 221 | _i2c.write(RX8025_addr, rtc_buf, 8, false); |
kenjiArai | 0:cdf2921959b4 | 222 | } |
kenjiArai | 0:cdf2921959b4 | 223 | |
kenjiArai | 3:d59c12d14ca9 | 224 | uint8_t RX8025::bin2bcd (uint8_t dt){ |
kenjiArai | 0:cdf2921959b4 | 225 | uint8_t bcdhigh = 0; |
kenjiArai | 0:cdf2921959b4 | 226 | |
kenjiArai | 0:cdf2921959b4 | 227 | while (dt >= 10) { |
kenjiArai | 0:cdf2921959b4 | 228 | bcdhigh++; |
kenjiArai | 0:cdf2921959b4 | 229 | dt -= 10; |
kenjiArai | 0:cdf2921959b4 | 230 | } |
kenjiArai | 0:cdf2921959b4 | 231 | return ((uint8_t)(bcdhigh << 4) | dt); |
kenjiArai | 0:cdf2921959b4 | 232 | } |
kenjiArai | 0:cdf2921959b4 | 233 | |
kenjiArai | 3:d59c12d14ca9 | 234 | uint8_t RX8025::bcd2bin (uint8_t dt){ |
kenjiArai | 0:cdf2921959b4 | 235 | uint8_t tmp = 0; |
kenjiArai | 0:cdf2921959b4 | 236 | |
kenjiArai | 0:cdf2921959b4 | 237 | tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10; |
kenjiArai | 0:cdf2921959b4 | 238 | return (tmp + (dt & (uint8_t)0x0f)); |
kenjiArai | 0:cdf2921959b4 | 239 | } |