RX-8025NB Real Time Clock Module by EPSON

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

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;