RX-8025NB Real Time Clock Module by EPSON

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

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?

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 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 }