RX-8025NB Real Time Clock Module by EPSON

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

Committer:
kenjiArai
Date:
Fri Aug 07 05:38:04 2020 +0000
Revision:
7:4793c4817590
Parent:
6:414dbeb77add
Child:
8:c8aebe7e802d
added FOUT enable/disable function. small modification for several functions.

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 7:4793c4817590 121 uint16_t set;
kenjiArai 2:ce49c4ba4c02 122
kenjiArai 2:ce49c4ba4c02 123 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 3:d59c12d14ca9 124 dt &= ~0x40; // DALE = 0
kenjiArai 2:ce49c4ba4c02 125 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 2:ce49c4ba4c02 126 read_rtc_std(&t); // read current time
kenjiArai 7:4793c4817590 127 set = time + t.tm_hour * 60 + t.tm_min;
kenjiArai 4:d8ce59684dfa 128 m = t.tm_min + (uint8_t)(time % 60);
kenjiArai 4:d8ce59684dfa 129 h = t.tm_hour;
kenjiArai 6:414dbeb77add 130 if (m >= 60) {
kenjiArai 3:d59c12d14ca9 131 m -= 60;
kenjiArai 3:d59c12d14ca9 132 h += 1;
kenjiArai 3:d59c12d14ca9 133 }
kenjiArai 4:d8ce59684dfa 134 h += (uint8_t)(time / 60);
kenjiArai 6:414dbeb77add 135 if (h >= 24) {
kenjiArai 3:d59c12d14ca9 136 h -= 24;
kenjiArai 3:d59c12d14ca9 137 }
kenjiArai 3:d59c12d14ca9 138 rtc_buf[2] = bin2bcd(h);
kenjiArai 3:d59c12d14ca9 139 rtc_buf[1] = bin2bcd(m);
kenjiArai 2:ce49c4ba4c02 140 rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4;
kenjiArai 7:4793c4817590 141 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 2:ce49c4ba4c02 142 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 6:414dbeb77add 143 dt |= 0x60; // DALE = 1
kenjiArai 2:ce49c4ba4c02 144 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 4:d8ce59684dfa 145 }
kenjiArai 4:d8ce59684dfa 146
kenjiArai 7:4793c4817590 147 void RX8025::set_next_IRQ (uint16_t time)
kenjiArai 7:4793c4817590 148 {
kenjiArai 7:4793c4817590 149 set_next_alarmD_INTA(time);
kenjiArai 7:4793c4817590 150 }
kenjiArai 7:4793c4817590 151
kenjiArai 6:414dbeb77add 152 void RX8025::set_next_alarmD_INTA (uint16_t time)
kenjiArai 6:414dbeb77add 153 {
kenjiArai 4:d8ce59684dfa 154 uint16_t t;
kenjiArai 4:d8ce59684dfa 155
kenjiArai 6:414dbeb77add 156 if (time < 2) {
kenjiArai 4:d8ce59684dfa 157 // Alarm does not check seconds digit.
kenjiArai 7:4793c4817590 158 // If 59 to 0 is occured during setting here,
kenjiArai 7:4793c4817590 159 // 1 minute will have a trouble.
kenjiArai 4:d8ce59684dfa 160 t = 2;
kenjiArai 7:4793c4817590 161 } else if (time > 1440) { // set less than 24 hours
kenjiArai 4:d8ce59684dfa 162 t = 1440;
kenjiArai 4:d8ce59684dfa 163 } else {
kenjiArai 4:d8ce59684dfa 164 t = time;
kenjiArai 4:d8ce59684dfa 165 }
kenjiArai 6:414dbeb77add 166 set_alarmD_reg(t);
kenjiArai 2:ce49c4ba4c02 167 }
kenjiArai 2:ce49c4ba4c02 168
kenjiArai 7:4793c4817590 169 /////////////// Clear Alarm-D / INTA interrupt /////////////////////////////////
kenjiArai 7:4793c4817590 170 void RX8025::clear_IRQ()
kenjiArai 7:4793c4817590 171 {
kenjiArai 7:4793c4817590 172 clear_alarmD_INTA();
kenjiArai 7:4793c4817590 173 }
kenjiArai 7:4793c4817590 174
kenjiArai 6:414dbeb77add 175 void RX8025::clear_alarmD_INTA ()
kenjiArai 6:414dbeb77add 176 {
kenjiArai 7:4793c4817590 177 int8_t dt, reg;
kenjiArai 7:4793c4817590 178
kenjiArai 6:414dbeb77add 179 for (uint32_t i = 0; i < 40; i++) {
kenjiArai 6:414dbeb77add 180 reg = read_reg_byte(RX8025_REG_CONTL2);
kenjiArai 6:414dbeb77add 181 if ((reg & 0x01) == 0) {
kenjiArai 6:414dbeb77add 182 break;
kenjiArai 6:414dbeb77add 183 }
kenjiArai 3:d59c12d14ca9 184 dt = reg & 0xfe;
kenjiArai 3:d59c12d14ca9 185 write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 6:414dbeb77add 186 }
kenjiArai 2:ce49c4ba4c02 187 }
kenjiArai 2:ce49c4ba4c02 188
kenjiArai 7:4793c4817590 189 /////////////// Read/Write specific register ///////////////////////////////////
kenjiArai 6:414dbeb77add 190 uint8_t RX8025::read_reg_byte(uint8_t reg)
kenjiArai 6:414dbeb77add 191 {
kenjiArai 2:ce49c4ba4c02 192 rtc_buf[0] = reg << 4;
kenjiArai 7:4793c4817590 193 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 194 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 1, false);
kenjiArai 2:ce49c4ba4c02 195 return rtc_buf[0];
kenjiArai 0:cdf2921959b4 196 }
kenjiArai 0:cdf2921959b4 197
kenjiArai 6:414dbeb77add 198 uint8_t RX8025::write_reg_byte(uint8_t reg, uint8_t data)
kenjiArai 6:414dbeb77add 199 {
kenjiArai 2:ce49c4ba4c02 200 rtc_buf[0] = reg << 4;
kenjiArai 2:ce49c4ba4c02 201 rtc_buf[1] = data;
kenjiArai 7:4793c4817590 202 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 2, false);
kenjiArai 2:ce49c4ba4c02 203 return read_reg_byte(reg);
kenjiArai 0:cdf2921959b4 204 }
kenjiArai 0:cdf2921959b4 205
kenjiArai 7:4793c4817590 206 /////////////// I2C Freq. //////////////////////////////////////////////////////
kenjiArai 6:414dbeb77add 207 void RX8025::frequency(int hz)
kenjiArai 6:414dbeb77add 208 {
kenjiArai 0:cdf2921959b4 209 _i2c.frequency(hz);
kenjiArai 0:cdf2921959b4 210 }
kenjiArai 0:cdf2921959b4 211
kenjiArai 7:4793c4817590 212 /////////////// Read/Write RTC another format //////////////////////////////////
kenjiArai 6:414dbeb77add 213 void RX8025::read_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 214 {
kenjiArai 2:ce49c4ba4c02 215 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 7:4793c4817590 216 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 217 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 10, false);
kenjiArai 0:cdf2921959b4 218 tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f);
kenjiArai 0:cdf2921959b4 219 tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f);
kenjiArai 0:cdf2921959b4 220 tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f);
kenjiArai 0:cdf2921959b4 221 tm->rtc_date = bcd2bin(rtc_buf[RX8025_REG_DAY] & 0x3f);
kenjiArai 0:cdf2921959b4 222 tm->rtc_weekday = rtc_buf[RX8025_REG_WDAY] & 0x07;
kenjiArai 0:cdf2921959b4 223 tm->rtc_month = bcd2bin(rtc_buf[RX8025_REG_MON] & 0x1f);
kenjiArai 0:cdf2921959b4 224 tm->rtc_year_raw= bcd2bin(rtc_buf[RX8025_REG_YEAR]);
kenjiArai 0:cdf2921959b4 225 tm->rtc_year = tm->rtc_year_raw + 100 + 1900;
kenjiArai 0:cdf2921959b4 226 }
kenjiArai 0:cdf2921959b4 227
kenjiArai 6:414dbeb77add 228 void RX8025::write_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 229 {
kenjiArai 0:cdf2921959b4 230 rtc_buf[RX8025_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw);
kenjiArai 2:ce49c4ba4c02 231 rtc_buf[RX8025_REG_MON + 1] = bin2bcd(tm->rtc_month);
kenjiArai 0:cdf2921959b4 232 rtc_buf[RX8025_REG_WDAY + 1] = (tm->rtc_weekday & 0x07);
kenjiArai 2:ce49c4ba4c02 233 rtc_buf[RX8025_REG_DAY + 1] = bin2bcd(tm->rtc_date);
kenjiArai 0:cdf2921959b4 234 rtc_buf[RX8025_REG_HOUR + 1] = bin2bcd(tm->rtc_hours);
kenjiArai 2:ce49c4ba4c02 235 rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes);
kenjiArai 2:ce49c4ba4c02 236 rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds);
kenjiArai 2:ce49c4ba4c02 237 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 7:4793c4817590 238 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 8, false);
kenjiArai 0:cdf2921959b4 239 }
kenjiArai 0:cdf2921959b4 240
kenjiArai 7:4793c4817590 241 /////////////// Square wave output /////////////////////////////////////////////
kenjiArai 7:4793c4817590 242 void RX8025::set_sq_wave (sq_wave_t sqw_dt)
kenjiArai 7:4793c4817590 243 {
kenjiArai 7:4793c4817590 244 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 245 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true);
kenjiArai 7:4793c4817590 246 _i2c.read((int)RX8025_addr, (char *)rtc_buf, 2, false);
kenjiArai 7:4793c4817590 247 if (sqw_dt == RTC_SQW_NONE) { // FOUT is disable
kenjiArai 7:4793c4817590 248 rtc_buf[2] = rtc_buf[1] | 0x08; // CLEN1 = 1
kenjiArai 7:4793c4817590 249 rtc_buf[1] = rtc_buf[0] | 0x10; // CLEN2 = 1
kenjiArai 7:4793c4817590 250 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 251 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 7:4793c4817590 252 } else { // FOUT is enable
kenjiArai 7:4793c4817590 253 rtc_buf[2] = rtc_buf[1] & 0xf7; // CLEN1 = 0
kenjiArai 7:4793c4817590 254 rtc_buf[1] = rtc_buf[0] & 0xef; // CLEN2 = 0
kenjiArai 7:4793c4817590 255 rtc_buf[0] = RX8025_REG_CONTL1 << 4;
kenjiArai 7:4793c4817590 256 _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false);
kenjiArai 7:4793c4817590 257 }
kenjiArai 7:4793c4817590 258 }
kenjiArai 7:4793c4817590 259
kenjiArai 7:4793c4817590 260 /////////////// conversion BCD & BIN ///////////////////////////////////////////
kenjiArai 6:414dbeb77add 261 uint8_t RX8025::bin2bcd (uint8_t dt)
kenjiArai 6:414dbeb77add 262 {
kenjiArai 0:cdf2921959b4 263 uint8_t bcdhigh = 0;
kenjiArai 0:cdf2921959b4 264
kenjiArai 0:cdf2921959b4 265 while (dt >= 10) {
kenjiArai 0:cdf2921959b4 266 bcdhigh++;
kenjiArai 0:cdf2921959b4 267 dt -= 10;
kenjiArai 0:cdf2921959b4 268 }
kenjiArai 0:cdf2921959b4 269 return ((uint8_t)(bcdhigh << 4) | dt);
kenjiArai 0:cdf2921959b4 270 }
kenjiArai 0:cdf2921959b4 271
kenjiArai 6:414dbeb77add 272 uint8_t RX8025::bcd2bin (uint8_t dt)
kenjiArai 6:414dbeb77add 273 {
kenjiArai 0:cdf2921959b4 274 uint8_t tmp = 0;
kenjiArai 0:cdf2921959b4 275
kenjiArai 0:cdf2921959b4 276 tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10;
kenjiArai 0:cdf2921959b4 277 return (tmp + (dt & (uint8_t)0x0f));
kenjiArai 0:cdf2921959b4 278 }