M41T62 is a serial real-time clock (RTC) made by STMicroelectronics.

Dependents:   LPC1114_data_logger Check_external_RTC LPC1114_barometer_with_data_logging

Committer:
kenjiArai
Date:
Sun Jun 22 01:45:49 2014 +0000
Revision:
1:9d7702a887d3
Parent:
0:2919f8bd90f3
Child:
3:41c351da2fdf
modified interface and prepared two way, 1) C Standard struct tm, 2) Own way

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:2919f8bd90f3 1 /*
kenjiArai 0:2919f8bd90f3 2 * mbed library program
kenjiArai 0:2919f8bd90f3 3 * Control M41T62 RTC Module
kenjiArai 0:2919f8bd90f3 4 *
kenjiArai 0:2919f8bd90f3 5 * Copyright (c) 2014 Kenji Arai / JH1PJL
kenjiArai 0:2919f8bd90f3 6 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:2919f8bd90f3 7 * http://mbed.org/users/kenjiArai/
kenjiArai 0:2919f8bd90f3 8 * Created: June 21st, 2014
kenjiArai 1:9d7702a887d3 9 * Revised: June 22nd, 2014
kenjiArai 0:2919f8bd90f3 10 *
kenjiArai 0:2919f8bd90f3 11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:2919f8bd90f3 12 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:2919f8bd90f3 13 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:2919f8bd90f3 14 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:2919f8bd90f3 15 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:2919f8bd90f3 16 */
kenjiArai 0:2919f8bd90f3 17 /*
kenjiArai 0:2919f8bd90f3 18 *---------------- REFERENCE ----------------------------------------------------------------------
kenjiArai 0:2919f8bd90f3 19 * http://www.st-japan.co.jp/web/jp/catalog/sense_power/FM151/CL1410/SC403/PF82507
kenjiArai 1:9d7702a887d3 20 * http://strawberry-linux.com/catalog/items?code=12062
kenjiArai 0:2919f8bd90f3 21 */
kenjiArai 0:2919f8bd90f3 22
kenjiArai 0:2919f8bd90f3 23 #include "mbed.h"
kenjiArai 0:2919f8bd90f3 24 #include "m41t62_rtc.h"
kenjiArai 0:2919f8bd90f3 25
kenjiArai 0:2919f8bd90f3 26 // Register definition
kenjiArai 0:2919f8bd90f3 27 #define M41T62_REG_SSEC 0
kenjiArai 0:2919f8bd90f3 28 #define M41T62_REG_SEC 1
kenjiArai 0:2919f8bd90f3 29 #define M41T62_REG_MIN 2
kenjiArai 0:2919f8bd90f3 30 #define M41T62_REG_HOUR 3
kenjiArai 0:2919f8bd90f3 31 #define M41T62_REG_WDAY 4
kenjiArai 0:2919f8bd90f3 32 #define M41T62_REG_DAY 5
kenjiArai 0:2919f8bd90f3 33 #define M41T62_REG_MON 6
kenjiArai 0:2919f8bd90f3 34 #define M41T62_REG_YEAR 7
kenjiArai 0:2919f8bd90f3 35 #define M41T62_REG_ALARM_MON 0xa
kenjiArai 0:2919f8bd90f3 36 #define M41T62_REG_ALARM_DAY 0xb
kenjiArai 0:2919f8bd90f3 37 #define M41T62_REG_ALARM_HOUR 0xc
kenjiArai 0:2919f8bd90f3 38 #define M41T62_REG_ALARM_MIN 0xd
kenjiArai 0:2919f8bd90f3 39 #define M41T62_REG_ALARM_SEC 0xe
kenjiArai 1:9d7702a887d3 40 #define M41T62_REG_FLAGS 0xf
kenjiArai 0:2919f8bd90f3 41
kenjiArai 1:9d7702a887d3 42 M41T62::M41T62 (PinName p_sda, PinName p_scl) : i2c(p_sda, p_scl){
kenjiArai 1:9d7702a887d3 43 M41T62_addr = M41T62ADDR;
kenjiArai 1:9d7702a887d3 44 }
kenjiArai 1:9d7702a887d3 45
kenjiArai 1:9d7702a887d3 46 M41T62::M41T62 (I2C& p_i2c) : i2c(p_i2c){
kenjiArai 0:2919f8bd90f3 47 M41T62_addr = M41T62ADDR;
kenjiArai 0:2919f8bd90f3 48 }
kenjiArai 0:2919f8bd90f3 49
kenjiArai 1:9d7702a887d3 50 void M41T62::read_rtc_std (tm *t){
kenjiArai 1:9d7702a887d3 51 rtc_time time;
kenjiArai 1:9d7702a887d3 52
kenjiArai 1:9d7702a887d3 53 read_rtc_direct(&time);
kenjiArai 1:9d7702a887d3 54 t->tm_sec = time.rtc_seconds;
kenjiArai 1:9d7702a887d3 55 t->tm_min = time.rtc_minutes;
kenjiArai 1:9d7702a887d3 56 t->tm_hour = time.rtc_hours;
kenjiArai 1:9d7702a887d3 57 t->tm_mday = time.rtc_date;
kenjiArai 1:9d7702a887d3 58 if ( time.rtc_weekday == RTC_Wk_Sunday){
kenjiArai 1:9d7702a887d3 59 t->tm_wday = 0; // Sun is not 7 but 0
kenjiArai 1:9d7702a887d3 60 } else {
kenjiArai 1:9d7702a887d3 61 t->tm_wday = time.rtc_weekday;
kenjiArai 1:9d7702a887d3 62 }
kenjiArai 1:9d7702a887d3 63 t->tm_mon = time.rtc_month - 1;
kenjiArai 1:9d7702a887d3 64 t->tm_year = time.rtc_year_raw + 100;
kenjiArai 1:9d7702a887d3 65 t->tm_isdst= 0;
kenjiArai 0:2919f8bd90f3 66 }
kenjiArai 0:2919f8bd90f3 67
kenjiArai 1:9d7702a887d3 68 void M41T62::write_rtc_std (tm *t){
kenjiArai 1:9d7702a887d3 69 rtc_time time;
kenjiArai 1:9d7702a887d3 70
kenjiArai 1:9d7702a887d3 71 time.rtc_seconds = t->tm_sec;
kenjiArai 1:9d7702a887d3 72 time.rtc_minutes = t->tm_min;
kenjiArai 1:9d7702a887d3 73 time.rtc_hours = t->tm_hour;
kenjiArai 1:9d7702a887d3 74 time.rtc_date = t->tm_mday;
kenjiArai 1:9d7702a887d3 75 if ( t->tm_wday == 0){
kenjiArai 1:9d7702a887d3 76 time.rtc_weekday = RTC_Wk_Sunday;
kenjiArai 1:9d7702a887d3 77 } else {
kenjiArai 1:9d7702a887d3 78 time.rtc_weekday = t->tm_wday;
kenjiArai 1:9d7702a887d3 79 }
kenjiArai 1:9d7702a887d3 80 time.rtc_month = t->tm_mon + 1;
kenjiArai 1:9d7702a887d3 81 time.rtc_year_raw = t->tm_year - 100;
kenjiArai 1:9d7702a887d3 82 write_rtc_direct(&time);
kenjiArai 1:9d7702a887d3 83 }
kenjiArai 1:9d7702a887d3 84
kenjiArai 1:9d7702a887d3 85 void M41T62::read_rtc_direct (rtc_time *tm){
kenjiArai 0:2919f8bd90f3 86 uint8_t eep_dt;
kenjiArai 0:2919f8bd90f3 87
kenjiArai 0:2919f8bd90f3 88 eep_dt = M41T62_REG_SSEC;
kenjiArai 0:2919f8bd90f3 89 i2c_write_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 0:2919f8bd90f3 90 i2c_read_n_bytes((int)M41T62_addr, (char *)rtc_buf, 8);
kenjiArai 0:2919f8bd90f3 91 tm->rtc_seconds = bcd2bin(rtc_buf[M41T62_REG_SEC] & 0x7f);
kenjiArai 0:2919f8bd90f3 92 tm->rtc_minutes = bcd2bin(rtc_buf[M41T62_REG_MIN] & 0x7f);
kenjiArai 0:2919f8bd90f3 93 tm->rtc_hours = bcd2bin(rtc_buf[M41T62_REG_HOUR] & 0x3f);
kenjiArai 0:2919f8bd90f3 94 tm->rtc_date = bcd2bin(rtc_buf[M41T62_REG_DAY] & 0x3f);
kenjiArai 0:2919f8bd90f3 95 tm->rtc_weekday = rtc_buf[M41T62_REG_WDAY] & 0x07;
kenjiArai 0:2919f8bd90f3 96 tm->rtc_month = bcd2bin(rtc_buf[M41T62_REG_MON] & 0x1f);
kenjiArai 1:9d7702a887d3 97 tm->rtc_year_raw= bcd2bin(rtc_buf[M41T62_REG_YEAR]);
kenjiArai 1:9d7702a887d3 98 tm->rtc_year = tm->rtc_year_raw + 100 + 1900;
kenjiArai 0:2919f8bd90f3 99 }
kenjiArai 0:2919f8bd90f3 100
kenjiArai 1:9d7702a887d3 101 void M41T62::write_rtc_direct (rtc_time *tm){
kenjiArai 0:2919f8bd90f3 102 uint8_t eep_dt;
kenjiArai 0:2919f8bd90f3 103
kenjiArai 0:2919f8bd90f3 104 eep_dt = M41T62_REG_SSEC;
kenjiArai 0:2919f8bd90f3 105 i2c_write_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 0:2919f8bd90f3 106 i2c_read_n_bytes((int)M41T62_addr, (char *)rtc_buf, 8);
kenjiArai 0:2919f8bd90f3 107 rtc_buf[0] = M41T62_REG_SSEC;
kenjiArai 0:2919f8bd90f3 108 rtc_buf[M41T62_REG_SSEC + 1] = 0;
kenjiArai 1:9d7702a887d3 109 rtc_buf[M41T62_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw);
kenjiArai 0:2919f8bd90f3 110 rtc_buf[M41T62_REG_MON + 1] = bin2bcd(tm->rtc_month) | (rtc_buf[M41T62_REG_MON] & ~0x1f);
kenjiArai 0:2919f8bd90f3 111 rtc_buf[M41T62_REG_DAY + 1] = bin2bcd(tm->rtc_date) | (rtc_buf[M41T62_REG_DAY] & ~0x3f);
kenjiArai 0:2919f8bd90f3 112 rtc_buf[M41T62_REG_WDAY + 1] = (tm->rtc_weekday & 0x07) | (rtc_buf[M41T62_REG_WDAY] & ~0x07);
kenjiArai 0:2919f8bd90f3 113 rtc_buf[M41T62_REG_HOUR + 1] = bin2bcd(tm->rtc_hours) | (rtc_buf[M41T62_REG_HOUR] & ~0x3f);
kenjiArai 0:2919f8bd90f3 114 rtc_buf[M41T62_REG_MIN + 1] = bin2bcd(tm->rtc_minutes) | (rtc_buf[M41T62_REG_MIN] & ~0x7f);
kenjiArai 0:2919f8bd90f3 115 rtc_buf[M41T62_REG_SEC + 1] = bin2bcd(tm->rtc_seconds) | (rtc_buf[M41T62_REG_SEC] & ~0x7f);
kenjiArai 0:2919f8bd90f3 116 i2c_write_n_bytes((int)M41T62_addr, (char *)rtc_buf, 9);
kenjiArai 0:2919f8bd90f3 117 }
kenjiArai 0:2919f8bd90f3 118
kenjiArai 1:9d7702a887d3 119 void M41T62::set_sq_wave (uint8_t sqw_dt){
kenjiArai 0:2919f8bd90f3 120 uint8_t eep_dt[2];
kenjiArai 0:2919f8bd90f3 121
kenjiArai 1:9d7702a887d3 122 // set SQW frequency
kenjiArai 0:2919f8bd90f3 123 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 0:2919f8bd90f3 124 i2c_write_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 0:2919f8bd90f3 125 i2c_read_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 0:2919f8bd90f3 126 eep_dt[1] = (eep_dt[0] & 0x07) | (sqw_dt << 4);
kenjiArai 0:2919f8bd90f3 127 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 0:2919f8bd90f3 128 i2c_write_n_bytes((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 1:9d7702a887d3 129 // set or clear SQWE
kenjiArai 1:9d7702a887d3 130 eep_dt[0] = M41T62_REG_ALARM_MON;
kenjiArai 1:9d7702a887d3 131 i2c_write_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 1:9d7702a887d3 132 i2c_read_n_bytes((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 1:9d7702a887d3 133 eep_dt[1] = (eep_dt[0] & 0x07) | (sqw_dt << 4);
kenjiArai 1:9d7702a887d3 134 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 1:9d7702a887d3 135 i2c_write_n_bytes((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 1:9d7702a887d3 136 if (sqw_dt == RTC_SQW_NONE){ // Clear SQWE
kenjiArai 1:9d7702a887d3 137 eep_dt[1] = eep_dt[0] & 0xbf;
kenjiArai 1:9d7702a887d3 138 } else { // Set SQWE
kenjiArai 1:9d7702a887d3 139 eep_dt[1] = eep_dt[0] | 0x40;
kenjiArai 1:9d7702a887d3 140 }
kenjiArai 1:9d7702a887d3 141 eep_dt[0] = M41T62_REG_ALARM_MON;
kenjiArai 1:9d7702a887d3 142 i2c_write_n_bytes((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 0:2919f8bd90f3 143 }
kenjiArai 0:2919f8bd90f3 144
kenjiArai 1:9d7702a887d3 145 void M41T62::i2c_read_n_bytes (int addr, char *dt, int n){
kenjiArai 0:2919f8bd90f3 146 i2c.read(addr, dt, n);
kenjiArai 0:2919f8bd90f3 147 }
kenjiArai 0:2919f8bd90f3 148
kenjiArai 1:9d7702a887d3 149 void M41T62::i2c_write_n_bytes (int addr, char *dt, int n){
kenjiArai 0:2919f8bd90f3 150 i2c.write(addr, dt, n);
kenjiArai 0:2919f8bd90f3 151 }
kenjiArai 0:2919f8bd90f3 152
kenjiArai 0:2919f8bd90f3 153 uint8_t M41T62::bin2bcd (uint8_t dt){
kenjiArai 0:2919f8bd90f3 154 uint8_t bcdhigh = 0;
kenjiArai 0:2919f8bd90f3 155
kenjiArai 1:9d7702a887d3 156 while (dt >= 10){
kenjiArai 0:2919f8bd90f3 157 bcdhigh++;
kenjiArai 0:2919f8bd90f3 158 dt -= 10;
kenjiArai 0:2919f8bd90f3 159 }
kenjiArai 0:2919f8bd90f3 160 return ((uint8_t)(bcdhigh << 4) | dt);
kenjiArai 0:2919f8bd90f3 161 }
kenjiArai 0:2919f8bd90f3 162
kenjiArai 0:2919f8bd90f3 163 uint8_t M41T62::bcd2bin (uint8_t dt){
kenjiArai 0:2919f8bd90f3 164 uint8_t tmp = 0;
kenjiArai 0:2919f8bd90f3 165
kenjiArai 0:2919f8bd90f3 166 tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10;
kenjiArai 0:2919f8bd90f3 167 return (tmp + (dt & (uint8_t)0x0f));
kenjiArai 0:2919f8bd90f3 168 }
kenjiArai 0:2919f8bd90f3 169