RX-8025NB Real Time Clock Module by EPSON

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

Committer:
kenjiArai
Date:
Fri Aug 07 06:21:58 2020 +0000
Revision:
8:c8aebe7e802d
Parent:
7:4793c4817590
deleted unused line

Who changed what in which revision?

UserRevisionLine numberNew 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 7:4793c4817590 6 * Copyright (c) 2015,'16,'17,'19,'20 Kenji Arai / JH1PJL
kenjiArai 7:4793c4817590 7 * http://www7b.biglobe.ne.jp/~kenjia/
kenjiArai 7:4793c4817590 8 * https://os.mbed.com/users/kenjiArai/
kenjiArai 7:4793c4817590 9 * Created: June 3rd, 2015
kenjiArai 7:4793c4817590 10 * Revised: August 7th, 2020
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 7:4793c4817590 16 #define RTC_Wk_Sunday ((uint8_t)0x00)
kenjiArai 7:4793c4817590 17
kenjiArai 5:e8e8b1b6c103 18 RX8025::RX8025 (PinName p_sda, PinName p_scl) :
kenjiArai 6:414dbeb77add 19 _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
kenjiArai 5:e8e8b1b6c103 20 {
kenjiArai 0:cdf2921959b4 21 RX8025_addr = RX8025ADDR;
kenjiArai 1:817e81048235 22 init();
kenjiArai 0:cdf2921959b4 23 }
kenjiArai 0:cdf2921959b4 24
kenjiArai 6:414dbeb77add 25 RX8025::RX8025 (I2C& p_i2c) : _i2c(p_i2c)
kenjiArai 6:414dbeb77add 26 {
kenjiArai 0:cdf2921959b4 27 RX8025_addr = RX8025ADDR;
kenjiArai 1:817e81048235 28 init();
kenjiArai 1:817e81048235 29 }
kenjiArai 1:817e81048235 30
kenjiArai 7:4793c4817590 31 /////////////// Initialize /////////////////////////////////////////////////////
kenjiArai 6:414dbeb77add 32 void RX8025::init()
kenjiArai 6:414dbeb77add 33 {
kenjiArai 2:ce49c4ba4c02 34 tm t;
kenjiArai 7:4793c4817590 35 int8_t dt;
kenjiArai 1:817e81048235 36
kenjiArai 1:817e81048235 37 _i2c.frequency(400000);
kenjiArai 7:4793c4817590 38 dt = read_reg_byte(RX8025_REG_CONTL2);
kenjiArai 7:4793c4817590 39 if (dt & 0x10) { // Power on reset
kenjiArai 7:4793c4817590 40 dt = write_reg_byte(RX8025_REG_CONTL2, 0); // all clear
kenjiArai 7:4793c4817590 41 // Set 24H
kenjiArai 7:4793c4817590 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 7:4793c4817590 45 // set January 1st,2019 1am as a default
kenjiArai 7:4793c4817590 46 t.tm_sec = 0;
kenjiArai 7:4793c4817590 47 t.tm_min = 0;
kenjiArai 7:4793c4817590 48 t.tm_hour = 1;
kenjiArai 7:4793c4817590 49 t.tm_mday = 1;
kenjiArai 7:4793c4817590 50 t.tm_wday = 0;
kenjiArai 7:4793c4817590 51 t.tm_mon = 0;
kenjiArai 7:4793c4817590 52 t.tm_year = 119;
kenjiArai 7:4793c4817590 53 write_rtc_std(&t);
kenjiArai 7:4793c4817590 54 } else {
kenjiArai 7:4793c4817590 55 // Set 24H
kenjiArai 7:4793c4817590 56 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 7:4793c4817590 57 if (dt & 0x20) { // set already
kenjiArai 7:4793c4817590 58 ;
kenjiArai 7:4793c4817590 59 } else {
kenjiArai 7:4793c4817590 60 dt |= 0x20;
kenjiArai 7:4793c4817590 61 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 7:4793c4817590 62 }
kenjiArai 2:ce49c4ba4c02 63 }
kenjiArai 0:cdf2921959b4 64 }
kenjiArai 0:cdf2921959b4 65
kenjiArai 7:4793c4817590 66 /////////////// Read RTC data //////////////////////////////////////////////////
kenjiArai 6:414dbeb77add 67 void RX8025::get_time_rtc (tm *t)
kenjiArai 6:414dbeb77add 68 {
kenjiArai 0:cdf2921959b4 69 read_rtc_std(t);
kenjiArai 0:cdf2921959b4 70 }
kenjiArai 0:cdf2921959b4 71
kenjiArai 6:414dbeb77add 72 void RX8025::read_rtc_std (tm *t)
kenjiArai 6:414dbeb77add 73 {
kenjiArai 0:cdf2921959b4 74 rtc_time time;
kenjiArai 0:cdf2921959b4 75
kenjiArai 0:cdf2921959b4 76 read_rtc_direct(&time);
kenjiArai 0:cdf2921959b4 77 t->tm_sec = time.rtc_seconds;
kenjiArai 0:cdf2921959b4 78 t->tm_min = time.rtc_minutes;
kenjiArai 0:cdf2921959b4 79 t->tm_hour = time.rtc_hours;
kenjiArai 0:cdf2921959b4 80 t->tm_mday = time.rtc_date;
kenjiArai 7:4793c4817590 81 if (time.rtc_weekday == RTC_Wk_Sunday) {
kenjiArai 0:cdf2921959b4 82 t->tm_wday = 0; // Sun is not 7 but 0
kenjiArai 0:cdf2921959b4 83 } else {
kenjiArai 0:cdf2921959b4 84 t->tm_wday = time.rtc_weekday;
kenjiArai 0:cdf2921959b4 85 }
kenjiArai 0:cdf2921959b4 86 t->tm_mon = time.rtc_month - 1;
kenjiArai 0:cdf2921959b4 87 t->tm_year = time.rtc_year_raw + 100;
kenjiArai 0:cdf2921959b4 88 t->tm_isdst= 0;
kenjiArai 0:cdf2921959b4 89 }
kenjiArai 0:cdf2921959b4 90
kenjiArai 7:4793c4817590 91 /////////////// Write data to RTC //////////////////////////////////////////////
kenjiArai 6:414dbeb77add 92 void RX8025::set_time_rtc (tm *t)
kenjiArai 6:414dbeb77add 93 {
kenjiArai 0:cdf2921959b4 94 write_rtc_std(t);
kenjiArai 0:cdf2921959b4 95 }
kenjiArai 0:cdf2921959b4 96
kenjiArai 6:414dbeb77add 97 void RX8025::write_rtc_std (tm *t)
kenjiArai 6:414dbeb77add 98 {
kenjiArai 0:cdf2921959b4 99 rtc_time time;
kenjiArai 0:cdf2921959b4 100
kenjiArai 0:cdf2921959b4 101 time.rtc_seconds = t->tm_sec;
kenjiArai 0:cdf2921959b4 102 time.rtc_minutes = t->tm_min;
kenjiArai 0:cdf2921959b4 103 time.rtc_hours = t->tm_hour;
kenjiArai 0:cdf2921959b4 104 time.rtc_date = t->tm_mday;
kenjiArai 0:cdf2921959b4 105 if ( t->tm_wday == 0) {
kenjiArai 0:cdf2921959b4 106 time.rtc_weekday = RTC_Wk_Sunday;
kenjiArai 0:cdf2921959b4 107 } else {
kenjiArai 0:cdf2921959b4 108 time.rtc_weekday = t->tm_wday;
kenjiArai 0:cdf2921959b4 109 }
kenjiArai 0:cdf2921959b4 110 time.rtc_month = t->tm_mon + 1;
kenjiArai 0:cdf2921959b4 111 time.rtc_year_raw = t->tm_year - 100;
kenjiArai 0:cdf2921959b4 112 write_rtc_direct(&time);
kenjiArai 0:cdf2921959b4 113 }
kenjiArai 0:cdf2921959b4 114
kenjiArai 7:4793c4817590 115 /////////////// Set Alarm-D / INTA /////////////////////////////////////////////
kenjiArai 6:414dbeb77add 116 void RX8025::set_alarmD_reg (uint16_t time)
kenjiArai 6:414dbeb77add 117 {
kenjiArai 2:ce49c4ba4c02 118 tm t;
kenjiArai 7:4793c4817590 119 int8_t dt;
kenjiArai 3:d59c12d14ca9 120 uint8_t m, h;
kenjiArai 2:ce49c4ba4c02 121
kenjiArai 2:ce49c4ba4c02 122 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 3:d59c12d14ca9 123 dt &= ~0x40; // DALE = 0
kenjiArai 2:ce49c4ba4c02 124 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 2:ce49c4ba4c02 125 read_rtc_std(&t); // read current time
kenjiArai 4:d8ce59684dfa 126 m = t.tm_min + (uint8_t)(time % 60);
kenjiArai 4:d8ce59684dfa 127 h = t.tm_hour;
kenjiArai 6:414dbeb77add 128 if (m >= 60) {
kenjiArai 3:d59c12d14ca9 129 m -= 60;
kenjiArai 3:d59c12d14ca9 130 h += 1;
kenjiArai 3:d59c12d14ca9 131 }
kenjiArai 4:d8ce59684dfa 132 h += (uint8_t)(time / 60);
kenjiArai 6:414dbeb77add 133 if (h >= 24) {
kenjiArai 3:d59c12d14ca9 134 h -= 24;
kenjiArai 3:d59c12d14ca9 135 }
kenjiArai 3:d59c12d14ca9 136 rtc_buf[2] = bin2bcd(h);
kenjiArai 3:d59c12d14ca9 137 rtc_buf[1] = bin2bcd(m);
kenjiArai 2:ce49c4ba4c02 138 rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4;
kenjiArai 7:4793c4817590 139 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 2:ce49c4ba4c02 140 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 6:414dbeb77add 141 dt |= 0x60; // DALE = 1
kenjiArai 2:ce49c4ba4c02 142 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 4:d8ce59684dfa 143 }
kenjiArai 4:d8ce59684dfa 144
kenjiArai 7:4793c4817590 145 void RX8025::set_next_IRQ (uint16_t time)
kenjiArai 7:4793c4817590 146 {
kenjiArai 7:4793c4817590 147 set_next_alarmD_INTA(time);
kenjiArai 7:4793c4817590 148 }
kenjiArai 7:4793c4817590 149
kenjiArai 6:414dbeb77add 150 void RX8025::set_next_alarmD_INTA (uint16_t time)
kenjiArai 6:414dbeb77add 151 {
kenjiArai 4:d8ce59684dfa 152 uint16_t t;
kenjiArai 4:d8ce59684dfa 153
kenjiArai 6:414dbeb77add 154 if (time < 2) {
kenjiArai 4:d8ce59684dfa 155 // Alarm does not check seconds digit.
kenjiArai 7:4793c4817590 156 // If 59 to 0 is occured during setting here,
kenjiArai 7:4793c4817590 157 // 1 minute will have a trouble.
kenjiArai 4:d8ce59684dfa 158 t = 2;
kenjiArai 7:4793c4817590 159 } else if (time > 1440) { // set less than 24 hours
kenjiArai 4:d8ce59684dfa 160 t = 1440;
kenjiArai 4:d8ce59684dfa 161 } else {
kenjiArai 4:d8ce59684dfa 162 t = time;
kenjiArai 4:d8ce59684dfa 163 }
kenjiArai 6:414dbeb77add 164 set_alarmD_reg(t);
kenjiArai 2:ce49c4ba4c02 165 }
kenjiArai 2:ce49c4ba4c02 166
kenjiArai 7:4793c4817590 167 /////////////// Clear Alarm-D / INTA interrupt /////////////////////////////////
kenjiArai 7:4793c4817590 168 void RX8025::clear_IRQ()
kenjiArai 7:4793c4817590 169 {
kenjiArai 7:4793c4817590 170 clear_alarmD_INTA();
kenjiArai 7:4793c4817590 171 }
kenjiArai 7:4793c4817590 172
kenjiArai 6:414dbeb77add 173 void RX8025::clear_alarmD_INTA ()
kenjiArai 6:414dbeb77add 174 {
kenjiArai 7:4793c4817590 175 int8_t dt, reg;
kenjiArai 7:4793c4817590 176
kenjiArai 6:414dbeb77add 177 for (uint32_t i = 0; i < 40; i++) {
kenjiArai 6:414dbeb77add 178 reg = read_reg_byte(RX8025_REG_CONTL2);
kenjiArai 6:414dbeb77add 179 if ((reg & 0x01) == 0) {
kenjiArai 6:414dbeb77add 180 break;
kenjiArai 6:414dbeb77add 181 }
kenjiArai 3:d59c12d14ca9 182 dt = reg & 0xfe;
kenjiArai 3:d59c12d14ca9 183 write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 6:414dbeb77add 184 }
kenjiArai 2:ce49c4ba4c02 185 }
kenjiArai 2:ce49c4ba4c02 186
kenjiArai 7:4793c4817590 187 /////////////// Read/Write specific register ///////////////////////////////////
kenjiArai 6:414dbeb77add 188 uint8_t RX8025::read_reg_byte(uint8_t reg)
kenjiArai 6:414dbeb77add 189 {
kenjiArai 2:ce49c4ba4c02 190 rtc_buf[0] = reg << 4;
kenjiArai 7:4793c4817590 191 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 192 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 1, false);
kenjiArai 2:ce49c4ba4c02 193 return rtc_buf[0];
kenjiArai 0:cdf2921959b4 194 }
kenjiArai 0:cdf2921959b4 195
kenjiArai 6:414dbeb77add 196 uint8_t RX8025::write_reg_byte(uint8_t reg, uint8_t data)
kenjiArai 6:414dbeb77add 197 {
kenjiArai 2:ce49c4ba4c02 198 rtc_buf[0] = reg << 4;
kenjiArai 2:ce49c4ba4c02 199 rtc_buf[1] = data;
kenjiArai 7:4793c4817590 200 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 2, false);
kenjiArai 2:ce49c4ba4c02 201 return read_reg_byte(reg);
kenjiArai 0:cdf2921959b4 202 }
kenjiArai 0:cdf2921959b4 203
kenjiArai 7:4793c4817590 204 /////////////// I2C Freq. //////////////////////////////////////////////////////
kenjiArai 6:414dbeb77add 205 void RX8025::frequency(int hz)
kenjiArai 6:414dbeb77add 206 {
kenjiArai 0:cdf2921959b4 207 _i2c.frequency(hz);
kenjiArai 0:cdf2921959b4 208 }
kenjiArai 0:cdf2921959b4 209
kenjiArai 7:4793c4817590 210 /////////////// Read/Write RTC another format //////////////////////////////////
kenjiArai 6:414dbeb77add 211 void RX8025::read_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 212 {
kenjiArai 2:ce49c4ba4c02 213 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 7:4793c4817590 214 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 215 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 10, false);
kenjiArai 0:cdf2921959b4 216 tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f);
kenjiArai 0:cdf2921959b4 217 tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f);
kenjiArai 0:cdf2921959b4 218 tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f);
kenjiArai 0:cdf2921959b4 219 tm->rtc_date = bcd2bin(rtc_buf[RX8025_REG_DAY] & 0x3f);
kenjiArai 0:cdf2921959b4 220 tm->rtc_weekday = rtc_buf[RX8025_REG_WDAY] & 0x07;
kenjiArai 0:cdf2921959b4 221 tm->rtc_month = bcd2bin(rtc_buf[RX8025_REG_MON] & 0x1f);
kenjiArai 0:cdf2921959b4 222 tm->rtc_year_raw= bcd2bin(rtc_buf[RX8025_REG_YEAR]);
kenjiArai 0:cdf2921959b4 223 tm->rtc_year = tm->rtc_year_raw + 100 + 1900;
kenjiArai 0:cdf2921959b4 224 }
kenjiArai 0:cdf2921959b4 225
kenjiArai 6:414dbeb77add 226 void RX8025::write_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 227 {
kenjiArai 0:cdf2921959b4 228 rtc_buf[RX8025_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw);
kenjiArai 2:ce49c4ba4c02 229 rtc_buf[RX8025_REG_MON + 1] = bin2bcd(tm->rtc_month);
kenjiArai 0:cdf2921959b4 230 rtc_buf[RX8025_REG_WDAY + 1] = (tm->rtc_weekday & 0x07);
kenjiArai 2:ce49c4ba4c02 231 rtc_buf[RX8025_REG_DAY + 1] = bin2bcd(tm->rtc_date);
kenjiArai 0:cdf2921959b4 232 rtc_buf[RX8025_REG_HOUR + 1] = bin2bcd(tm->rtc_hours);
kenjiArai 2:ce49c4ba4c02 233 rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes);
kenjiArai 2:ce49c4ba4c02 234 rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds);
kenjiArai 2:ce49c4ba4c02 235 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 7:4793c4817590 236 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 8, false);
kenjiArai 0:cdf2921959b4 237 }
kenjiArai 0:cdf2921959b4 238
kenjiArai 7:4793c4817590 239 /////////////// Square wave output /////////////////////////////////////////////
kenjiArai 7:4793c4817590 240 void RX8025::set_sq_wave (sq_wave_t sqw_dt)
kenjiArai 7:4793c4817590 241 {
kenjiArai 7:4793c4817590 242 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 243 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 244 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 2, false);
kenjiArai 7:4793c4817590 245 if (sqw_dt == RTC_SQW_NONE) { // FOUT is disable
kenjiArai 7:4793c4817590 246 rtc_buf[2] = rtc_buf[1] | 0x08; // CLEN1 = 1
kenjiArai 7:4793c4817590 247 rtc_buf[1] = rtc_buf[0] | 0x10; // CLEN2 = 1
kenjiArai 7:4793c4817590 248 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 249 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 7:4793c4817590 250 } else { // FOUT is enable
kenjiArai 7:4793c4817590 251 rtc_buf[2] = rtc_buf[1] & 0xf7; // CLEN1 = 0
kenjiArai 7:4793c4817590 252 rtc_buf[1] = rtc_buf[0] & 0xef; // CLEN2 = 0
kenjiArai 7:4793c4817590 253 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 254 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 7:4793c4817590 255 }
kenjiArai 7:4793c4817590 256 }
kenjiArai 7:4793c4817590 257
kenjiArai 7:4793c4817590 258 /////////////// conversion BCD & BIN ///////////////////////////////////////////
kenjiArai 6:414dbeb77add 259 uint8_t RX8025::bin2bcd (uint8_t dt)
kenjiArai 6:414dbeb77add 260 {
kenjiArai 0:cdf2921959b4 261 uint8_t bcdhigh = 0;
kenjiArai 0:cdf2921959b4 262
kenjiArai 0:cdf2921959b4 263 while (dt >= 10) {
kenjiArai 0:cdf2921959b4 264 bcdhigh++;
kenjiArai 0:cdf2921959b4 265 dt -= 10;
kenjiArai 0:cdf2921959b4 266 }
kenjiArai 0:cdf2921959b4 267 return ((uint8_t)(bcdhigh << 4) | dt);
kenjiArai 0:cdf2921959b4 268 }
kenjiArai 0:cdf2921959b4 269
kenjiArai 6:414dbeb77add 270 uint8_t RX8025::bcd2bin (uint8_t dt)
kenjiArai 6:414dbeb77add 271 {
kenjiArai 0:cdf2921959b4 272 uint8_t tmp = 0;
kenjiArai 0:cdf2921959b4 273
kenjiArai 0:cdf2921959b4 274 tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10;
kenjiArai 0:cdf2921959b4 275 return (tmp + (dt & (uint8_t)0x0f));
kenjiArai 0:cdf2921959b4 276 }