RX-8025NB Real Time Clock Module by EPSON

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

Committer:
kenjiArai
Date:
Tue Dec 17 23:19:54 2019 +0000
Revision:
6:414dbeb77add
Parent:
5:e8e8b1b6c103
Child:
7:4793c4817590
modified init() routine

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 6:414dbeb77add 6 * Copyright (c) 2015,'16,'17,'19 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 6:414dbeb77add 10 * Revised: December 17th, 2019
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 6:414dbeb77add 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 6:414dbeb77add 23 RX8025::RX8025 (I2C& p_i2c) : _i2c(p_i2c)
kenjiArai 6:414dbeb77add 24 {
kenjiArai 0:cdf2921959b4 25 RX8025_addr = RX8025ADDR;
kenjiArai 1:817e81048235 26 init();
kenjiArai 1:817e81048235 27 }
kenjiArai 1:817e81048235 28
kenjiArai 1:817e81048235 29 /////////////// Initialize ////////////////////////////////
kenjiArai 6:414dbeb77add 30 void RX8025::init()
kenjiArai 6:414dbeb77add 31 {
kenjiArai 2:ce49c4ba4c02 32 tm t;
kenjiArai 2:ce49c4ba4c02 33 char dt;
kenjiArai 1:817e81048235 34
kenjiArai 1:817e81048235 35 _i2c.frequency(400000);
kenjiArai 6:414dbeb77add 36 // Set 24H
kenjiArai 6:414dbeb77add 37 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 6:414dbeb77add 38 if (dt & 0x20) { // set already
kenjiArai 6:414dbeb77add 39 ;
kenjiArai 2:ce49c4ba4c02 40 } else {
kenjiArai 2:ce49c4ba4c02 41 dt |= 0x20;
kenjiArai 2:ce49c4ba4c02 42 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 2:ce49c4ba4c02 43 }
kenjiArai 0:cdf2921959b4 44 }
kenjiArai 0:cdf2921959b4 45
kenjiArai 0:cdf2921959b4 46 /////////////// Read RTC data /////////////////////////////
kenjiArai 6:414dbeb77add 47 void RX8025::get_time_rtc (tm *t)
kenjiArai 6:414dbeb77add 48 {
kenjiArai 0:cdf2921959b4 49 read_rtc_std(t);
kenjiArai 0:cdf2921959b4 50 }
kenjiArai 0:cdf2921959b4 51
kenjiArai 6:414dbeb77add 52 void RX8025::read_rtc_std (tm *t)
kenjiArai 6:414dbeb77add 53 {
kenjiArai 0:cdf2921959b4 54 rtc_time time;
kenjiArai 0:cdf2921959b4 55
kenjiArai 0:cdf2921959b4 56 read_rtc_direct(&time);
kenjiArai 0:cdf2921959b4 57 t->tm_sec = time.rtc_seconds;
kenjiArai 0:cdf2921959b4 58 t->tm_min = time.rtc_minutes;
kenjiArai 0:cdf2921959b4 59 t->tm_hour = time.rtc_hours;
kenjiArai 0:cdf2921959b4 60 t->tm_mday = time.rtc_date;
kenjiArai 0:cdf2921959b4 61 if ( time.rtc_weekday == RTC_Wk_Sunday) {
kenjiArai 0:cdf2921959b4 62 t->tm_wday = 0; // Sun is not 7 but 0
kenjiArai 0:cdf2921959b4 63 } else {
kenjiArai 0:cdf2921959b4 64 t->tm_wday = time.rtc_weekday;
kenjiArai 0:cdf2921959b4 65 }
kenjiArai 0:cdf2921959b4 66 t->tm_mon = time.rtc_month - 1;
kenjiArai 0:cdf2921959b4 67 t->tm_year = time.rtc_year_raw + 100;
kenjiArai 0:cdf2921959b4 68 t->tm_isdst= 0;
kenjiArai 0:cdf2921959b4 69 }
kenjiArai 0:cdf2921959b4 70
kenjiArai 0:cdf2921959b4 71 /////////////// Write data to RTC /////////////////////////
kenjiArai 6:414dbeb77add 72 void RX8025::set_time_rtc (tm *t)
kenjiArai 6:414dbeb77add 73 {
kenjiArai 0:cdf2921959b4 74 write_rtc_std(t);
kenjiArai 0:cdf2921959b4 75 }
kenjiArai 0:cdf2921959b4 76
kenjiArai 6:414dbeb77add 77 void RX8025::write_rtc_std (tm *t)
kenjiArai 6:414dbeb77add 78 {
kenjiArai 0:cdf2921959b4 79 rtc_time time;
kenjiArai 0:cdf2921959b4 80
kenjiArai 0:cdf2921959b4 81 time.rtc_seconds = t->tm_sec;
kenjiArai 0:cdf2921959b4 82 time.rtc_minutes = t->tm_min;
kenjiArai 0:cdf2921959b4 83 time.rtc_hours = t->tm_hour;
kenjiArai 0:cdf2921959b4 84 time.rtc_date = t->tm_mday;
kenjiArai 0:cdf2921959b4 85 if ( t->tm_wday == 0) {
kenjiArai 0:cdf2921959b4 86 time.rtc_weekday = RTC_Wk_Sunday;
kenjiArai 0:cdf2921959b4 87 } else {
kenjiArai 0:cdf2921959b4 88 time.rtc_weekday = t->tm_wday;
kenjiArai 0:cdf2921959b4 89 }
kenjiArai 0:cdf2921959b4 90 time.rtc_month = t->tm_mon + 1;
kenjiArai 0:cdf2921959b4 91 time.rtc_year_raw = t->tm_year - 100;
kenjiArai 0:cdf2921959b4 92 write_rtc_direct(&time);
kenjiArai 0:cdf2921959b4 93 }
kenjiArai 0:cdf2921959b4 94
kenjiArai 2:ce49c4ba4c02 95 /////////////// Set Alarm-D / INTA ////////////////////////
kenjiArai 6:414dbeb77add 96 void RX8025::set_alarmD_reg (uint16_t time)
kenjiArai 6:414dbeb77add 97 {
kenjiArai 2:ce49c4ba4c02 98 tm t;
kenjiArai 2:ce49c4ba4c02 99 char dt;
kenjiArai 3:d59c12d14ca9 100 uint8_t m, h;
kenjiArai 4:d8ce59684dfa 101 uint16_t set, real;
kenjiArai 2:ce49c4ba4c02 102
kenjiArai 2:ce49c4ba4c02 103 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 3:d59c12d14ca9 104 dt &= ~0x40; // DALE = 0
kenjiArai 2:ce49c4ba4c02 105 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 2:ce49c4ba4c02 106 read_rtc_std(&t); // read current time
kenjiArai 4:d8ce59684dfa 107 real = t.tm_hour * 60 + t.tm_min;
kenjiArai 4:d8ce59684dfa 108 set = real + time;
kenjiArai 4:d8ce59684dfa 109 m = t.tm_min + (uint8_t)(time % 60);
kenjiArai 4:d8ce59684dfa 110 h = t.tm_hour;
kenjiArai 6:414dbeb77add 111 if (m >= 60) {
kenjiArai 3:d59c12d14ca9 112 m -= 60;
kenjiArai 3:d59c12d14ca9 113 h += 1;
kenjiArai 3:d59c12d14ca9 114 }
kenjiArai 4:d8ce59684dfa 115 h += (uint8_t)(time / 60);
kenjiArai 6:414dbeb77add 116 if (h >= 24) {
kenjiArai 3:d59c12d14ca9 117 h -= 24;
kenjiArai 3:d59c12d14ca9 118 }
kenjiArai 3:d59c12d14ca9 119 rtc_buf[2] = bin2bcd(h);
kenjiArai 3:d59c12d14ca9 120 rtc_buf[1] = bin2bcd(m);
kenjiArai 2:ce49c4ba4c02 121 rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4;
kenjiArai 2:ce49c4ba4c02 122 _i2c.write(RX8025_addr, rtc_buf, 3, false);
kenjiArai 2:ce49c4ba4c02 123 dt = read_reg_byte(RX8025_REG_CONTL1);
kenjiArai 6:414dbeb77add 124 dt |= 0x60; // DALE = 1
kenjiArai 2:ce49c4ba4c02 125 dt = write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 4:d8ce59684dfa 126 }
kenjiArai 4:d8ce59684dfa 127
kenjiArai 6:414dbeb77add 128 //bool RX8025::set_next_alarmD_INTA (uint16_t time)
kenjiArai 6:414dbeb77add 129 void RX8025::set_next_alarmD_INTA (uint16_t time)
kenjiArai 6:414dbeb77add 130 {
kenjiArai 4:d8ce59684dfa 131 uint8_t ret;
kenjiArai 4:d8ce59684dfa 132 uint16_t t;
kenjiArai 4:d8ce59684dfa 133
kenjiArai 6:414dbeb77add 134 if (time < 2) {
kenjiArai 4:d8ce59684dfa 135 // Alarm does not check seconds digit.
kenjiArai 4:d8ce59684dfa 136 // If 59 to 0 is occured during setting here, 1 minute will have a trouble.
kenjiArai 4:d8ce59684dfa 137 t = 2;
kenjiArai 6:414dbeb77add 138 } else if (time > 1440) { // Less than 24 hours
kenjiArai 4:d8ce59684dfa 139 t = 1440;
kenjiArai 4:d8ce59684dfa 140 } else {
kenjiArai 4:d8ce59684dfa 141 t = time;
kenjiArai 4:d8ce59684dfa 142 }
kenjiArai 6:414dbeb77add 143 set_alarmD_reg(t);
kenjiArai 2:ce49c4ba4c02 144 }
kenjiArai 2:ce49c4ba4c02 145
kenjiArai 2:ce49c4ba4c02 146 /////////////// Clear Alarm-D / INTA interrupt ////////////
kenjiArai 6:414dbeb77add 147 void RX8025::clear_alarmD_INTA ()
kenjiArai 6:414dbeb77add 148 {
kenjiArai 3:d59c12d14ca9 149 char dt, reg;
kenjiArai 6:414dbeb77add 150
kenjiArai 6:414dbeb77add 151 for (uint32_t i = 0; i < 40; i++) {
kenjiArai 6:414dbeb77add 152 reg = read_reg_byte(RX8025_REG_CONTL2);
kenjiArai 6:414dbeb77add 153 if ((reg & 0x01) == 0) {
kenjiArai 6:414dbeb77add 154 break;
kenjiArai 6:414dbeb77add 155 }
kenjiArai 3:d59c12d14ca9 156 dt = reg & 0xfe;
kenjiArai 3:d59c12d14ca9 157 write_reg_byte(RX8025_REG_CONTL1, dt);
kenjiArai 6:414dbeb77add 158 }
kenjiArai 2:ce49c4ba4c02 159 }
kenjiArai 2:ce49c4ba4c02 160
kenjiArai 0:cdf2921959b4 161 /////////////// Read/Write specific register //////////////
kenjiArai 6:414dbeb77add 162 uint8_t RX8025::read_reg_byte(uint8_t reg)
kenjiArai 6:414dbeb77add 163 {
kenjiArai 2:ce49c4ba4c02 164 rtc_buf[0] = reg << 4;
kenjiArai 2:ce49c4ba4c02 165 _i2c.write(RX8025_addr, rtc_buf, 1, true);
kenjiArai 2:ce49c4ba4c02 166 _i2c.read(RX8025_addr, rtc_buf, 1, false);
kenjiArai 2:ce49c4ba4c02 167 return rtc_buf[0];
kenjiArai 0:cdf2921959b4 168 }
kenjiArai 0:cdf2921959b4 169
kenjiArai 6:414dbeb77add 170 uint8_t RX8025::write_reg_byte(uint8_t reg, uint8_t data)
kenjiArai 6:414dbeb77add 171 {
kenjiArai 2:ce49c4ba4c02 172 rtc_buf[0] = reg << 4;
kenjiArai 2:ce49c4ba4c02 173 rtc_buf[1] = data;
kenjiArai 2:ce49c4ba4c02 174 _i2c.write(RX8025_addr, rtc_buf, 2, false);
kenjiArai 2:ce49c4ba4c02 175 return read_reg_byte(reg);
kenjiArai 0:cdf2921959b4 176 }
kenjiArai 0:cdf2921959b4 177
kenjiArai 0:cdf2921959b4 178 /////////////// I2C Freq. /////////////////////////////////
kenjiArai 6:414dbeb77add 179 void RX8025::frequency(int hz)
kenjiArai 6:414dbeb77add 180 {
kenjiArai 0:cdf2921959b4 181 _i2c.frequency(hz);
kenjiArai 0:cdf2921959b4 182 }
kenjiArai 0:cdf2921959b4 183
kenjiArai 0:cdf2921959b4 184 /////////////// Read/Write RTC another format /////////////
kenjiArai 6:414dbeb77add 185 void RX8025::read_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 186 {
kenjiArai 2:ce49c4ba4c02 187 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 2:ce49c4ba4c02 188 _i2c.write(RX8025_addr, rtc_buf, 1, true);
kenjiArai 2:ce49c4ba4c02 189 _i2c.read(RX8025_addr, rtc_buf, 10, false);
kenjiArai 0:cdf2921959b4 190 tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f);
kenjiArai 0:cdf2921959b4 191 tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f);
kenjiArai 0:cdf2921959b4 192 tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f);
kenjiArai 0:cdf2921959b4 193 tm->rtc_date = bcd2bin(rtc_buf[RX8025_REG_DAY] & 0x3f);
kenjiArai 0:cdf2921959b4 194 tm->rtc_weekday = rtc_buf[RX8025_REG_WDAY] & 0x07;
kenjiArai 0:cdf2921959b4 195 tm->rtc_month = bcd2bin(rtc_buf[RX8025_REG_MON] & 0x1f);
kenjiArai 0:cdf2921959b4 196 tm->rtc_year_raw= bcd2bin(rtc_buf[RX8025_REG_YEAR]);
kenjiArai 0:cdf2921959b4 197 tm->rtc_year = tm->rtc_year_raw + 100 + 1900;
kenjiArai 0:cdf2921959b4 198 }
kenjiArai 0:cdf2921959b4 199
kenjiArai 6:414dbeb77add 200 void RX8025::write_rtc_direct (rtc_time *tm)
kenjiArai 6:414dbeb77add 201 {
kenjiArai 0:cdf2921959b4 202 rtc_buf[RX8025_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw);
kenjiArai 2:ce49c4ba4c02 203 rtc_buf[RX8025_REG_MON + 1] = bin2bcd(tm->rtc_month);
kenjiArai 0:cdf2921959b4 204 rtc_buf[RX8025_REG_WDAY + 1] = (tm->rtc_weekday & 0x07);
kenjiArai 2:ce49c4ba4c02 205 rtc_buf[RX8025_REG_DAY + 1] = bin2bcd(tm->rtc_date);
kenjiArai 0:cdf2921959b4 206 rtc_buf[RX8025_REG_HOUR + 1] = bin2bcd(tm->rtc_hours);
kenjiArai 2:ce49c4ba4c02 207 rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes);
kenjiArai 2:ce49c4ba4c02 208 rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds);
kenjiArai 2:ce49c4ba4c02 209 rtc_buf[0] = RX8025_REG_SEC << 4;
kenjiArai 2:ce49c4ba4c02 210 _i2c.write(RX8025_addr, rtc_buf, 8, false);
kenjiArai 0:cdf2921959b4 211 }
kenjiArai 0:cdf2921959b4 212
kenjiArai 6:414dbeb77add 213 uint8_t RX8025::bin2bcd (uint8_t dt)
kenjiArai 6:414dbeb77add 214 {
kenjiArai 0:cdf2921959b4 215 uint8_t bcdhigh = 0;
kenjiArai 0:cdf2921959b4 216
kenjiArai 0:cdf2921959b4 217 while (dt >= 10) {
kenjiArai 0:cdf2921959b4 218 bcdhigh++;
kenjiArai 0:cdf2921959b4 219 dt -= 10;
kenjiArai 0:cdf2921959b4 220 }
kenjiArai 0:cdf2921959b4 221 return ((uint8_t)(bcdhigh << 4) | dt);
kenjiArai 0:cdf2921959b4 222 }
kenjiArai 0:cdf2921959b4 223
kenjiArai 6:414dbeb77add 224 uint8_t RX8025::bcd2bin (uint8_t dt)
kenjiArai 6:414dbeb77add 225 {
kenjiArai 0:cdf2921959b4 226 uint8_t tmp = 0;
kenjiArai 0:cdf2921959b4 227
kenjiArai 0:cdf2921959b4 228 tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10;
kenjiArai 0:cdf2921959b4 229 return (tmp + (dt & (uint8_t)0x0f));
kenjiArai 0:cdf2921959b4 230 }