00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 #include "board.h"
00110
00111 #include <stdint.h>
00112 #include <stdio.h>
00113 #include <stdarg.h>
00114
00115
00116
00117
00118
00119
00120 #define STATE_MENU 0
00121
00122 #define STATE_SET_TIME 1
00123
00124 #define STATE_SET_DATE 2
00125
00126 #define STATE_SET_TIME_ALARM 3
00127
00128 #define STATE_SET_DATE_ALARM 4
00129
00130
00131 #define MAX_EDIT_SIZE 10
00132
00133
00134 #define IsDigitChar(c) ((c) >= '0' && (c) <='9')
00135
00136 #define CharToDigit(c) ((c) - '0')
00137
00138
00139
00140
00141 volatile uint16_t Temperature = 0;
00142 volatile uint32_t CountDownTimer = 0;
00143
00144 static unsigned int bState = STATE_MENU;
00145
00146
00147 static unsigned char newHour;
00148
00149 static unsigned char newMinute;
00150
00151 static unsigned char newSecond;
00152
00153
00154 static unsigned short newYear;
00155
00156 static unsigned char newMonth;
00157
00158 static unsigned char newDay;
00159
00160 static unsigned char newWeek;
00161
00162
00163 static unsigned char alarmTriggered = 0;
00164
00165
00166 static char rtc_time[8+1] = {'0', '0', ':', '0', '0', ':', '0', '0','\0'};
00167
00168 static char date[10+1] = {'0', '0', '/', '0', '0', '/', '0', '0', '0', '0', '\0'};
00169
00170 static char pDayNames[7][4] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
00171
00172 static char pEraseSeq[] = "\b \b";
00173
00174 static char calendar[80];
00175
00176 static unsigned int bMenuShown = 0;
00177
00178
00179
00180
00181
00182
00183
00184 static signed int _PrnToBuf(char *pBuf, const char *pFormat, ...)
00185 {
00186 va_list ap;
00187 signed int rc;
00188
00189 va_start(ap, pFormat);
00190 rc = vsprintf( pBuf, pFormat, ap);
00191 va_end(ap);
00192
00193 return rc;
00194 }
00195
00196
00197
00198
00199 static int _GetNewTime(void)
00200 {
00201 char ucKey;
00202 int i = 0;
00203
00204
00205 newHour = newMinute = newSecond = 0xFF;
00206
00207
00208 while (1) {
00209 ucKey = DBG_GetChar();
00210
00211
00212 if (ucKey == 0x0d || ucKey == 0x0a) {
00213 puts("\n\r");
00214 break;
00215 }
00216
00217
00218 if (ucKey == 0x7f || ucKey == 0x08) {
00219 if (i > 0) {
00220
00221 if (!rtc_time[i]) {
00222 --i;
00223 }
00224
00225 puts(pEraseSeq);
00226 --i;
00227
00228
00229 if (!IsDigitChar(rtc_time[i]) && i > 0) {
00230 puts(pEraseSeq);
00231 --i;
00232 }
00233 }
00234 }
00235
00236
00237 if (!rtc_time[i]) {
00238 continue;
00239 }
00240
00241 if (!IsDigitChar(ucKey)) {
00242 continue;
00243 }
00244
00245 DBG_PutChar(ucKey);
00246 rtc_time[i++] = ucKey;
00247
00248
00249 if (!IsDigitChar(rtc_time[i]) && i < 8) {
00250 DBG_PutChar(rtc_time[i]);
00251 ++i;
00252 }
00253 }
00254
00255 if (i == 0)
00256 return 0;
00257
00258 if (i != 0 && rtc_time[i] != '\0')
00259 return 1;
00260
00261 newHour = CharToDigit(rtc_time[0]) * 10 + CharToDigit(rtc_time[1]);
00262 newMinute = CharToDigit(rtc_time[3]) * 10 + CharToDigit(rtc_time[4]);
00263 newSecond = CharToDigit(rtc_time[6]) * 10 + CharToDigit(rtc_time[7]);
00264
00265
00266 return 0;
00267 }
00268
00269
00270
00271
00272 static char _CalcWeek(int year, int month, int day)
00273 {
00274 char week;
00275
00276 if (month == 1 || month == 2) {
00277 month += 12;
00278 --year;
00279 }
00280
00281 week = (day + 2 * month + 3 * (month + 1 ) / 5 + year + year / 4 -
00282 year / 100 + year / 400) % 7;
00283 ++week;
00284
00285 return week;
00286 }
00287
00288
00289
00290
00291
00292 static int _GetNewDate(void)
00293 {
00294 char ucKey;
00295 int i=0;
00296
00297
00298 newYear = 0xFFFF;
00299 newMonth = newDay = newWeek = 0xFF;
00300
00301
00302 while (1) {
00303 ucKey = DBG_GetChar();
00304
00305
00306 if (ucKey == 0x0d || ucKey == 0x0a) {
00307 puts( "\n\r" );
00308 break;
00309 }
00310
00311 if (ucKey == 0x7f || ucKey == 0x08) {
00312 if (i > 0) {
00313
00314 if (!date[i]) {
00315 --i;
00316 }
00317
00318 puts(pEraseSeq);
00319 --i;
00320
00321
00322 if (!IsDigitChar( date[i] ) && i > 0) {
00323 puts(pEraseSeq);
00324 --i;
00325 }
00326 }
00327 }
00328
00329
00330 if (!date[i])
00331 continue;
00332
00333 if (!IsDigitChar(ucKey))
00334 continue;
00335
00336 DBG_PutChar(ucKey);
00337 date[i++] = ucKey;
00338
00339
00340 if (!IsDigitChar(date[i]) && i < 10) {
00341 DBG_PutChar(date[i]);
00342 ++i;
00343 }
00344 }
00345
00346 if (i == 0)
00347 return 0;
00348
00349 if (i != 0 && date[i] != '\0' && i != 6)
00350 return 1;
00351
00352
00353 newMonth = CharToDigit(date[0]) * 10 + CharToDigit(date[1]);
00354 newDay = CharToDigit(date[3] ) * 10 + CharToDigit(date[4]);
00355 if (i != 6) {
00356
00357 newYear = CharToDigit(date[6]) * 1000 + CharToDigit(date[7]) * 100 +
00358 CharToDigit(date[8]) * 10 + CharToDigit(date[9]);
00359 newWeek = _CalcWeek(newYear, newMonth, newDay);
00360 }
00361
00362
00363 return 0;
00364 }
00365
00366
00367
00368
00369 void TC0_Handler(void)
00370 {
00371 volatile uint32_t dummy;
00372
00373 dummy = TC0->TC_CHANNEL[ 0 ].TC_SR;
00374
00375 if (CountDownTimer >= 240) {
00376 RTC_ClockCalibration(RTC, Temperature);
00377 TRACE_INFO("RTC has been re-calibrated \n\r");
00378 CountDownTimer = 0;
00379 }
00380 CountDownTimer++;
00381 }
00382
00383
00384
00385
00386 static void _RefreshDisplay(void)
00387 {
00388 unsigned char hour, minute, second;
00389 unsigned short year;
00390 unsigned char month, day, week;
00391
00392 if (bState != STATE_MENU) {
00393
00394 } else {
00395
00396 RTC_GetTime(RTC, &hour, &minute, &second);
00397 RTC_GetDate(RTC, &year, &month, &day, &week);
00398
00399
00400 if (!bMenuShown) {
00401 printf("\n\rMenu:\n\r" );
00402 printf(" t - Set time\n\r" );
00403 printf(" d - Set date\n\r" );
00404 printf(" i - Set time alarm\n\r" );
00405 printf(" m - Set date alarm\n\r" );
00406 printf(" p - PPM calibration of RTC\n\r" );
00407
00408 if (alarmTriggered)
00409 printf(" c - Clear alarm notification\n\r");
00410
00411 printf(" q - Quit!\n\r" );
00412 printf("\n\r" );
00413 bMenuShown = 1;
00414 }
00415
00416
00417 _PrnToBuf(rtc_time, "%02d:%02d:%02d", hour, minute, second);
00418 _PrnToBuf(date, "%02d/%02d/%04d", month, day, year);
00419 _PrnToBuf(calendar, " [Time/Date: %s, %s %s ][Alarm status:%s]",
00420 rtc_time, date, pDayNames[week-1], alarmTriggered?"Triggered!":"" );
00421 printf("\r%s", calendar);
00422 }
00423 }
00424
00425
00426
00427
00428 void RTC_Handler(void)
00429 {
00430 uint32_t dwStatus = RTC->RTC_SR;
00431
00432
00433 if ((dwStatus & RTC_SR_SEC) == RTC_SR_SEC) {
00434
00435 RTC_DisableIt(RTC, RTC_IDR_SECDIS);
00436
00437 _RefreshDisplay();
00438
00439 RTC->RTC_SCCR = RTC_SCCR_SECCLR;
00440
00441 RTC_EnableIt(RTC, RTC_IER_SECEN);
00442 }
00443
00444 else {
00445 if ((dwStatus & RTC_SR_ALARM) == RTC_SR_ALARM) {
00446
00447 RTC_DisableIt(RTC, RTC_IDR_ALRDIS);
00448
00449 alarmTriggered = 1;
00450 _RefreshDisplay();
00451 bMenuShown = 0;
00452 RTC->RTC_SCCR = RTC_SCCR_ALRCLR;
00453
00454 RTC_EnableIt(RTC, RTC_IER_ALREN);
00455 }
00456 }
00457 }
00458
00459
00460
00461
00462 static void _ConfigureTc(void)
00463 {
00464 uint32_t div;
00465 uint32_t tcclks;
00466
00467
00468 PMC_EnablePeripheral(ID_TC0);
00469
00470
00471 TC_FindMckDivisor(4, BOARD_MCK/2, &div, &tcclks, BOARD_MCK);
00472 TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
00473 TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 4;
00474
00475
00476 NVIC_ClearPendingIRQ(TC0_IRQn);
00477 NVIC_EnableIRQ(TC0_IRQn);
00478
00479 NVIC_SetPriority(TC0_IRQn ,2);
00480 TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
00481
00482 TC_Start(TC0, 0);
00483
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 extern int main(void)
00497 {
00498 uint8_t ucKey;
00499
00500
00501 WDT_Disable(WDT);
00502
00503
00504 SCB_EnableICache();
00505 SCB_EnableDCache();
00506
00507
00508 printf("\n\r\n\r\n\r");
00509 printf("-- RTC Example %s --\n\r", SOFTPACK_VERSION);
00510 printf("-- %s\n\r", BOARD_NAME);
00511 printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00512
00513 printf("Configure TC.\n\r");
00514 _ConfigureTc();
00515
00516 Temperature = 25;
00517
00518
00519 RTC_SetHourMode(RTC, 0);
00520 if (RTC_SetTimeAlarm(RTC, 0, 0, 0)) {
00521 printf("\n\r Disable time alarm fail!");
00522 }
00523
00524 if (RTC_SetDateAlarm(RTC, 0, 0)) {
00525 printf("\n\r Disable date alarm fail!");
00526 }
00527
00528
00529 NVIC_DisableIRQ(RTC_IRQn);
00530 NVIC_ClearPendingIRQ(RTC_IRQn);
00531 NVIC_SetPriority(RTC_IRQn, 0);
00532 NVIC_EnableIRQ(RTC_IRQn);
00533 RTC_EnableIt(RTC, RTC_IER_SECEN | RTC_IER_ALREN);
00534
00535
00536 _RefreshDisplay();
00537 newHour = 0;
00538 newMinute = 0;
00539 newSecond = 30;
00540 RTC_SetTimeAlarm(RTC, &newHour, &newMinute, &newSecond);
00541 bMenuShown = 0;
00542 alarmTriggered = 0;
00543 RTC_ClockCalibration(RTC, Temperature);
00544
00545
00546 while ( 1 ) {
00547 ucKey = DBG_GetChar();
00548
00549
00550 if (ucKey == 't') {
00551 bState = STATE_SET_TIME;
00552
00553 do {
00554 printf("\n\r\n\r Set time(hh:mm:ss): ");
00555 } while (_GetNewTime());
00556
00557
00558 if (newHour != 0xFF) {
00559 if (RTC_SetTime(RTC, newHour, newMinute, newSecond)) {
00560 printf("\n\r Time not set, invalid input!\n\r");
00561 }
00562 }
00563
00564 bState = STATE_MENU;
00565 bMenuShown = 0;
00566 _RefreshDisplay();
00567 CountDownTimer = 0;
00568 }
00569
00570 if (ucKey == 'p') {
00571 RTC_ClockCalibration(RTC, 30);
00572 bState = STATE_MENU;
00573 bMenuShown = 0;
00574 _RefreshDisplay();
00575 }
00576
00577
00578 if (ucKey == 'd') {
00579 bState = STATE_SET_DATE;
00580
00581 do {
00582 printf("\n\r\n\r Set date(mm/dd/yyyy): ");
00583 } while (_GetNewDate());
00584
00585
00586 if (newYear !=0xFFFF) {
00587 if (RTC_SetDate(RTC, newYear, newMonth, newDay, newWeek)) {
00588 printf("\n\r Date not set, invalid input!\n\r");
00589 }
00590 }
00591
00592
00593 if (newMonth != 0xFF && newYear == 0xFFFF) {
00594 printf("\n\r Not Set for no year field!\n\r");
00595 }
00596
00597 bState = STATE_MENU;
00598 bMenuShown = 0;
00599 CountDownTimer = 0;
00600 _RefreshDisplay();
00601 }
00602
00603
00604
00605 if (ucKey == 'i') {
00606 bState = STATE_SET_TIME_ALARM;
00607
00608 do {
00609 printf("\n\r\n\r Set time alarm(hh:mm:ss): ");
00610 } while (_GetNewTime());
00611
00612 if (newHour != 0xFF) {
00613 if (RTC_SetTimeAlarm(RTC, &newHour, &newMinute, &newSecond)) {
00614 printf("\n\r Time alarm not set, invalid input!\n\r");
00615 } else {
00616 printf("\n\r Time alarm is set at %02d:%02d:%02d!",
00617 newHour, newMinute, newSecond);
00618 }
00619 }
00620 bState = STATE_MENU;
00621 bMenuShown = 0;
00622 alarmTriggered = 0;
00623 CountDownTimer = 0;
00624 _RefreshDisplay();
00625 }
00626
00627
00628 if (ucKey == 'm') {
00629 bState = STATE_SET_DATE_ALARM;
00630
00631 do {
00632 printf("\n\r\n\r Set date alarm(mm/dd/): ");
00633 } while (_GetNewDate());
00634
00635 if ( newYear == 0xFFFF && newMonth != 0xFF) {
00636 if (RTC_SetDateAlarm(RTC, &newMonth, &newDay)) {
00637 printf("\n\r Date alarm not set, invalid input!\n\r");
00638 } else {
00639 printf("\n\r Date alarm is set on %02d/%02d!",
00640 newMonth, newDay);
00641 }
00642
00643 }
00644 bState = STATE_MENU;
00645 bMenuShown = 0;
00646 alarmTriggered = 0;
00647 CountDownTimer = 0;
00648 _RefreshDisplay();
00649 }
00650
00651
00652 if (ucKey == 'c') {
00653 alarmTriggered = 0;
00654 bMenuShown = 0;
00655 _RefreshDisplay();
00656 }
00657
00658
00659 if (ucKey == 'q') {
00660 break;
00661 }
00662 }
00663
00664 return 0;
00665 }