00001
00040 #include <dev/board.h>
00041 #include <dev/debug.h>
00042
00043 #include <sys/version.h>
00044 #include <sys/timer.h>
00045
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <io.h>
00049 #include <string.h>
00050 #include <time.h>
00051
00058 static char *version = "1.0";
00059
00060
00061 static char *rotor = "|/-\\";
00062
00063 static char *weekday_name[7] = {
00064 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
00065 };
00066
00067
00068
00069
00070 static void PrintDateTime(CONST struct _tm *stm)
00071 {
00072 printf("%s, %04d/%02d/%02d, %02d:%02d:%02d%s"
00073 , weekday_name[stm->tm_wday]
00074 , stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday
00075 , stm->tm_hour, stm->tm_min, stm->tm_sec
00076 , stm->tm_isdst ? " DST" : ""
00077 );
00078 }
00079
00080
00081
00082
00083
00084
00085 static int EnterDate(struct _tm *stm)
00086 {
00087 int year;
00088 int mon;
00089 int mday;
00090 int n;
00091
00092 printf("Enter date, use format YYYY/MM/DD (%04d/%02d/%02d): ",
00093 stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday);
00094 n = scanf("%d/%d/%d", &year, &mon, &mday);
00095 if (n >= 1) {
00096 printf("%04d", year);
00097 if (year < 1970 || year > 2038) {
00098 printf("\nBad year: %d is not within range 1970..2038\n", year);
00099 return -1;
00100 }
00101 stm->tm_year = year - 1900;
00102 }
00103 if (n >= 2) {
00104 printf("/%02d", mon);
00105 if (mon < 1 || mon > 31) {
00106 printf("\nBad month: %d is not within range 1..12\n", mon);
00107 return -1;
00108 }
00109 stm->tm_mon = mon - 1;
00110 }
00111 if (n >= 3) {
00112 printf("/%02d", mday);
00113 if (mday < 1 || mday > 31) {
00114 printf("\nBad day: %d is not within range 1..31\n", mday);
00115 return -1;
00116 }
00117 stm->tm_mday = mday;
00118 }
00119 putchar('\n');
00120
00121 return 0;
00122 }
00123
00124
00125
00126
00127
00128
00129 static int EnterTime(struct _tm *stm)
00130 {
00131 int hour;
00132 int minute;
00133 int second;
00134 int n;
00135
00136 printf("Enter time, use 24h format HH:MM:SS (%02d:%02d:%02d): ",
00137 stm->tm_hour, stm->tm_min, stm->tm_sec);
00138 n = scanf("%d:%d:%d", &hour, &minute, &second);
00139 if (n >= 1) {
00140 printf("%02d", hour);
00141 if (hour < 0 || hour > 23) {
00142 printf("\nBad hour: %d is not within range 0..23\n", hour);
00143 return -1;
00144 }
00145 stm->tm_hour = hour;
00146 }
00147 if (n >= 2) {
00148 printf(":%02d", minute);
00149 if (minute < 0 || minute > 59) {
00150 printf("\nBad minute: %d is not within range 0..59\n", minute);
00151 return -1;
00152 }
00153 stm->tm_min = minute;
00154 }
00155 if (n >= 3) {
00156 printf(":%02d", second);
00157 if (second < 0 || second > 59) {
00158 printf("\nBad second: %d is not within range 0..59\n", second);
00159 return -1;
00160 }
00161 stm->tm_sec = second;
00162 }
00163 putchar('\n');
00164
00165 return 0;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 static long EnterTimeDiff(long init)
00176 {
00177 long hours;
00178 long minutes;
00179 long seconds;
00180 int n;
00181
00182 seconds = init;
00183 minutes = seconds / 60L;
00184 hours = minutes / 60L;
00185 minutes = abs(minutes % 60L);
00186 printf("Enter time difference in format HH:MM (%+03ld:%02ld): ", hours, minutes);
00187 n = scanf("%ld:%ld", &hours, &minutes);
00188 if (n >= 1) {
00189 printf("%+03ld", hours);
00190 if (hours < -12 || hours > 12) {
00191 printf("\nBad hours: %ld is not within range -12..+12\n", hours);
00192 return init;
00193 }
00194 }
00195 if (n >= 2) {
00196 printf("%02ld", minutes);
00197 if (minutes < 0 || minutes > 59) {
00198 printf("\nBad minutes: %ld is not within range 0..59\n", minutes);
00199 return init;
00200 }
00201 }
00202 putchar('\n');
00203
00204 return (hours * 60L + minutes) * 60L;
00205 }
00206
00207
00208
00209
00210
00211
00212 static void DisplaySeconds(void)
00213 {
00214 int i = 0;
00215
00216 while (!kbhit()) {
00217 printf(" [%c] Seconds since epoch: %ld\r", rotor[++i & 3], (long)time(NULL));
00218 NutSleep(200);
00219 }
00220 putchar('\n');
00221 }
00222
00223
00224
00225
00226
00227
00228 static void DisplayZuluTime(void)
00229 {
00230 time_t secs;
00231 struct _tm *gmt;
00232 int i = 0;
00233
00234 while (!kbhit()) {
00235 secs = time(NULL);
00236 gmt = gmtime(&secs);
00237 printf(" [%c] Universal time: ", rotor[++i & 3]);
00238 PrintDateTime(gmt);
00239 printf(" \r");
00240 NutSleep(500);
00241 }
00242 putchar('\n');
00243 }
00244
00245
00246
00247
00248
00249
00250 static void DisplayLocalTime(void)
00251 {
00252 time_t tt;
00253 struct _tm *ltm;
00254 int i = 0;
00255
00256 while (!kbhit()) {
00257
00258 tt = time(NULL);
00259 ltm = localtime(&tt);
00260 printf(" [%c] Local time: ", rotor[++i & 3]);
00261 PrintDateTime(ltm);
00262
00263
00264 tt = _timezone;
00265 if (ltm->tm_isdst > 0) {
00266 tt += _dstbias;
00267 }
00268 tt /= -60L;
00269
00270
00271 printf(" UTC%+03ld:%02ld \r", tt / 60L, abs(tt) % 60L);
00272 NutSleep(200);
00273 }
00274 putchar('\n');
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284 static void CalcWeekDay(void)
00285 {
00286 struct _tm date;
00287 time_t secs;
00288
00289
00290 time(&secs);
00291 memcpy(&date, localtime(&secs), sizeof(date));
00292
00293 if (EnterDate(&date) == 0) {
00294 mktime(&date);
00295 puts(weekday_name[date.tm_wday]);
00296 }
00297 }
00298
00299
00300
00301
00302 static void SetTimeZone(void)
00303 {
00304
00305 _timezone = EnterTimeDiff(_timezone);
00306 }
00307
00308
00309
00310
00311 static void SetLocalTime(void)
00312 {
00313 struct _tm ltm;
00314 time_t now;
00315
00316
00317 time(&now);
00318 memcpy(<m, localtime(&now), sizeof(ltm));
00319
00320
00321 if (EnterDate(<m) == 0 && EnterTime(<m) == 0) {
00322
00323 ltm.tm_isdst = -1;
00324
00325 now = mktime(<m);
00326
00327 stime(&now);
00328 }
00329 }
00330
00331
00332
00333
00334 int main(void)
00335 {
00336 u_long baud = 115200;
00337 int cmd;
00338
00339
00340 NutRegisterDevice(&DEV_UART, 0, 0);
00341 freopen(DEV_UART_NAME, "w", stdout);
00342 freopen(DEV_UART_NAME, "r", stdin);
00343 _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00344 printf("\n\nCalendar Time %s running on Nut/OS %s\n", version, NutVersionString());
00345
00346 #ifdef RTC_CHIP
00347
00348 printf("Registering RTC hardware...");
00349 if (NutRegisterRtc(&RTC_CHIP)) {
00350 puts("failed");
00351 } else {
00352 u_long rtc_stat;
00353
00354 NutRtcGetStatus(&rtc_stat);
00355 if (rtc_stat & RTC_STATUS_PF) {
00356 puts("power failure");
00357 }
00358 else {
00359 puts("OK");
00360 }
00361 }
00362 #endif
00363
00364 for (;;) {
00365
00366 puts("\n 0 - Display seconds counter");
00367 puts(" 1 - Display universal time");
00368 puts(" 2 - Display local time");
00369 puts(" 3 - Calculate weekday");
00370 puts(" S - Set local time");
00371 puts(" Y - Toggle DST calculation");
00372 puts(" Z - Set timezone");
00373
00374 printf("What is thy bidding, my master? ");
00375
00376
00377 while (kbhit()) {
00378 cmd = getchar();
00379 }
00380
00381
00382 cmd = getchar();
00383 putchar(cmd);
00384 putchar('\n');
00385
00386
00387 switch(cmd) {
00388 case '0':
00389 DisplaySeconds();
00390 break;
00391 case '1':
00392 DisplayZuluTime();
00393 break;
00394 case '2':
00395 DisplayLocalTime();
00396 break;
00397 case '3':
00398 CalcWeekDay();
00399 break;
00400 case 'S':
00401 case 's':
00402 SetLocalTime();
00403 break;
00404 case 'Y':
00405 case 'y':
00406
00407
00408 _daylight = _daylight == 0;
00409 printf("DST calculation %sabled\n", _daylight ? "en" : "dis");
00410 break;
00411 case 'Z':
00412 case 'z':
00413 SetTimeZone();
00414 break;
00415 }
00416 }
00417 return 0;
00418 }
00419