RX-8025NB Real Time Clock Module by EPSON
Dependents: TYBLE16_simple_data_logger Check_external_RTC
RX8025NB.cpp@3:d59c12d14ca9, 2016-05-04 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed May 04 05:42:25 2016 +0000
- Revision:
- 3:d59c12d14ca9
- Parent:
- 2:ce49c4ba4c02
- Child:
- 4:d8ce59684dfa
bug fix Alarm D INT_A
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 | 2:ce49c4ba4c02 | 6 | * Copyright (c) 2015,'16 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 | 3:d59c12d14ca9 | 10 | * Revised: May 4th, 2016 |
kenjiArai | 0:cdf2921959b4 | 11 | * |
kenjiArai | 0:cdf2921959b4 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
kenjiArai | 0:cdf2921959b4 | 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
kenjiArai | 0:cdf2921959b4 | 14 | * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:cdf2921959b4 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
kenjiArai | 0:cdf2921959b4 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:cdf2921959b4 | 17 | */ |
kenjiArai | 0:cdf2921959b4 | 18 | |
kenjiArai | 0:cdf2921959b4 | 19 | #include "mbed.h" |
kenjiArai | 0:cdf2921959b4 | 20 | #include "RX8025NB.h" |
kenjiArai | 0:cdf2921959b4 | 21 | |
kenjiArai | 3:d59c12d14ca9 | 22 | RX8025::RX8025 (PinName p_sda, PinName p_scl) : _i2c(p_sda, p_scl){ |
kenjiArai | 0:cdf2921959b4 | 23 | RX8025_addr = RX8025ADDR; |
kenjiArai | 1:817e81048235 | 24 | init(); |
kenjiArai | 0:cdf2921959b4 | 25 | } |
kenjiArai | 0:cdf2921959b4 | 26 | |
kenjiArai | 3:d59c12d14ca9 | 27 | RX8025::RX8025 (I2C& p_i2c) : _i2c(p_i2c){ |
kenjiArai | 0:cdf2921959b4 | 28 | RX8025_addr = RX8025ADDR; |
kenjiArai | 1:817e81048235 | 29 | init(); |
kenjiArai | 1:817e81048235 | 30 | } |
kenjiArai | 1:817e81048235 | 31 | |
kenjiArai | 1:817e81048235 | 32 | /////////////// Initialize //////////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 33 | void RX8025::init(){ |
kenjiArai | 2:ce49c4ba4c02 | 34 | tm t; |
kenjiArai | 2:ce49c4ba4c02 | 35 | char dt; |
kenjiArai | 1:817e81048235 | 36 | |
kenjiArai | 1:817e81048235 | 37 | _i2c.frequency(400000); |
kenjiArai | 2:ce49c4ba4c02 | 38 | dt = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 2:ce49c4ba4c02 | 39 | if (dt & 0x10){ // Power on reset |
kenjiArai | 2:ce49c4ba4c02 | 40 | dt = write_reg_byte(RX8025_REG_CONTL2, 0); // all clear |
kenjiArai | 2:ce49c4ba4c02 | 41 | // Set 24H |
kenjiArai | 2:ce49c4ba4c02 | 42 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 2:ce49c4ba4c02 | 43 | dt |= 0x20; |
kenjiArai | 2:ce49c4ba4c02 | 44 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 45 | // set January 1st,2016 1am as a default |
kenjiArai | 2:ce49c4ba4c02 | 46 | t.tm_sec = 0; |
kenjiArai | 2:ce49c4ba4c02 | 47 | t.tm_min = 0; |
kenjiArai | 2:ce49c4ba4c02 | 48 | t.tm_hour = 1; |
kenjiArai | 2:ce49c4ba4c02 | 49 | t.tm_mday = 1; |
kenjiArai | 2:ce49c4ba4c02 | 50 | t.tm_wday = 0; |
kenjiArai | 2:ce49c4ba4c02 | 51 | t.tm_mon = 0; |
kenjiArai | 2:ce49c4ba4c02 | 52 | t.tm_year = 116; |
kenjiArai | 2:ce49c4ba4c02 | 53 | write_rtc_std(&t); |
kenjiArai | 2:ce49c4ba4c02 | 54 | } else { |
kenjiArai | 2:ce49c4ba4c02 | 55 | // Set 24H |
kenjiArai | 2:ce49c4ba4c02 | 56 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 2:ce49c4ba4c02 | 57 | dt |= 0x20; |
kenjiArai | 2:ce49c4ba4c02 | 58 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 59 | } |
kenjiArai | 0:cdf2921959b4 | 60 | } |
kenjiArai | 0:cdf2921959b4 | 61 | |
kenjiArai | 0:cdf2921959b4 | 62 | /////////////// Read RTC data ///////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 63 | void RX8025::get_time_rtc (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 64 | read_rtc_std(t); |
kenjiArai | 0:cdf2921959b4 | 65 | } |
kenjiArai | 0:cdf2921959b4 | 66 | |
kenjiArai | 3:d59c12d14ca9 | 67 | void RX8025::read_rtc_std (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 68 | rtc_time time; |
kenjiArai | 0:cdf2921959b4 | 69 | |
kenjiArai | 0:cdf2921959b4 | 70 | read_rtc_direct(&time); |
kenjiArai | 0:cdf2921959b4 | 71 | t->tm_sec = time.rtc_seconds; |
kenjiArai | 0:cdf2921959b4 | 72 | t->tm_min = time.rtc_minutes; |
kenjiArai | 0:cdf2921959b4 | 73 | t->tm_hour = time.rtc_hours; |
kenjiArai | 0:cdf2921959b4 | 74 | t->tm_mday = time.rtc_date; |
kenjiArai | 0:cdf2921959b4 | 75 | if ( time.rtc_weekday == RTC_Wk_Sunday) { |
kenjiArai | 0:cdf2921959b4 | 76 | t->tm_wday = 0; // Sun is not 7 but 0 |
kenjiArai | 0:cdf2921959b4 | 77 | } else { |
kenjiArai | 0:cdf2921959b4 | 78 | t->tm_wday = time.rtc_weekday; |
kenjiArai | 0:cdf2921959b4 | 79 | } |
kenjiArai | 0:cdf2921959b4 | 80 | t->tm_mon = time.rtc_month - 1; |
kenjiArai | 0:cdf2921959b4 | 81 | t->tm_year = time.rtc_year_raw + 100; |
kenjiArai | 0:cdf2921959b4 | 82 | t->tm_isdst= 0; |
kenjiArai | 0:cdf2921959b4 | 83 | } |
kenjiArai | 0:cdf2921959b4 | 84 | |
kenjiArai | 0:cdf2921959b4 | 85 | /////////////// Write data to RTC ///////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 86 | void RX8025::set_time_rtc (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 87 | write_rtc_std(t); |
kenjiArai | 0:cdf2921959b4 | 88 | } |
kenjiArai | 0:cdf2921959b4 | 89 | |
kenjiArai | 3:d59c12d14ca9 | 90 | void RX8025::write_rtc_std (tm *t){ |
kenjiArai | 0:cdf2921959b4 | 91 | rtc_time time; |
kenjiArai | 0:cdf2921959b4 | 92 | |
kenjiArai | 0:cdf2921959b4 | 93 | time.rtc_seconds = t->tm_sec; |
kenjiArai | 0:cdf2921959b4 | 94 | time.rtc_minutes = t->tm_min; |
kenjiArai | 0:cdf2921959b4 | 95 | time.rtc_hours = t->tm_hour; |
kenjiArai | 0:cdf2921959b4 | 96 | time.rtc_date = t->tm_mday; |
kenjiArai | 0:cdf2921959b4 | 97 | if ( t->tm_wday == 0) { |
kenjiArai | 0:cdf2921959b4 | 98 | time.rtc_weekday = RTC_Wk_Sunday; |
kenjiArai | 0:cdf2921959b4 | 99 | } else { |
kenjiArai | 0:cdf2921959b4 | 100 | time.rtc_weekday = t->tm_wday; |
kenjiArai | 0:cdf2921959b4 | 101 | } |
kenjiArai | 0:cdf2921959b4 | 102 | time.rtc_month = t->tm_mon + 1; |
kenjiArai | 0:cdf2921959b4 | 103 | time.rtc_year_raw = t->tm_year - 100; |
kenjiArai | 0:cdf2921959b4 | 104 | write_rtc_direct(&time); |
kenjiArai | 0:cdf2921959b4 | 105 | } |
kenjiArai | 0:cdf2921959b4 | 106 | |
kenjiArai | 2:ce49c4ba4c02 | 107 | /////////////// Set Alarm-D / INTA //////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 108 | void RX8025::set_next_alarmD_INTA (uint16_t time){ |
kenjiArai | 2:ce49c4ba4c02 | 109 | tm t; |
kenjiArai | 2:ce49c4ba4c02 | 110 | char dt; |
kenjiArai | 3:d59c12d14ca9 | 111 | uint8_t m, h; |
kenjiArai | 2:ce49c4ba4c02 | 112 | |
kenjiArai | 2:ce49c4ba4c02 | 113 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 3:d59c12d14ca9 | 114 | dt &= ~0x40; // DALE = 0 |
kenjiArai | 2:ce49c4ba4c02 | 115 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 3:d59c12d14ca9 | 116 | if (time > 1440){ // Less than 24 hours |
kenjiArai | 2:ce49c4ba4c02 | 117 | time = 1440; |
kenjiArai | 3:d59c12d14ca9 | 118 | } else if ((time == 0)){ |
kenjiArai | 3:d59c12d14ca9 | 119 | time = 1; // 1 minute is minimum vale |
kenjiArai | 2:ce49c4ba4c02 | 120 | } |
kenjiArai | 2:ce49c4ba4c02 | 121 | read_rtc_std(&t); // read current time |
kenjiArai | 3:d59c12d14ca9 | 122 | m = t.tm_min + (time % 60); |
kenjiArai | 3:d59c12d14ca9 | 123 | h = t.tm_hour; |
kenjiArai | 3:d59c12d14ca9 | 124 | if (m >= 60){ |
kenjiArai | 3:d59c12d14ca9 | 125 | m -= 60; |
kenjiArai | 3:d59c12d14ca9 | 126 | h += 1; |
kenjiArai | 3:d59c12d14ca9 | 127 | } |
kenjiArai | 3:d59c12d14ca9 | 128 | h = h + (time / 60); |
kenjiArai | 3:d59c12d14ca9 | 129 | if (h >= 24){ |
kenjiArai | 3:d59c12d14ca9 | 130 | h -= 24; |
kenjiArai | 3:d59c12d14ca9 | 131 | } |
kenjiArai | 3:d59c12d14ca9 | 132 | rtc_buf[2] = bin2bcd(h); |
kenjiArai | 3:d59c12d14ca9 | 133 | rtc_buf[1] = bin2bcd(m); |
kenjiArai | 2:ce49c4ba4c02 | 134 | rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4; |
kenjiArai | 2:ce49c4ba4c02 | 135 | _i2c.write(RX8025_addr, rtc_buf, 3, false); |
kenjiArai | 2:ce49c4ba4c02 | 136 | dt = read_reg_byte(RX8025_REG_CONTL1); |
kenjiArai | 3:d59c12d14ca9 | 137 | dt |= 0x40; // DALE = 1 |
kenjiArai | 2:ce49c4ba4c02 | 138 | dt = write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 2:ce49c4ba4c02 | 139 | } |
kenjiArai | 2:ce49c4ba4c02 | 140 | |
kenjiArai | 2:ce49c4ba4c02 | 141 | /////////////// Clear Alarm-D / INTA interrupt //////////// |
kenjiArai | 3:d59c12d14ca9 | 142 | void RX8025::clear_alarmD_INTA (){ |
kenjiArai | 3:d59c12d14ca9 | 143 | char dt, reg; |
kenjiArai | 3:d59c12d14ca9 | 144 | reg = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 3:d59c12d14ca9 | 145 | do { // make sure to set Hi-imp state |
kenjiArai | 3:d59c12d14ca9 | 146 | dt = reg & 0xfe; |
kenjiArai | 3:d59c12d14ca9 | 147 | write_reg_byte(RX8025_REG_CONTL1, dt); |
kenjiArai | 3:d59c12d14ca9 | 148 | reg = read_reg_byte(RX8025_REG_CONTL2); |
kenjiArai | 3:d59c12d14ca9 | 149 | } while (reg & 0x01); |
kenjiArai | 2:ce49c4ba4c02 | 150 | } |
kenjiArai | 2:ce49c4ba4c02 | 151 | |
kenjiArai | 0:cdf2921959b4 | 152 | /////////////// Read/Write specific register ////////////// |
kenjiArai | 3:d59c12d14ca9 | 153 | uint8_t RX8025::read_reg_byte(uint8_t reg){ |
kenjiArai | 2:ce49c4ba4c02 | 154 | rtc_buf[0] = reg << 4; |
kenjiArai | 2:ce49c4ba4c02 | 155 | _i2c.write(RX8025_addr, rtc_buf, 1, true); |
kenjiArai | 2:ce49c4ba4c02 | 156 | _i2c.read(RX8025_addr, rtc_buf, 1, false); |
kenjiArai | 2:ce49c4ba4c02 | 157 | return rtc_buf[0]; |
kenjiArai | 0:cdf2921959b4 | 158 | } |
kenjiArai | 0:cdf2921959b4 | 159 | |
kenjiArai | 3:d59c12d14ca9 | 160 | uint8_t RX8025::write_reg_byte(uint8_t reg, uint8_t data){ |
kenjiArai | 2:ce49c4ba4c02 | 161 | rtc_buf[0] = reg << 4; |
kenjiArai | 2:ce49c4ba4c02 | 162 | rtc_buf[1] = data; |
kenjiArai | 2:ce49c4ba4c02 | 163 | _i2c.write(RX8025_addr, rtc_buf, 2, false); |
kenjiArai | 2:ce49c4ba4c02 | 164 | return read_reg_byte(reg); |
kenjiArai | 0:cdf2921959b4 | 165 | } |
kenjiArai | 0:cdf2921959b4 | 166 | |
kenjiArai | 0:cdf2921959b4 | 167 | /////////////// I2C Freq. ///////////////////////////////// |
kenjiArai | 3:d59c12d14ca9 | 168 | void RX8025::frequency(int hz){ |
kenjiArai | 0:cdf2921959b4 | 169 | _i2c.frequency(hz); |
kenjiArai | 0:cdf2921959b4 | 170 | } |
kenjiArai | 0:cdf2921959b4 | 171 | |
kenjiArai | 0:cdf2921959b4 | 172 | /////////////// Read/Write RTC another format ///////////// |
kenjiArai | 3:d59c12d14ca9 | 173 | void RX8025::read_rtc_direct (rtc_time *tm){ |
kenjiArai | 2:ce49c4ba4c02 | 174 | rtc_buf[0] = RX8025_REG_SEC << 4; |
kenjiArai | 2:ce49c4ba4c02 | 175 | _i2c.write(RX8025_addr, rtc_buf, 1, true); |
kenjiArai | 2:ce49c4ba4c02 | 176 | _i2c.read(RX8025_addr, rtc_buf, 10, false); |
kenjiArai | 0:cdf2921959b4 | 177 | tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f); |
kenjiArai | 0:cdf2921959b4 | 178 | tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f); |
kenjiArai | 0:cdf2921959b4 | 179 | tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f); |
kenjiArai | 0:cdf2921959b4 | 180 | tm->rtc_date = bcd2bin(rtc_buf[RX8025_REG_DAY] & 0x3f); |
kenjiArai | 0:cdf2921959b4 | 181 | tm->rtc_weekday = rtc_buf[RX8025_REG_WDAY] & 0x07; |
kenjiArai | 0:cdf2921959b4 | 182 | tm->rtc_month = bcd2bin(rtc_buf[RX8025_REG_MON] & 0x1f); |
kenjiArai | 0:cdf2921959b4 | 183 | tm->rtc_year_raw= bcd2bin(rtc_buf[RX8025_REG_YEAR]); |
kenjiArai | 0:cdf2921959b4 | 184 | tm->rtc_year = tm->rtc_year_raw + 100 + 1900; |
kenjiArai | 0:cdf2921959b4 | 185 | } |
kenjiArai | 0:cdf2921959b4 | 186 | |
kenjiArai | 0:cdf2921959b4 | 187 | void RX8025::write_rtc_direct (rtc_time *tm) |
kenjiArai | 0:cdf2921959b4 | 188 | { |
kenjiArai | 0:cdf2921959b4 | 189 | rtc_buf[RX8025_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw); |
kenjiArai | 2:ce49c4ba4c02 | 190 | rtc_buf[RX8025_REG_MON + 1] = bin2bcd(tm->rtc_month); |
kenjiArai | 0:cdf2921959b4 | 191 | rtc_buf[RX8025_REG_WDAY + 1] = (tm->rtc_weekday & 0x07); |
kenjiArai | 2:ce49c4ba4c02 | 192 | rtc_buf[RX8025_REG_DAY + 1] = bin2bcd(tm->rtc_date); |
kenjiArai | 0:cdf2921959b4 | 193 | rtc_buf[RX8025_REG_HOUR + 1] = bin2bcd(tm->rtc_hours); |
kenjiArai | 2:ce49c4ba4c02 | 194 | rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes); |
kenjiArai | 2:ce49c4ba4c02 | 195 | rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds); |
kenjiArai | 2:ce49c4ba4c02 | 196 | rtc_buf[0] = RX8025_REG_SEC << 4; |
kenjiArai | 2:ce49c4ba4c02 | 197 | _i2c.write(RX8025_addr, rtc_buf, 8, false); |
kenjiArai | 0:cdf2921959b4 | 198 | } |
kenjiArai | 0:cdf2921959b4 | 199 | |
kenjiArai | 3:d59c12d14ca9 | 200 | uint8_t RX8025::bin2bcd (uint8_t dt){ |
kenjiArai | 0:cdf2921959b4 | 201 | uint8_t bcdhigh = 0; |
kenjiArai | 0:cdf2921959b4 | 202 | |
kenjiArai | 0:cdf2921959b4 | 203 | while (dt >= 10) { |
kenjiArai | 0:cdf2921959b4 | 204 | bcdhigh++; |
kenjiArai | 0:cdf2921959b4 | 205 | dt -= 10; |
kenjiArai | 0:cdf2921959b4 | 206 | } |
kenjiArai | 0:cdf2921959b4 | 207 | return ((uint8_t)(bcdhigh << 4) | dt); |
kenjiArai | 0:cdf2921959b4 | 208 | } |
kenjiArai | 0:cdf2921959b4 | 209 | |
kenjiArai | 3:d59c12d14ca9 | 210 | uint8_t RX8025::bcd2bin (uint8_t dt){ |
kenjiArai | 0:cdf2921959b4 | 211 | uint8_t tmp = 0; |
kenjiArai | 0:cdf2921959b4 | 212 | |
kenjiArai | 0:cdf2921959b4 | 213 | tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10; |
kenjiArai | 0:cdf2921959b4 | 214 | return (tmp + (dt & (uint8_t)0x0f)); |
kenjiArai | 0:cdf2921959b4 | 215 | } |