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 Feb 22 01:08:24 2015 +0000
Revision:
3:41c351da2fdf
Parent:
1:9d7702a887d3
Child:
4:0c07690cb24f
added change function for  I2C frequency

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:2919f8bd90f3 1 /*
kenjiArai 3:41c351da2fdf 2 * mbed library program
kenjiArai 0:2919f8bd90f3 3 * Control M41T62 RTC Module
kenjiArai 0:2919f8bd90f3 4 *
kenjiArai 3:41c351da2fdf 5 * Copyright (c) 2014,'15 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 3:41c351da2fdf 9 * Revised: Feburary 22nd, 2015
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 3:41c351da2fdf 26 M41T62::M41T62 (PinName p_sda, PinName p_scl) : _i2c(p_sda, p_scl)
kenjiArai 3:41c351da2fdf 27 {
kenjiArai 1:9d7702a887d3 28 M41T62_addr = M41T62ADDR;
kenjiArai 3:41c351da2fdf 29 _i2c.frequency(100000);
kenjiArai 1:9d7702a887d3 30 }
kenjiArai 1:9d7702a887d3 31
kenjiArai 3:41c351da2fdf 32 M41T62::M41T62 (I2C& p_i2c) : _i2c(p_i2c)
kenjiArai 3:41c351da2fdf 33 {
kenjiArai 0:2919f8bd90f3 34 M41T62_addr = M41T62ADDR;
kenjiArai 3:41c351da2fdf 35 _i2c.frequency(100000);
kenjiArai 0:2919f8bd90f3 36 }
kenjiArai 0:2919f8bd90f3 37
kenjiArai 3:41c351da2fdf 38 void M41T62::read_rtc_std (tm *t)
kenjiArai 3:41c351da2fdf 39 {
kenjiArai 3:41c351da2fdf 40 rtc_time time;
kenjiArai 1:9d7702a887d3 41
kenjiArai 1:9d7702a887d3 42 read_rtc_direct(&time);
kenjiArai 1:9d7702a887d3 43 t->tm_sec = time.rtc_seconds;
kenjiArai 1:9d7702a887d3 44 t->tm_min = time.rtc_minutes;
kenjiArai 1:9d7702a887d3 45 t->tm_hour = time.rtc_hours;
kenjiArai 1:9d7702a887d3 46 t->tm_mday = time.rtc_date;
kenjiArai 3:41c351da2fdf 47 if ( time.rtc_weekday == RTC_Wk_Sunday) {
kenjiArai 1:9d7702a887d3 48 t->tm_wday = 0; // Sun is not 7 but 0
kenjiArai 1:9d7702a887d3 49 } else {
kenjiArai 1:9d7702a887d3 50 t->tm_wday = time.rtc_weekday;
kenjiArai 1:9d7702a887d3 51 }
kenjiArai 1:9d7702a887d3 52 t->tm_mon = time.rtc_month - 1;
kenjiArai 1:9d7702a887d3 53 t->tm_year = time.rtc_year_raw + 100;
kenjiArai 1:9d7702a887d3 54 t->tm_isdst= 0;
kenjiArai 0:2919f8bd90f3 55 }
kenjiArai 0:2919f8bd90f3 56
kenjiArai 3:41c351da2fdf 57 void M41T62::write_rtc_std (tm *t)
kenjiArai 3:41c351da2fdf 58 {
kenjiArai 3:41c351da2fdf 59 rtc_time time;
kenjiArai 3:41c351da2fdf 60
kenjiArai 1:9d7702a887d3 61 time.rtc_seconds = t->tm_sec;
kenjiArai 1:9d7702a887d3 62 time.rtc_minutes = t->tm_min;
kenjiArai 1:9d7702a887d3 63 time.rtc_hours = t->tm_hour;
kenjiArai 1:9d7702a887d3 64 time.rtc_date = t->tm_mday;
kenjiArai 3:41c351da2fdf 65 if ( t->tm_wday == 0) {
kenjiArai 1:9d7702a887d3 66 time.rtc_weekday = RTC_Wk_Sunday;
kenjiArai 1:9d7702a887d3 67 } else {
kenjiArai 1:9d7702a887d3 68 time.rtc_weekday = t->tm_wday;
kenjiArai 1:9d7702a887d3 69 }
kenjiArai 1:9d7702a887d3 70 time.rtc_month = t->tm_mon + 1;
kenjiArai 1:9d7702a887d3 71 time.rtc_year_raw = t->tm_year - 100;
kenjiArai 1:9d7702a887d3 72 write_rtc_direct(&time);
kenjiArai 1:9d7702a887d3 73 }
kenjiArai 1:9d7702a887d3 74
kenjiArai 3:41c351da2fdf 75 void M41T62::read_rtc_direct (rtc_time *tm)
kenjiArai 3:41c351da2fdf 76 {
kenjiArai 3:41c351da2fdf 77 uint8_t eep_dt;
kenjiArai 0:2919f8bd90f3 78
kenjiArai 0:2919f8bd90f3 79 eep_dt = M41T62_REG_SSEC;
kenjiArai 3:41c351da2fdf 80 _i2c.write((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 3:41c351da2fdf 81 _i2c.read((int)M41T62_addr, (char *)rtc_buf, 8);
kenjiArai 0:2919f8bd90f3 82 tm->rtc_seconds = bcd2bin(rtc_buf[M41T62_REG_SEC] & 0x7f);
kenjiArai 0:2919f8bd90f3 83 tm->rtc_minutes = bcd2bin(rtc_buf[M41T62_REG_MIN] & 0x7f);
kenjiArai 0:2919f8bd90f3 84 tm->rtc_hours = bcd2bin(rtc_buf[M41T62_REG_HOUR] & 0x3f);
kenjiArai 0:2919f8bd90f3 85 tm->rtc_date = bcd2bin(rtc_buf[M41T62_REG_DAY] & 0x3f);
kenjiArai 0:2919f8bd90f3 86 tm->rtc_weekday = rtc_buf[M41T62_REG_WDAY] & 0x07;
kenjiArai 0:2919f8bd90f3 87 tm->rtc_month = bcd2bin(rtc_buf[M41T62_REG_MON] & 0x1f);
kenjiArai 1:9d7702a887d3 88 tm->rtc_year_raw= bcd2bin(rtc_buf[M41T62_REG_YEAR]);
kenjiArai 1:9d7702a887d3 89 tm->rtc_year = tm->rtc_year_raw + 100 + 1900;
kenjiArai 0:2919f8bd90f3 90 }
kenjiArai 0:2919f8bd90f3 91
kenjiArai 3:41c351da2fdf 92 void M41T62::write_rtc_direct (rtc_time *tm)
kenjiArai 3:41c351da2fdf 93 {
kenjiArai 3:41c351da2fdf 94 uint8_t eep_dt;
kenjiArai 0:2919f8bd90f3 95
kenjiArai 0:2919f8bd90f3 96 eep_dt = M41T62_REG_SSEC;
kenjiArai 3:41c351da2fdf 97 _i2c.write((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 3:41c351da2fdf 98 _i2c.read((int)M41T62_addr, (char *)rtc_buf, 8);
kenjiArai 0:2919f8bd90f3 99 rtc_buf[0] = M41T62_REG_SSEC;
kenjiArai 0:2919f8bd90f3 100 rtc_buf[M41T62_REG_SSEC + 1] = 0;
kenjiArai 3:41c351da2fdf 101 rtc_buf[M41T62_REG_YEAR + 1] = bin2bcd(tm->rtc_year_raw);
kenjiArai 0:2919f8bd90f3 102 rtc_buf[M41T62_REG_MON + 1] = bin2bcd(tm->rtc_month) | (rtc_buf[M41T62_REG_MON] & ~0x1f);
kenjiArai 0:2919f8bd90f3 103 rtc_buf[M41T62_REG_DAY + 1] = bin2bcd(tm->rtc_date) | (rtc_buf[M41T62_REG_DAY] & ~0x3f);
kenjiArai 0:2919f8bd90f3 104 rtc_buf[M41T62_REG_WDAY + 1] = (tm->rtc_weekday & 0x07) | (rtc_buf[M41T62_REG_WDAY] & ~0x07);
kenjiArai 0:2919f8bd90f3 105 rtc_buf[M41T62_REG_HOUR + 1] = bin2bcd(tm->rtc_hours) | (rtc_buf[M41T62_REG_HOUR] & ~0x3f);
kenjiArai 0:2919f8bd90f3 106 rtc_buf[M41T62_REG_MIN + 1] = bin2bcd(tm->rtc_minutes) | (rtc_buf[M41T62_REG_MIN] & ~0x7f);
kenjiArai 3:41c351da2fdf 107 rtc_buf[M41T62_REG_SEC + 1] = bin2bcd(tm->rtc_seconds) | (rtc_buf[M41T62_REG_SEC] & ~0x7f);
kenjiArai 3:41c351da2fdf 108 _i2c.write((int)M41T62_addr, (char *)rtc_buf, 9);
kenjiArai 0:2919f8bd90f3 109 }
kenjiArai 0:2919f8bd90f3 110
kenjiArai 3:41c351da2fdf 111 void M41T62::frequency(int hz)
kenjiArai 3:41c351da2fdf 112 {
kenjiArai 3:41c351da2fdf 113 _i2c.frequency(hz);
kenjiArai 3:41c351da2fdf 114 }
kenjiArai 3:41c351da2fdf 115
kenjiArai 3:41c351da2fdf 116 void M41T62::set_sq_wave (uint8_t sqw_dt)
kenjiArai 3:41c351da2fdf 117 {
kenjiArai 3:41c351da2fdf 118 uint8_t eep_dt[2];
kenjiArai 0:2919f8bd90f3 119
kenjiArai 1:9d7702a887d3 120 // set SQW frequency
kenjiArai 0:2919f8bd90f3 121 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 3:41c351da2fdf 122 _i2c.write((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 3:41c351da2fdf 123 _i2c.read((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 0:2919f8bd90f3 124 eep_dt[1] = (eep_dt[0] & 0x07) | (sqw_dt << 4);
kenjiArai 0:2919f8bd90f3 125 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 3:41c351da2fdf 126 _i2c.write((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 1:9d7702a887d3 127 // set or clear SQWE
kenjiArai 1:9d7702a887d3 128 eep_dt[0] = M41T62_REG_ALARM_MON;
kenjiArai 3:41c351da2fdf 129 _i2c.write((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 3:41c351da2fdf 130 _i2c.read((int)M41T62_addr, (char *)eep_dt, 1);
kenjiArai 1:9d7702a887d3 131 eep_dt[1] = (eep_dt[0] & 0x07) | (sqw_dt << 4);
kenjiArai 1:9d7702a887d3 132 eep_dt[0] = M41T62_REG_WDAY;
kenjiArai 3:41c351da2fdf 133 _i2c.write((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 3:41c351da2fdf 134 if (sqw_dt == RTC_SQW_NONE) { // Clear SQWE
kenjiArai 1:9d7702a887d3 135 eep_dt[1] = eep_dt[0] & 0xbf;
kenjiArai 1:9d7702a887d3 136 } else { // Set SQWE
kenjiArai 1:9d7702a887d3 137 eep_dt[1] = eep_dt[0] | 0x40;
kenjiArai 1:9d7702a887d3 138 }
kenjiArai 1:9d7702a887d3 139 eep_dt[0] = M41T62_REG_ALARM_MON;
kenjiArai 3:41c351da2fdf 140 _i2c.write((int)M41T62_addr, (char *)rtc_buf, 2);
kenjiArai 0:2919f8bd90f3 141 }
kenjiArai 0:2919f8bd90f3 142
kenjiArai 3:41c351da2fdf 143 uint8_t M41T62::bin2bcd (uint8_t dt)
kenjiArai 3:41c351da2fdf 144 {
kenjiArai 3:41c351da2fdf 145 uint8_t bcdhigh = 0;
kenjiArai 0:2919f8bd90f3 146
kenjiArai 3:41c351da2fdf 147 while (dt >= 10) {
kenjiArai 0:2919f8bd90f3 148 bcdhigh++;
kenjiArai 0:2919f8bd90f3 149 dt -= 10;
kenjiArai 0:2919f8bd90f3 150 }
kenjiArai 0:2919f8bd90f3 151 return ((uint8_t)(bcdhigh << 4) | dt);
kenjiArai 0:2919f8bd90f3 152 }
kenjiArai 0:2919f8bd90f3 153
kenjiArai 3:41c351da2fdf 154 uint8_t M41T62::bcd2bin (uint8_t dt)
kenjiArai 3:41c351da2fdf 155 {
kenjiArai 3:41c351da2fdf 156 uint8_t tmp = 0;
kenjiArai 0:2919f8bd90f3 157
kenjiArai 0:2919f8bd90f3 158 tmp = ((uint8_t)(dt & (uint8_t)0xf0) >> (uint8_t)0x4) * 10;
kenjiArai 0:2919f8bd90f3 159 return (tmp + (dt & (uint8_t)0x0f));
kenjiArai 0:2919f8bd90f3 160 }