This is the clock which used highly quality RTC module RT8564NB. This module is I2C controllable. At the time of poweron/reset, the start time received from ntp server. See: http://blogs.yahoo.co.jp/jf1vrr_station/19895596.html (Japanese)
Dependencies: EthernetNetIf NTPClient_NetServices TextLCD mbed
main.cpp@1:7c1d3790f08d, 2011-04-27 (annotated)
- Committer:
- jf1vrr
- Date:
- Wed Apr 27 11:03:21 2011 +0000
- Revision:
- 1:7c1d3790f08d
- Parent:
- 0:50e7bcac5eb9
Rev. 0.01B Add time justify function, sec LED
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jf1vrr | 1:7c1d3790f08d | 1 | /* |
jf1vrr | 1:7c1d3790f08d | 2 | This is the clock which used highly quality RTC module RT8564NB. |
jf1vrr | 0:50e7bcac5eb9 | 3 | This module is I2C controllable. At the time of poweron/reset, the start |
jf1vrr | 1:7c1d3790f08d | 4 | time received from ntp server. |
jf1vrr | 1:7c1d3790f08d | 5 | |
jf1vrr | 1:7c1d3790f08d | 6 | Revision History: |
jf1vrr | 1:7c1d3790f08d | 7 | Rev. 0.01A 2011/04/26 New |
jf1vrr | 1:7c1d3790f08d | 8 | Rev. 0.01B 2011/04/27 Add time justify function, sec LED |
jf1vrr | 0:50e7bcac5eb9 | 9 | */ |
jf1vrr | 0:50e7bcac5eb9 | 10 | #include "mbed.h" |
jf1vrr | 0:50e7bcac5eb9 | 11 | #include "TextLCD.h" |
jf1vrr | 0:50e7bcac5eb9 | 12 | #include "EthernetNetIf.h" |
jf1vrr | 0:50e7bcac5eb9 | 13 | #include "NTPClient.h" |
jf1vrr | 0:50e7bcac5eb9 | 14 | |
jf1vrr | 0:50e7bcac5eb9 | 15 | #define RTC8564NB_ADR 0xA2 |
jf1vrr | 0:50e7bcac5eb9 | 16 | |
jf1vrr | 0:50e7bcac5eb9 | 17 | #define CONTROL1 0x00 |
jf1vrr | 0:50e7bcac5eb9 | 18 | #define CONTROL2 0x01 |
jf1vrr | 0:50e7bcac5eb9 | 19 | #define SECONDS 0x02 |
jf1vrr | 0:50e7bcac5eb9 | 20 | #define MINUTES 0x03 |
jf1vrr | 0:50e7bcac5eb9 | 21 | #define HOURS 0x04 |
jf1vrr | 0:50e7bcac5eb9 | 22 | #define DAYS 0x05 |
jf1vrr | 0:50e7bcac5eb9 | 23 | #define WEEKDAYS 0x06 |
jf1vrr | 0:50e7bcac5eb9 | 24 | #define MONTHS 0x07 |
jf1vrr | 0:50e7bcac5eb9 | 25 | #define YEARS 0x08 |
jf1vrr | 0:50e7bcac5eb9 | 26 | #define MINUTE_ALARM 0x09 |
jf1vrr | 0:50e7bcac5eb9 | 27 | #define HOUR_ALARM 0x0A |
jf1vrr | 0:50e7bcac5eb9 | 28 | #define DAY_ALARM 0x0B |
jf1vrr | 0:50e7bcac5eb9 | 29 | #define WEEKDAY_ALARM 0x0C |
jf1vrr | 0:50e7bcac5eb9 | 30 | #define CLOCKOUT_FREQ 0x0D |
jf1vrr | 0:50e7bcac5eb9 | 31 | #define TIMER_CINTROL 0x0E |
jf1vrr | 0:50e7bcac5eb9 | 32 | #define TIMER 0x0F |
jf1vrr | 0:50e7bcac5eb9 | 33 | #define _READ 0x01 |
jf1vrr | 0:50e7bcac5eb9 | 34 | |
jf1vrr | 0:50e7bcac5eb9 | 35 | TextLCD lcd(p24, p26, p27, p28, p29, p30); |
jf1vrr | 0:50e7bcac5eb9 | 36 | EthernetNetIf eth; |
jf1vrr | 0:50e7bcac5eb9 | 37 | NTPClient ntp; |
jf1vrr | 0:50e7bcac5eb9 | 38 | I2C i2c(p9, p10); |
jf1vrr | 1:7c1d3790f08d | 39 | DigitalOut sec_led(LED1); |
jf1vrr | 1:7c1d3790f08d | 40 | DigitalOut test_led(LED2); |
jf1vrr | 1:7c1d3790f08d | 41 | InterruptIn just_button(p15); |
jf1vrr | 1:7c1d3790f08d | 42 | |
jf1vrr | 0:50e7bcac5eb9 | 43 | int offset_JAPAN = 32400; |
jf1vrr | 0:50e7bcac5eb9 | 44 | |
jf1vrr | 0:50e7bcac5eb9 | 45 | char year, month, day, week; |
jf1vrr | 0:50e7bcac5eb9 | 46 | char hour, minute, sec; |
jf1vrr | 0:50e7bcac5eb9 | 47 | char ntp_year[3], ntp_month[3], ntp_day[3], ntp_week[4]; |
jf1vrr | 0:50e7bcac5eb9 | 48 | char ntp_hour[3], ntp_minute[3], ntp_sec[3]; |
jf1vrr | 0:50e7bcac5eb9 | 49 | char week_val; |
jf1vrr | 0:50e7bcac5eb9 | 50 | |
jf1vrr | 0:50e7bcac5eb9 | 51 | char week_chr[7][4] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; |
jf1vrr | 0:50e7bcac5eb9 | 52 | |
jf1vrr | 0:50e7bcac5eb9 | 53 | void rtc_write(char address, char value) |
jf1vrr | 0:50e7bcac5eb9 | 54 | { |
jf1vrr | 0:50e7bcac5eb9 | 55 | i2c.start(); |
jf1vrr | 0:50e7bcac5eb9 | 56 | i2c.write(RTC8564NB_ADR); |
jf1vrr | 0:50e7bcac5eb9 | 57 | i2c.write(address); |
jf1vrr | 0:50e7bcac5eb9 | 58 | i2c.write(value); |
jf1vrr | 0:50e7bcac5eb9 | 59 | i2c.stop(); |
jf1vrr | 0:50e7bcac5eb9 | 60 | } |
jf1vrr | 0:50e7bcac5eb9 | 61 | |
jf1vrr | 0:50e7bcac5eb9 | 62 | char rtc_read(char address) |
jf1vrr | 0:50e7bcac5eb9 | 63 | { |
jf1vrr | 0:50e7bcac5eb9 | 64 | char value; |
jf1vrr | 0:50e7bcac5eb9 | 65 | i2c.start(); |
jf1vrr | 0:50e7bcac5eb9 | 66 | i2c.write(RTC8564NB_ADR); |
jf1vrr | 0:50e7bcac5eb9 | 67 | i2c.write(address); |
jf1vrr | 0:50e7bcac5eb9 | 68 | i2c.start(); |
jf1vrr | 0:50e7bcac5eb9 | 69 | i2c.write(RTC8564NB_ADR | _READ); |
jf1vrr | 0:50e7bcac5eb9 | 70 | value = i2c.read(0); |
jf1vrr | 0:50e7bcac5eb9 | 71 | i2c.stop(); |
jf1vrr | 0:50e7bcac5eb9 | 72 | |
jf1vrr | 0:50e7bcac5eb9 | 73 | return value; |
jf1vrr | 0:50e7bcac5eb9 | 74 | } |
jf1vrr | 1:7c1d3790f08d | 75 | |
jf1vrr | 1:7c1d3790f08d | 76 | void time_just() |
jf1vrr | 1:7c1d3790f08d | 77 | { |
jf1vrr | 1:7c1d3790f08d | 78 | char _min, _hour; |
jf1vrr | 1:7c1d3790f08d | 79 | test_led = !test_led; |
jf1vrr | 1:7c1d3790f08d | 80 | _min = rtc_read(MINUTES); |
jf1vrr | 1:7c1d3790f08d | 81 | if (_min >= 0x30) { |
jf1vrr | 1:7c1d3790f08d | 82 | _hour = rtc_read(HOURS); |
jf1vrr | 1:7c1d3790f08d | 83 | if (_hour == 0x23) |
jf1vrr | 1:7c1d3790f08d | 84 | _hour = 0x00; |
jf1vrr | 1:7c1d3790f08d | 85 | else if ((_hour & 0x0F) == 0x09) |
jf1vrr | 1:7c1d3790f08d | 86 | _hour = (_hour & 0xF0) + 0x10; |
jf1vrr | 1:7c1d3790f08d | 87 | else |
jf1vrr | 1:7c1d3790f08d | 88 | _hour = _hour + 0x01; |
jf1vrr | 1:7c1d3790f08d | 89 | rtc_write(HOURS, _hour); |
jf1vrr | 1:7c1d3790f08d | 90 | } |
jf1vrr | 1:7c1d3790f08d | 91 | rtc_write(MINUTES, 0x00); |
jf1vrr | 1:7c1d3790f08d | 92 | rtc_write(SECONDS, 0x00); |
jf1vrr | 1:7c1d3790f08d | 93 | } |
jf1vrr | 0:50e7bcac5eb9 | 94 | |
jf1vrr | 0:50e7bcac5eb9 | 95 | int main() { |
jf1vrr | 1:7c1d3790f08d | 96 | just_button.rise(&time_just); |
jf1vrr | 1:7c1d3790f08d | 97 | |
jf1vrr | 0:50e7bcac5eb9 | 98 | lcd.cls(); |
jf1vrr | 0:50e7bcac5eb9 | 99 | lcd.printf("RTC8564NB CLOCK" ); |
jf1vrr | 0:50e7bcac5eb9 | 100 | wait(2.0); |
jf1vrr | 0:50e7bcac5eb9 | 101 | |
jf1vrr | 0:50e7bcac5eb9 | 102 | /* Set up Ethernet */ |
jf1vrr | 0:50e7bcac5eb9 | 103 | lcd.cls(); |
jf1vrr | 0:50e7bcac5eb9 | 104 | lcd.printf("Setting up Eth\n"); |
jf1vrr | 0:50e7bcac5eb9 | 105 | EthernetErr ethErr = eth.setup(); |
jf1vrr | 0:50e7bcac5eb9 | 106 | if (ethErr) { |
jf1vrr | 0:50e7bcac5eb9 | 107 | lcd.cls(); |
jf1vrr | 0:50e7bcac5eb9 | 108 | lcd.printf("Error with Eth\nNum: %d", ethErr); |
jf1vrr | 0:50e7bcac5eb9 | 109 | return -1; |
jf1vrr | 0:50e7bcac5eb9 | 110 | } |
jf1vrr | 0:50e7bcac5eb9 | 111 | |
jf1vrr | 0:50e7bcac5eb9 | 112 | /* Set up NTP */ |
jf1vrr | 0:50e7bcac5eb9 | 113 | lcd.printf("Setting up NTP\n"); |
jf1vrr | 0:50e7bcac5eb9 | 114 | Host server(IpAddr(), 123, "ntp1.jst.mfeed.ad.jp"); |
jf1vrr | 0:50e7bcac5eb9 | 115 | ntp.setTime(server); |
jf1vrr | 0:50e7bcac5eb9 | 116 | |
jf1vrr | 0:50e7bcac5eb9 | 117 | time_t seconds = time(NULL)+offset_JAPAN; |
jf1vrr | 0:50e7bcac5eb9 | 118 | |
jf1vrr | 0:50e7bcac5eb9 | 119 | lcd.cls(); |
jf1vrr | 0:50e7bcac5eb9 | 120 | strftime(ntp_year, 16, "%y", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 121 | strftime(ntp_month, 16, "%m", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 122 | strftime(ntp_day, 16, "%d", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 123 | strftime(ntp_week, 16, "%a", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 124 | strftime(ntp_hour, 16, "%H", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 125 | strftime(ntp_minute, 16, "%M", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 126 | strftime(ntp_sec, 16, "%S", localtime(&seconds)); |
jf1vrr | 0:50e7bcac5eb9 | 127 | |
jf1vrr | 0:50e7bcac5eb9 | 128 | switch (ntp_week[0]){ |
jf1vrr | 0:50e7bcac5eb9 | 129 | case 'S': |
jf1vrr | 0:50e7bcac5eb9 | 130 | switch (ntp_week[1]) { |
jf1vrr | 0:50e7bcac5eb9 | 131 | case 'u': week_val = 0x00; break; |
jf1vrr | 0:50e7bcac5eb9 | 132 | case 'a': week_val = 0x06; break; |
jf1vrr | 0:50e7bcac5eb9 | 133 | } |
jf1vrr | 0:50e7bcac5eb9 | 134 | break; |
jf1vrr | 0:50e7bcac5eb9 | 135 | case 'M': week_val = 0x01; break; |
jf1vrr | 0:50e7bcac5eb9 | 136 | case 'T': |
jf1vrr | 0:50e7bcac5eb9 | 137 | switch (ntp_week[1]) { |
jf1vrr | 0:50e7bcac5eb9 | 138 | case 'u': week_val = 0x02; break; |
jf1vrr | 0:50e7bcac5eb9 | 139 | case 'h': week_val = 0x04; break; |
jf1vrr | 0:50e7bcac5eb9 | 140 | } |
jf1vrr | 0:50e7bcac5eb9 | 141 | break; |
jf1vrr | 0:50e7bcac5eb9 | 142 | case 'W': week_val = 0x03; break; |
jf1vrr | 0:50e7bcac5eb9 | 143 | case 'F': week_val = 0x05; break; |
jf1vrr | 0:50e7bcac5eb9 | 144 | } |
jf1vrr | 0:50e7bcac5eb9 | 145 | |
jf1vrr | 0:50e7bcac5eb9 | 146 | rtc_write(CONTROL1, 0x20); //stop |
jf1vrr | 0:50e7bcac5eb9 | 147 | rtc_write(CONTROL2, 0x00); |
jf1vrr | 0:50e7bcac5eb9 | 148 | rtc_write(YEARS, ((ntp_year[0]-0x30)<<4)+(ntp_year[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 149 | rtc_write(MONTHS, ((ntp_month[0]-0x30)<<4)+(ntp_month[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 150 | rtc_write(DAYS, ((ntp_day[0]-0x30)<<4)+(ntp_day[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 151 | rtc_write(HOURS, ((ntp_hour[0]-0x30)<<4)+(ntp_hour[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 152 | rtc_write(MINUTES, ((ntp_minute[0]-0x30)<<4)+(ntp_minute[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 153 | rtc_write(SECONDS, ((ntp_sec[0]-0x30)<<4)+(ntp_sec[1]-0x30)); |
jf1vrr | 0:50e7bcac5eb9 | 154 | rtc_write(WEEKDAYS, week_val); |
jf1vrr | 0:50e7bcac5eb9 | 155 | rtc_write(CLOCKOUT_FREQ, 0x00); // 0x83 = TE on & 1Hz |
jf1vrr | 0:50e7bcac5eb9 | 156 | rtc_write(TIMER_CINTROL, 0x00); |
jf1vrr | 0:50e7bcac5eb9 | 157 | rtc_write(CONTROL1, 0x00); //start |
jf1vrr | 0:50e7bcac5eb9 | 158 | |
jf1vrr | 0:50e7bcac5eb9 | 159 | while(1) { |
jf1vrr | 0:50e7bcac5eb9 | 160 | year = rtc_read(YEARS); |
jf1vrr | 0:50e7bcac5eb9 | 161 | month = rtc_read(MONTHS); |
jf1vrr | 0:50e7bcac5eb9 | 162 | day = rtc_read(DAYS); |
jf1vrr | 0:50e7bcac5eb9 | 163 | week = rtc_read(WEEKDAYS); |
jf1vrr | 0:50e7bcac5eb9 | 164 | hour = rtc_read(HOURS); |
jf1vrr | 0:50e7bcac5eb9 | 165 | minute = rtc_read(MINUTES); |
jf1vrr | 0:50e7bcac5eb9 | 166 | sec = rtc_read(SECONDS); |
jf1vrr | 0:50e7bcac5eb9 | 167 | lcd.locate(0,0); |
jf1vrr | 0:50e7bcac5eb9 | 168 | lcd.printf("20%c%c/%c%c/%c%c %s", |
jf1vrr | 0:50e7bcac5eb9 | 169 | ((year >> 4) & 0x03) + 0x30, (year & 0x0F) + 0x30, |
jf1vrr | 0:50e7bcac5eb9 | 170 | ((month >> 4) & 0x01) + 0x30, (month & 0x0F) + 0x30, |
jf1vrr | 0:50e7bcac5eb9 | 171 | ((day >> 4) & 0x03)+ 0x30, (day & 0x0F) + 0x30, |
jf1vrr | 0:50e7bcac5eb9 | 172 | week_chr[week & 0x07]); |
jf1vrr | 0:50e7bcac5eb9 | 173 | lcd.locate(0,1); |
jf1vrr | 0:50e7bcac5eb9 | 174 | lcd.printf("%c%c:%c%c:%c%c", |
jf1vrr | 0:50e7bcac5eb9 | 175 | ((hour >> 4) & 0x03) + 0x30, (hour & 0x0F) + 0x30, |
jf1vrr | 0:50e7bcac5eb9 | 176 | (minute >> 4) + 0x30, (minute & 0x0F) + 0x30, |
jf1vrr | 0:50e7bcac5eb9 | 177 | (sec >> 4) + 0x30, (sec & 0x0F) + 0x30 ); |
jf1vrr | 1:7c1d3790f08d | 178 | |
jf1vrr | 1:7c1d3790f08d | 179 | sec_led = !sec_led; |
jf1vrr | 1:7c1d3790f08d | 180 | wait(0.5); |
jf1vrr | 0:50e7bcac5eb9 | 181 | } |
jf1vrr | 0:50e7bcac5eb9 | 182 | } |