RX-8025NB Real Time Clock Module by EPSON
Dependents: TYBLE16_simple_data_logger Check_external_RTC
Diff: RX8025NB.cpp
- Revision:
- 7:4793c4817590
- Parent:
- 6:414dbeb77add
- Child:
- 8:c8aebe7e802d
--- a/RX8025NB.cpp Tue Dec 17 23:19:54 2019 +0000 +++ b/RX8025NB.cpp Fri Aug 07 05:38:04 2020 +0000 @@ -3,16 +3,18 @@ * Control RX-8025NB Real Time Clock Module * EPSON * - * Copyright (c) 2015,'16,'17,'19 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * http://mbed.org/users/kenjiArai/ - * Created: June 3rd, 2015 - * Revised: December 17th, 2019 + * Copyright (c) 2015,'16,'17,'19,'20 Kenji Arai / JH1PJL + * http://www7b.biglobe.ne.jp/~kenjia/ + * https://os.mbed.com/users/kenjiArai/ + * Created: June 3rd, 2015 + * Revised: August 7th, 2020 */ #include "mbed.h" #include "RX8025NB.h" +#define RTC_Wk_Sunday ((uint8_t)0x00) + RX8025::RX8025 (PinName p_sda, PinName p_scl) : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) { @@ -26,24 +28,42 @@ init(); } -/////////////// Initialize //////////////////////////////// +/////////////// Initialize ///////////////////////////////////////////////////// void RX8025::init() { tm t; - char dt; + int8_t dt; _i2c.frequency(400000); - // Set 24H - dt = read_reg_byte(RX8025_REG_CONTL1); - if (dt & 0x20) { // set already - ; - } else { + dt = read_reg_byte(RX8025_REG_CONTL2); + if (dt & 0x10) { // Power on reset + dt = write_reg_byte(RX8025_REG_CONTL2, 0); // all clear + // Set 24H + dt = read_reg_byte(RX8025_REG_CONTL1); dt |= 0x20; dt = write_reg_byte(RX8025_REG_CONTL1, dt); + // set January 1st,2019 1am as a default + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 1; + t.tm_mday = 1; + t.tm_wday = 0; + t.tm_mon = 0; + t.tm_year = 119; + write_rtc_std(&t); + } else { + // Set 24H + dt = read_reg_byte(RX8025_REG_CONTL1); + if (dt & 0x20) { // set already + ; + } else { + dt |= 0x20; + dt = write_reg_byte(RX8025_REG_CONTL1, dt); + } } } -/////////////// Read RTC data ///////////////////////////// +/////////////// Read RTC data ////////////////////////////////////////////////// void RX8025::get_time_rtc (tm *t) { read_rtc_std(t); @@ -58,7 +78,7 @@ t->tm_min = time.rtc_minutes; t->tm_hour = time.rtc_hours; t->tm_mday = time.rtc_date; - if ( time.rtc_weekday == RTC_Wk_Sunday) { + if (time.rtc_weekday == RTC_Wk_Sunday) { t->tm_wday = 0; // Sun is not 7 but 0 } else { t->tm_wday = time.rtc_weekday; @@ -68,7 +88,7 @@ t->tm_isdst= 0; } -/////////////// Write data to RTC ///////////////////////// +/////////////// Write data to RTC ////////////////////////////////////////////// void RX8025::set_time_rtc (tm *t) { write_rtc_std(t); @@ -92,20 +112,19 @@ write_rtc_direct(&time); } -/////////////// Set Alarm-D / INTA //////////////////////// +/////////////// Set Alarm-D / INTA ///////////////////////////////////////////// void RX8025::set_alarmD_reg (uint16_t time) { tm t; - char dt; + int8_t dt; uint8_t m, h; - uint16_t set, real; + uint16_t set; dt = read_reg_byte(RX8025_REG_CONTL1); dt &= ~0x40; // DALE = 0 dt = write_reg_byte(RX8025_REG_CONTL1, dt); read_rtc_std(&t); // read current time - real = t.tm_hour * 60 + t.tm_min; - set = real + time; + set = time + t.tm_hour * 60 + t.tm_min; m = t.tm_min + (uint8_t)(time % 60); h = t.tm_hour; if (m >= 60) { @@ -119,23 +138,27 @@ rtc_buf[2] = bin2bcd(h); rtc_buf[1] = bin2bcd(m); rtc_buf[0] = RX8025_REG_ALARMD_MIN << 4; - _i2c.write(RX8025_addr, rtc_buf, 3, false); + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false); dt = read_reg_byte(RX8025_REG_CONTL1); dt |= 0x60; // DALE = 1 dt = write_reg_byte(RX8025_REG_CONTL1, dt); } -//bool RX8025::set_next_alarmD_INTA (uint16_t time) +void RX8025::set_next_IRQ (uint16_t time) +{ + set_next_alarmD_INTA(time); +} + void RX8025::set_next_alarmD_INTA (uint16_t time) { - uint8_t ret; uint16_t t; if (time < 2) { // Alarm does not check seconds digit. - // If 59 to 0 is occured during setting here, 1 minute will have a trouble. + // If 59 to 0 is occured during setting here, + // 1 minute will have a trouble. t = 2; - } else if (time > 1440) { // Less than 24 hours + } else if (time > 1440) { // set less than 24 hours t = 1440; } else { t = time; @@ -143,11 +166,16 @@ set_alarmD_reg(t); } -/////////////// Clear Alarm-D / INTA interrupt //////////// +/////////////// Clear Alarm-D / INTA interrupt ///////////////////////////////// +void RX8025::clear_IRQ() +{ + clear_alarmD_INTA(); +} + void RX8025::clear_alarmD_INTA () { - char dt, reg; - + int8_t dt, reg; + for (uint32_t i = 0; i < 40; i++) { reg = read_reg_byte(RX8025_REG_CONTL2); if ((reg & 0x01) == 0) { @@ -158,12 +186,12 @@ } } -/////////////// Read/Write specific register ////////////// +/////////////// Read/Write specific register /////////////////////////////////// uint8_t RX8025::read_reg_byte(uint8_t reg) { rtc_buf[0] = reg << 4; - _i2c.write(RX8025_addr, rtc_buf, 1, true); - _i2c.read(RX8025_addr, rtc_buf, 1, false); + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true); + _i2c.read((int)RX8025_addr, (char *)rtc_buf, 1, false); return rtc_buf[0]; } @@ -171,22 +199,22 @@ { rtc_buf[0] = reg << 4; rtc_buf[1] = data; - _i2c.write(RX8025_addr, rtc_buf, 2, false); + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 2, false); return read_reg_byte(reg); } -/////////////// I2C Freq. ///////////////////////////////// +/////////////// I2C Freq. ////////////////////////////////////////////////////// void RX8025::frequency(int hz) { _i2c.frequency(hz); } -/////////////// Read/Write RTC another format ///////////// +/////////////// Read/Write RTC another format ////////////////////////////////// void RX8025::read_rtc_direct (rtc_time *tm) { rtc_buf[0] = RX8025_REG_SEC << 4; - _i2c.write(RX8025_addr, rtc_buf, 1, true); - _i2c.read(RX8025_addr, rtc_buf, 10, false); + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true); + _i2c.read((int)RX8025_addr, (char *)rtc_buf, 10, false); tm->rtc_seconds = bcd2bin(rtc_buf[RX8025_REG_SEC] & 0x7f); tm->rtc_minutes = bcd2bin(rtc_buf[RX8025_REG_MIN] & 0x7f); tm->rtc_hours = bcd2bin(rtc_buf[RX8025_REG_HOUR] & 0x3f); @@ -207,9 +235,29 @@ rtc_buf[RX8025_REG_MIN + 1] = bin2bcd(tm->rtc_minutes); rtc_buf[RX8025_REG_SEC + 1] = bin2bcd(tm->rtc_seconds); rtc_buf[0] = RX8025_REG_SEC << 4; - _i2c.write(RX8025_addr, rtc_buf, 8, false); + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 8, false); } +/////////////// Square wave output ///////////////////////////////////////////// +void RX8025::set_sq_wave (sq_wave_t sqw_dt) +{ + rtc_buf[0] = RX8025_REG_CONTL1 << 4; + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 1, true); + _i2c.read((int)RX8025_addr, (char *)rtc_buf, 2, false); + if (sqw_dt == RTC_SQW_NONE) { // FOUT is disable + rtc_buf[2] = rtc_buf[1] | 0x08; // CLEN1 = 1 + rtc_buf[1] = rtc_buf[0] | 0x10; // CLEN2 = 1 + rtc_buf[0] = RX8025_REG_CONTL1 << 4; + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false); + } else { // FOUT is enable + rtc_buf[2] = rtc_buf[1] & 0xf7; // CLEN1 = 0 + rtc_buf[1] = rtc_buf[0] & 0xef; // CLEN2 = 0 + rtc_buf[0] = RX8025_REG_CONTL1 << 4; + _i2c.write((int)RX8025_addr, (char *)rtc_buf, 3, false); + } +} + +/////////////// conversion BCD & BIN /////////////////////////////////////////// uint8_t RX8025::bin2bcd (uint8_t dt) { uint8_t bcdhigh = 0;