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 #ifdef USE_BUILD_TIME
00052 #include <pro/rfctime.h>
00053 #endif
00054
00055 #ifdef USE_LINE_EDITOR
00056 #include <gorp/edline.h>
00057 #define LINE_MAXLENGTH 80
00058 static char edbuff[LINE_MAXLENGTH];
00059 static EDLINE *edline;
00060 #endif
00061
00070 static char *version = "2.1";
00071
00072
00073
00074 static char *rotor = "|/-\\";
00075
00076 static char *weekday_name[7] = {
00077 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
00078 };
00079
00080
00081
00082
00083 static void PrintDateTime(CONST struct _tm *stm)
00084 {
00085 printf("%s, %04d/%02d/%02d, %02d:%02d:%02d%s"
00086 , weekday_name[stm->tm_wday]
00087 , stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday
00088 , stm->tm_hour, stm->tm_min, stm->tm_sec
00089 , stm->tm_isdst ? " DST" : ""
00090 );
00091 }
00092
00093
00094
00095
00096
00097
00098 static int EnterDate(struct _tm *stm)
00099 {
00100 int year = stm->tm_year + 1900;
00101 int month = stm->tm_mon + 1;
00102 int day = stm->tm_mday;
00103
00104 printf("Enter date, use format YYYY/MM/DD");
00105 #ifdef USE_LINE_EDITOR
00106 printf(" : ");
00107 sprintf(edbuff, "%04d/%02d/%02d", year, month, day);
00108 EdLineRead(edline, edbuff, LINE_MAXLENGTH);
00109 sscanf(edbuff, "%d/%d/%d", &year, &month, &day);
00110 #else
00111 printf(" (%04d/%02d/%02d): ", year, month, day);
00112 scanf("%d/%d/%d", &year, &month, &day);
00113 putchar('\n');
00114 #endif
00115
00116 if (year < 1970 || year > 2038) {
00117 printf("Bad year: %d is not within range 1970..2038\n", year);
00118 return -1;
00119 }
00120 if (month < 1 || month > 12) {
00121 printf("Bad month: %d is not within range 1..12\n", month);
00122 return -1;
00123 }
00124 if (day < 1 || day > 31) {
00125 printf("Bad day: %d is not within range 1..31\n", day);
00126 return -1;
00127 }
00128 stm->tm_year = year - 1900;
00129 stm->tm_mon = month - 1;
00130 stm->tm_mday = day;
00131
00132 return 0;
00133 }
00134
00135
00136
00137
00138
00139
00140 static int EnterTime(struct _tm *stm)
00141 {
00142 int hour = stm->tm_hour;
00143 int minute = stm->tm_min;
00144 int second = stm->tm_sec;
00145
00146 printf("Enter time, use 24h format HH:MM:SS");
00147 #ifdef USE_LINE_EDITOR
00148 printf(": ");
00149 sprintf(edbuff, "%02d:%02d:%02d", hour, minute, second);
00150 EdLineRead(edline, edbuff, LINE_MAXLENGTH);
00151 sscanf(edbuff, "%d:%d:%d", &hour, &minute, &second);
00152 #else
00153 printf(" (%02d:%02d:%02d): ", hour, minute, second);
00154 scanf("%d:%d:%d", &hour, &minute, &second);
00155 putchar('\n');
00156 #endif
00157
00158 if (hour < 0 || hour > 23) {
00159 printf("Bad hour: %d is not within range 0..23\n", hour);
00160 return -1;
00161 }
00162 if (minute < 0 || minute > 59) {
00163 printf("Bad minute: %d is not within range 0..59\n", minute);
00164 return -1;
00165 }
00166 if (second < 0 || second > 59) {
00167 printf("Bad second: %d is not within range 0..59\n", second);
00168 return -1;
00169 }
00170 stm->tm_hour = hour;
00171 stm->tm_min = minute;
00172 stm->tm_sec = second;
00173
00174 return 0;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184 static long EnterTimeDiff(long init)
00185 {
00186 long hours;
00187 long minutes;
00188 long seconds;
00189
00190 seconds = init;
00191 minutes = seconds / 60L;
00192 hours = minutes / 60L;
00193 minutes = abs(minutes % 60L);
00194
00195 printf("Enter time difference in format HH:MM");
00196 #ifdef USE_LINE_EDITOR
00197 printf(": ");
00198 sprintf(edbuff, "%+03ld:%02ld", hours, minutes);
00199 EdLineRead(edline, edbuff, LINE_MAXLENGTH);
00200 sscanf(edbuff, "%ld:%ld", &hours, &minutes);
00201 #else
00202 printf(" (%+03ld:%02ld): ", hours, minutes);
00203 scanf("%ld:%ld", &hours, &minutes);
00204 putchar('\n');
00205 #endif
00206
00207 if (hours < -12 || hours > 12) {
00208 printf("\nBad hours: %ld is not within range -12..+12\n", hours);
00209 return init;
00210 }
00211 if (minutes < 0 || minutes > 59) {
00212 printf("\nBad minutes: %ld is not within range 0..59\n", minutes);
00213 return init;
00214 }
00215 return (hours * 60L + minutes) * 60L;
00216 }
00217
00218
00219
00220
00221
00222
00223 static void DisplaySeconds(void)
00224 {
00225 uint_fast8_t i = 0;
00226
00227 while (!kbhit()) {
00228 printf(" [%c] Seconds since epoch: %ld\r"
00229 , rotor[++i & 3]
00230 , (long) time(NULL));
00231 NutSleep(200);
00232 }
00233 putchar('\n');
00234 }
00235
00236
00237
00238
00239
00240
00241 static void DisplayZuluTime(void)
00242 {
00243 time_t secs;
00244 struct _tm *gmt;
00245 uint_fast8_t i = 0;
00246
00247 while (!kbhit()) {
00248 secs = time(NULL);
00249 gmt = gmtime(&secs);
00250 printf(" [%c] Universal time: ", rotor[++i & 3]);
00251 PrintDateTime(gmt);
00252 printf(" \r");
00253 NutSleep(500);
00254 }
00255 putchar('\n');
00256 }
00257
00258
00259
00260
00261
00262
00263 static void DisplayLocalTime(void)
00264 {
00265 time_t tt;
00266 struct _tm *ltm;
00267 uint_fast8_t i = 0;
00268
00269 while (!kbhit()) {
00270
00271 tt = time(NULL);
00272 ltm = localtime(&tt);
00273 printf(" [%c] Local time: ", rotor[++i & 3]);
00274 PrintDateTime(ltm);
00275
00276
00277 tt = _timezone;
00278 if (ltm->tm_isdst > 0) {
00279 tt += _dstbias;
00280 }
00281 tt /= -60L;
00282
00283
00284 printf(" UTC%+03ld:%02ld \r", tt / 60L, abs(tt) % 60L);
00285 NutSleep(200);
00286 }
00287 putchar('\n');
00288 }
00289
00290
00291
00292
00293
00294
00295 static void DisplayUpTime(void)
00296 {
00297 uint32_t hours;
00298 uint32_t minutes;
00299 uint32_t seconds;
00300 uint_fast8_t i = 0;
00301
00302 while (!kbhit()) {
00303 seconds = NutGetSeconds();
00304 minutes = seconds / 60UL;
00305 hours = minutes / 60UL;
00306 minutes %= 60UL;
00307 seconds %= 60UL;
00308 printf(" [%c] System is running %lu hours"
00309 ", %lu minutes and %lu seconds \r"
00310 , rotor[++i & 3], hours, minutes, seconds);
00311 NutSleep(500);
00312 }
00313 putchar('\n');
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 static void CalcWeekDay(void)
00324 {
00325 struct _tm date;
00326 time_t secs;
00327
00328
00329 time(&secs);
00330 memcpy(&date, localtime(&secs), sizeof(date));
00331
00332 if (EnterDate(&date) == 0) {
00333 mktime(&date);
00334 puts(weekday_name[date.tm_wday]);
00335 }
00336 }
00337
00338
00339
00340
00341 static void SetTimeZone(void)
00342 {
00343
00344 _timezone = EnterTimeDiff(_timezone);
00345 }
00346
00347
00348
00349
00350 static void SetLocalTime(void)
00351 {
00352 struct _tm ltm;
00353 time_t now;
00354
00355
00356 time(&now);
00357 memcpy(<m, localtime(&now), sizeof(ltm));
00358
00359
00360 if (EnterDate(<m) == 0 && EnterTime(<m) == 0) {
00361
00362 ltm.tm_isdst = -1;
00363
00364 now = mktime(<m);
00365
00366 stime(&now);
00367 }
00368 }
00369
00370
00371
00372
00373 int main(void)
00374 {
00375 uint32_t baud = 115200;
00376 int cmd;
00377
00378
00379 NutRegisterDevice(&DEV_CONSOLE, 0, 0);
00380 freopen(DEV_CONSOLE_NAME, "w", stdout);
00381 freopen(DEV_CONSOLE_NAME, "r", stdin);
00382 _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00383 printf("\n\nCalendar Time %s running on Nut/OS %s\n"
00384 , version, NutVersionString());
00385
00386 #ifdef USE_LINE_EDITOR
00387
00388 printf("Opening line editor...");
00389 edline = EdLineOpen(EDIT_MODE_ECHO);
00390 if (edline) {
00391 puts("OK");
00392 } else {
00393 puts("failed");
00394 }
00395 #else
00396 puts("Note: Enable local echo!");
00397 #endif
00398
00399 #if USE_TIME_ZONE
00400 _timezone = USE_TIME_ZONE;
00401 #endif
00402
00403 #ifdef RTC_CHIP
00404
00405 printf("Registering RTC hardware...");
00406 if (NutRegisterRtc(&RTC_CHIP)) {
00407 puts("failed");
00408 } else {
00409 uint32_t rtc_stat;
00410
00411 NutRtcGetStatus(&rtc_stat);
00412 if (rtc_stat & RTC_STATUS_PF) {
00413 puts("power failure");
00414 } else {
00415 puts("OK");
00416 }
00417 }
00418 #elif USE_BUILD_TIME
00419 {
00420
00421 time_t now = RfcTimeParse("Unk, " __DATE__ " " __TIME__);
00422 stime(&now);
00423 puts("Built " __DATE__ " " __TIME__);
00424 }
00425 #endif
00426
00427 for (;;) {
00428
00429 puts("\n 0 - Display seconds counter");
00430 puts(" 1 - Display universal time");
00431 puts(" 2 - Display local time");
00432 puts(" 3 - Display system uptime");
00433 puts(" C - Calculate weekday");
00434 puts(" S - Set local time");
00435 puts(" Y - Toggle DST calculation");
00436 puts(" Z - Set timezone");
00437
00438 printf("What is thy bidding, my master? ");
00439
00440
00441 while (kbhit()) {
00442 cmd = getchar();
00443 }
00444
00445
00446 cmd = getchar();
00447 putchar('\n');
00448
00449
00450 switch (cmd) {
00451 case '0':
00452 DisplaySeconds();
00453 break;
00454 case '1':
00455 DisplayZuluTime();
00456 break;
00457 case '2':
00458 DisplayLocalTime();
00459 break;
00460 case '3':
00461 DisplayUpTime();
00462 break;
00463 case 'C':
00464 case 'c':
00465 CalcWeekDay();
00466 break;
00467 case 'S':
00468 case 's':
00469 SetLocalTime();
00470 break;
00471 case 'Y':
00472 case 'y':
00473
00474
00475 _daylight = _daylight == 0;
00476 printf("DST calculation %sabled\n", _daylight ? "en" : "dis");
00477 break;
00478 case 'Z':
00479 case 'z':
00480 SetTimeZone();
00481 break;
00482 }
00483 }
00484 return 0;
00485 }