Kenji Arai / RX8025NB

Dependents:   TYBLE16_simple_data_logger Check_external_RTC

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Fri Aug 07 05:38:04 2020 +0000
Parent:
6:414dbeb77add
Child:
8:c8aebe7e802d
Commit message:
added FOUT enable/disable function. small modification for several functions.

Changed in this revision

RX8025NB.cpp Show annotated file Show diff for this revision Revisions of this file
RX8025NB.h Show annotated file Show diff for this revision Revisions of this file
--- 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;
--- a/RX8025NB.h	Tue Dec 17 23:19:54 2019 +0000
+++ b/RX8025NB.h	Fri Aug 07 05:38:04 2020 +0000
@@ -3,11 +3,11 @@
  *  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
  */
 
 /*
@@ -27,14 +27,6 @@
 //  7bit address = 0b0110010(No other choice)
 #define RX8025ADDR  (0x32 << 1)
 
-#define RTC_Wk_Sunday          ((uint8_t)0x00)
-#define RTC_Wk_Monday          ((uint8_t)0x01)
-#define RTC_Wk_Tuesday         ((uint8_t)0x02)
-#define RTC_Wk_Wednesday       ((uint8_t)0x03)
-#define RTC_Wk_Thursday        ((uint8_t)0x04)
-#define RTC_Wk_Friday          ((uint8_t)0x05)
-#define RTC_Wk_Saturday        ((uint8_t)0x06)
-
 // Register definition
 #define RX8025_REG_SEC         0x0
 #define RX8025_REG_MIN         0x1
@@ -56,12 +48,18 @@
 // Buffer size
 #define RTC_BUF_SIZ            (RX8025_REG_CONTL2 + 5)
 
+typedef enum {
+    RTC_SQW_NONE = 0,
+    RTC_SQW_32KHZ
+} sq_wave_t;
+
 /** Interface for RTC (I2C Interface)  EPSON RX8025
  *
  *  Standalone type RTC via I2C interface
  *
  * @code
  * #include "mbed.h"
+ * #include "RX8025NB.h"
  *
  * // I2C Communication
  *  RX8025     RX8025(dp5,dp27); // RTC(RX8025) SDA, SCL (Fixed address)
@@ -128,25 +126,27 @@
       * @param next time (unit: minutes) from now on minimum = 2 minutes!!
       * @return none
       */
-    void set_next_alarmD_INTA(uint16_t time);
+    void set_next_alarmD_INTA(uint16_t);
+    void set_next_IRQ(uint16_t);
 
     /** Clear Alarm-D / INTA interrupt
       * @param none
       * @return none
       */
     void clear_alarmD_INTA(void);
+    void clear_IRQ(void);
 
     /** Read one byte from specific register
       * @param register address
       * @return register data
       */
-    uint8_t read_reg_byte(uint8_t reg);
+    uint8_t read_reg_byte(uint8_t);
 
     /** Write one byte into specific register
       * @param register address, data
       * @return register saved data
       */
-    uint8_t write_reg_byte(uint8_t reg, uint8_t data);
+    uint8_t write_reg_byte(uint8_t, uint8_t);
 
     /** Read RTC data with own format
       * @param tm (data save area)
@@ -164,7 +164,13 @@
       * @param freq.
       * @return none
       */
-    void frequency(int hz);
+    void frequency(int);
+
+    /** Control FOUT output port (FOE pin must high when 32.768kHz output)
+      * @param output_mode 
+      * @return none
+      */
+    void set_sq_wave(sq_wave_t);
 
 protected:
     I2C *_i2c_p;
@@ -172,12 +178,13 @@
 
     uint8_t bin2bcd(uint8_t);
     uint8_t bcd2bin(uint8_t);
-    void set_alarmD_reg (uint16_t time);
+    void set_alarmD_reg (uint16_t);
     void init(void);
 
 private:
     uint8_t RX8025_addr;
-    char rtc_buf[RTC_BUF_SIZ];   // buffer for RTC
+    uint8_t rtc_buf[RTC_BUF_SIZ];   // buffer for RTC
+
 };
 
 #endif      // RX8025_H