00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "msp430x12x2.h"
00016 #include <stdlib.h>
00017
00018
00019
00020
00021 #include "rtc_display_def.h"
00022
00023
00024
00025
00026 void InicializaVariables(void);
00027
00028 void GrabaE2Prom(void);
00029 void LeeE2Prom(void);
00030 void ReadInfo(char offset, char * variable_byte, char nro_bytes);
00031 void WriteInfo(char offset, char * variable_byte, char nro_bytes);
00032
00033 void RevisaDesbordMiliseg(void);
00034 void SetRefTime(int *var_ref);
00035 void SetRefTimeValue(int *var_ref, int offset);
00036 BYTE CheckTimeout(int delay_value, int var_ref);
00037 int CheckTimeoutValue(int delay_value, int var_ref);
00038
00039 void Reloj(void);
00040
00041
00042 int CalculaDiaSemana(int anyo, int mes, int dia);
00043 int Enero1(int yr);
00044 void FormatFechaHora(void);
00045 void CambiaReloj(void);
00046
00047 #if __VER__ < 200
00048 interrupt[PORT2_VECTOR] void RegistroDesplazamiento(void);
00049 #else
00050 #pragma vector=PORT2_VECTOR
00051 __interrupt void RegistroDesplazamiento(void);
00052 #endif
00053
00054 #if __VER__ < 200
00055 interrupt[WDT_VECTOR] void BaseTiempos(void);
00056 #else
00057 #pragma vector=WDT_VECTOR
00058 __interrupt void BaseTiempos(void);
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 __no_init char address_byte @ 0x02FA;
00081
00082
00083
00084
00085 BYTE timeout;
00086
00087
00088 int tics_1mseg;
00089 int tics_1seg;
00090
00091 int t_ref_segundos;
00092
00093
00094
00095 int anyo;
00096 int mes, dia, dia_semana;
00097 int num_dias_mes[13];
00098 char min, hora;
00099
00100
00101 BYTE byte_rtc_01, byte_rtc_02, byte_rtc_03;
00102 BYTE byte_rtc_04, byte_rtc_05;
00103 BYTE byte_cmm_rtc_01, byte_cmm_rtc_02, byte_cmm_rtc_03;
00104 BYTE byte_cmm_rtc_04, byte_cmm_rtc_05;
00105 BYTE byte_cmm_rtc_00;
00106
00107
00108 char inx_byte_out;
00109 BYTE byte_in_rtc;
00110 BYTE inx_bit;
00111 char f_stat;
00112
00113 char f_test;
00114
00115
00116
00117
00118 void main(void) {
00119 _DINT();
00120
00121 InicializaVariables();
00122
00123 _EINT();
00124
00125
00126
00127
00128 for (;;) {
00129 _DINT();
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 RevisaDesbordMiliseg();
00141
00142 if (f_stat & F_FIX_SEG) {
00143 f_stat &= ~F_FIX_SEG;
00144
00145 SetRefTimeValue(&t_ref_segundos, CheckTimeoutValue(_1_SEG, t_ref_segundos));
00146 tics_1seg += 1;
00147
00148 Reloj();
00149 FormatFechaHora();
00150 }
00151
00152 if ((!(f_stat & F_OUT_ACTIVA)) &&
00153 (!(f_stat & F_IRQ_CHGED))) {
00154
00155 f_stat |= F_IRQ_CHGED;
00156 P2IE = BIT_RTC_LD;
00157 P2IFG = 0x00;
00158 P2DIR &= ~BIT_RTC_DATA_OUT;
00159
00160 if (byte_cmm_rtc_00 == COMMD_HORA) {
00161
00162 CambiaReloj();
00163 }
00164 }
00165 _EINT();
00166
00167 P3OUT |= 0x10;
00168 __low_power_mode_3();
00169 _NOP();
00170 _NOP();
00171 P3OUT &= ~0x10;
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180 void InicializaVariables(void){
00181
00182
00183
00184 P2IFG = 0x00;
00185 P2IE = 0x01;
00186 P2IES = 0x01;
00187
00188 f_stat = 0;
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 byte_cmm_rtc_01 = byte_cmm_rtc_02 = 0;
00203 byte_cmm_rtc_03 = byte_cmm_rtc_04 = 0;
00204 byte_cmm_rtc_05 = byte_cmm_rtc_00 = 0;
00205
00206 num_dias_mes[0] = 0;
00207 num_dias_mes[1] = 31;
00208 num_dias_mes[2] = 29;
00209 num_dias_mes[3] = 31;
00210 num_dias_mes[4] = 30;
00211 num_dias_mes[5] = 31;
00212 num_dias_mes[6] = 30;
00213 num_dias_mes[7] = 31;
00214 num_dias_mes[8] = 31;
00215 num_dias_mes[9] = 30;
00216 num_dias_mes[10] = 31;
00217 num_dias_mes[11] = 30;
00218 num_dias_mes[12] = 31;
00219
00220 P3OUT &= ~0x10;
00221 f_test = 0;
00222 }
00223
00224
00225
00226
00227 void GrabaE2Prom(void) {
00228 _DINT();
00229 WriteInfo(0, &address_byte, 6);
00230 _EINT();
00231 }
00232 void LeeE2Prom(void) {
00233 ReadInfo(0, &address_byte, 6);
00234 }
00235 void WriteInfo(char offset, char * variable_byte, char nro_bytes) {
00236 char *Flash_ptr;
00237 char n;
00238
00239 Flash_ptr = (char *) ADDRESS_SEG_B;
00240 FCTL1 = FWKEY + ERASE;
00241 for(n=0; n<8; n++);
00242 FCTL3 = FWKEY;
00243 for(n=0; n<8; n++);
00244 *Flash_ptr = 0;
00245 for(n=0; n<8; n++);
00246
00247 FCTL1 = FWKEY + WRT;
00248 for(n=0; n<8; n++);
00249
00250 for (; offset>0; offset--) Flash_ptr++;
00251 for (; nro_bytes>0; nro_bytes--) {
00252 *Flash_ptr++ = *variable_byte++;
00253 for(n=0; n<8; n++);
00254 }
00255
00256 FCTL1 = FWKEY;
00257 for(n=0; n<8; n++);
00258 FCTL3 = FWKEY + LOCK;
00259 for(n=0; n<8; n++);
00260 }
00261 void ReadInfo(char offset, char *variable_byte, char nro_bytes) {
00262 char *Flash_ptr;
00263
00264 Flash_ptr = (char *)ADDRESS_SEG_B;
00265
00266 for (; offset>0; offset--) Flash_ptr++;
00267 for (; nro_bytes>0; nro_bytes--) {
00268 *variable_byte++ = *Flash_ptr++;
00269 }
00270 }
00271
00272
00273
00274
00275
00276 void RevisaDesbordMiliseg(void) {
00277 BYTE reinicia_mili_tics, num_positivo;
00278 int aux_int;
00279
00280 aux_int = INT_MAX - tics_1mseg;
00281 reinicia_mili_tics = (aux_int < (int)1500);
00282 if (reinicia_mili_tics) {
00283 num_positivo = t_ref_segundos > 0;
00284 if (num_positivo) t_ref_segundos = -(tics_1mseg - t_ref_segundos);
00285
00286 tics_1mseg =0;
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295 void SetRefTime(int *var_ref) {
00296 *var_ref = tics_1mseg;
00297 return;
00298 }
00299 void SetRefTimeValue(int *var_ref, int offset) {
00300 *var_ref = tics_1mseg - offset;
00301 return;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311 BYTE CheckTimeout(int delay_value, int var_ref) {
00312 BYTE t_out;
00313 unsigned int aux;
00314
00315 aux = tics_1mseg - var_ref;
00316 t_out = (aux >= delay_value);
00317 return t_out;
00318 }
00319 int CheckTimeoutValue(int delay_value, int var_ref) {
00320 int aux;
00321
00322 aux = tics_1mseg - var_ref;
00323 return (aux - delay_value);
00324 }
00325
00326
00327
00328
00329
00330 void Reloj(void) {
00331
00332
00333
00334 if (tics_1seg >= 60) {
00335 tics_1seg = 0;
00336 min++;
00337 if (min >=60) {
00338 min = 0;
00339 hora++;
00340 if (hora >=24) {
00341 hora = 0;
00342 CalculaDiaSemana (anyo, mes, dia);
00343 dia+=1;
00344 if (dia > num_dias_mes[mes]) {
00345 dia = 1;
00346 mes+=1;
00347 if (mes > DICIEMBRE) {
00348 anyo +=1;
00349 mes = ENERO;
00350 }
00351 }
00352 dia_semana = CalculaDiaSemana (anyo, mes, dia);
00353 }
00354 }
00355 }
00356
00357
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 int CalculaDiaSemana(int anyo, int mes, int dia) {
00385 int aux_dia;
00386 int i;
00387
00388 aux_dia = Enero1(anyo);
00389 num_dias_mes[SEPTIEMBRE] = 30;
00390
00391 switch ((Enero1(anyo+1) + 7 - aux_dia) % 7) {
00392 case 1:
00393 num_dias_mes[FEBRERO] = 28;
00394 break;
00395 default:
00396 num_dias_mes[SEPTIEMBRE] = 19;
00397
00398 case 2:
00399 num_dias_mes[FEBRERO] = 29;
00400 break;
00401 }
00402 for (i = 1; i < mes; ++i)
00403 aux_dia += (int)num_dias_mes[i];
00404
00405 aux_dia += (int)dia -1;
00406 aux_dia %= 7;
00407
00408 return aux_dia;
00409 }
00410
00411
00412
00413
00414
00415
00416 int Enero1(int yr) {
00417
00418 int y, d;
00419
00420 y = yr;
00421 d = 4 + y + ((y + 3) / 4);
00422
00423 if (y > 1800) {
00424 d -= (y - 1701) / 100;
00425 d += (y - 1601) / 400;
00426 }
00427
00428 if (y > 1752)
00429 d += 3;
00430
00431 return (d % 7);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 void FormatFechaHora(void) {
00449 BYTE aux_byte, aux_byte2;
00450 int aux_int;
00451
00452 aux_int = anyo - 2000;
00453 aux_byte = (BYTE)(aux_int & 0x007F);
00454 aux_byte2 = (aux_byte << 1) & 0xFE;
00455 aux_byte = (BYTE)(dia & 0x1F);
00456 aux_byte = (aux_byte >> 4) & 0x01;
00457 byte_rtc_01 = aux_byte | aux_byte2;
00458
00459 aux_byte = (BYTE)(dia & 0x1F);
00460 aux_byte = (aux_byte << 4) & 0xF0;
00461 aux_byte2 = (BYTE)(mes & 0x0F);
00462 byte_rtc_02 = aux_byte | aux_byte2;
00463
00464 aux_byte2 = (BYTE)(dia_semana & 0x07);
00465 aux_byte2 = (aux_byte2 << 5) & 0xE0;
00466 aux_byte = (BYTE)(hora & 0x1F);
00467 byte_rtc_03 = aux_byte | aux_byte2;
00468
00469 byte_rtc_04 = (BYTE)(min & 0x3F);
00470 byte_rtc_05 = (BYTE)(tics_1seg & 0x003F);
00471 }
00472
00473
00474
00475
00476
00477
00478 void CambiaReloj(void) {
00479 BYTE aux_byte, aux_byte2;
00480
00481 if (byte_cmm_rtc_01 ||
00482 byte_cmm_rtc_02 ||
00483 byte_cmm_rtc_03 ||
00484 byte_cmm_rtc_04 ||
00485 byte_cmm_rtc_05) {
00486
00487 aux_byte = byte_cmm_rtc_01;
00488 aux_byte = (aux_byte >> 1)& 0x7F;
00489 anyo = (int)aux_byte + 2000;
00490
00491 aux_byte = byte_cmm_rtc_01;
00492 aux_byte = (aux_byte << 4) & 0x10;
00493 aux_byte2 = byte_cmm_rtc_02;
00494 aux_byte2 = (aux_byte2 >> 4) & 0x0F;
00495 dia = aux_byte | aux_byte2;
00496
00497 mes = byte_cmm_rtc_02 & 0x0F;
00498 hora = byte_cmm_rtc_03 & 0x1F;
00499
00500 min = byte_cmm_rtc_04 & 0x3F;
00501 tics_1seg = byte_cmm_rtc_05 & 0x3F;
00502 dia_semana = CalculaDiaSemana (anyo, mes, dia);
00503 }
00504 byte_cmm_rtc_01 = 0;
00505 byte_cmm_rtc_02 = 0;
00506 byte_cmm_rtc_03 = 0;
00507 byte_cmm_rtc_04 = 0;
00508 byte_cmm_rtc_05 = 0;
00509 byte_cmm_rtc_00 = 0;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 #if __VER__ < 200
00523 interrupt[PORT2_VECTOR] void RegistroDesplazamiento(void)
00524 #else
00525 #pragma vector=PORT2_VECTOR
00526 __interrupt void RegistroDesplazamiento(void)
00527 #endif
00528 {
00529 BYTE aux_byte;
00530
00531 P3OUT ^= 0x40;
00532
00533 if ((P2IFG & BIT_RTC_LD) &&
00534 (!(f_stat & F_OUT_ACTIVA))) {
00535 f_stat |= F_OUT_ACTIVA;
00536 P2DIR |= BIT_RTC_DATA_OUT;
00537
00538 inx_byte_out = 0;
00539 inx_bit = 0x80;
00540
00541 P2IE = BIT_RTC_SCLK;
00542 P2IFG = 0x00;
00543
00544
00545 aux_byte = byte_rtc_01;
00546 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00547 else P2OUT &= ~BIT_RTC_DATA_OUT;
00548 inx_bit = inx_bit >> 1;
00549 }
00550 else if ((P2IFG & BIT_RTC_SCLK)) {
00551 f_stat |= F_OUT_ACTIVA;
00552 P2DIR |= BIT_RTC_DATA_OUT;
00553 switch (inx_byte_out) {
00554 case 0:
00555 aux_byte = byte_rtc_01;
00556 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00557 else P2OUT &= ~BIT_RTC_DATA_OUT;
00558
00559 inx_bit = inx_bit >> 1;
00560 if (!(inx_bit)) {
00561 inx_byte_out = 1;
00562 inx_bit = 0x80;
00563 }
00564 break;
00565 case 1:
00566 aux_byte = byte_rtc_02;
00567 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00568 else P2OUT &= ~BIT_RTC_DATA_OUT;
00569
00570 inx_bit = inx_bit >> 1;
00571 if (!(inx_bit)) {
00572 inx_byte_out = 2;
00573 inx_bit = 0x80;
00574 }
00575 break;
00576 case 2:
00577 aux_byte = byte_rtc_03;
00578 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00579 else P2OUT &= ~BIT_RTC_DATA_OUT;
00580
00581 inx_bit = inx_bit >> 1;
00582 if (!(inx_bit)) {
00583 inx_byte_out = 3;
00584 inx_bit = 0x80;
00585 byte_in_rtc = 0;
00586 }
00587 break;
00588 case 3:
00589 aux_byte = byte_rtc_04;
00590 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00591 else P2OUT &= ~BIT_RTC_DATA_OUT;
00592
00593 inx_bit = inx_bit >> 1;
00594 if (!(inx_bit)) {
00595 inx_byte_out = 4;
00596 inx_bit = 0x80;
00597 byte_in_rtc = 0;
00598 }
00599 break;
00600 case 4:
00601 aux_byte = byte_rtc_05;
00602 if (aux_byte & inx_bit) P2OUT |= BIT_RTC_DATA_OUT;
00603 else P2OUT &= ~BIT_RTC_DATA_OUT;
00604
00605 inx_bit = inx_bit >> 1;
00606 if (!(inx_bit)) {
00607 inx_byte_out = 5;
00608 inx_bit = 0x80;
00609 byte_in_rtc = 0;
00610 }
00611 break;
00612 case 5:
00613 P2OUT &= ~BIT_RTC_DATA_OUT;
00614 inx_byte_out = 6;
00615 byte_in_rtc = 0;
00616 break;
00617 case 6:
00618 aux_byte = P2IN & BIT_LSB;
00619 byte_in_rtc = byte_in_rtc << 1;
00620 byte_in_rtc |= aux_byte;
00621
00622 inx_bit = inx_bit >> 1;
00623 if (!(inx_bit)) {
00624 inx_byte_out = 7;
00625 inx_bit = 0x80;
00626 byte_cmm_rtc_01 = byte_in_rtc;
00627 byte_in_rtc = 0;
00628 }
00629 break;
00630 case 7:
00631 aux_byte = P2IN & BIT_LSB;
00632 byte_in_rtc = byte_in_rtc << 1;
00633 byte_in_rtc |= aux_byte;
00634
00635 inx_bit = inx_bit >> 1;
00636 if (!(inx_bit)) {
00637 inx_byte_out = 8;
00638 inx_bit = 0x80;
00639 byte_cmm_rtc_02 = byte_in_rtc;
00640 byte_in_rtc = 0;
00641 }
00642 break;
00643 case 8:
00644 aux_byte = P2IN & BIT_LSB;
00645 byte_in_rtc = byte_in_rtc << 1;
00646 byte_in_rtc |= aux_byte;
00647
00648 inx_bit = inx_bit >> 1;
00649 if (!(inx_bit)) {
00650 inx_byte_out = 9;
00651 inx_bit = 0x80;
00652 byte_cmm_rtc_03 = byte_in_rtc;
00653 byte_in_rtc = 0;
00654 }
00655 break;
00656 case 9:
00657 aux_byte = P2IN & BIT_LSB;
00658 byte_in_rtc = byte_in_rtc << 1;
00659 byte_in_rtc |= aux_byte;
00660
00661 inx_bit = inx_bit >> 1;
00662 if (!(inx_bit)) {
00663 inx_byte_out = 10;
00664 inx_bit = 0x80;
00665 byte_cmm_rtc_04 = byte_in_rtc;
00666 byte_in_rtc = 0;
00667 }
00668 break;
00669 case 10:
00670 aux_byte = P2IN & BIT_LSB;
00671 byte_in_rtc = byte_in_rtc << 1;
00672 byte_in_rtc |= aux_byte;
00673
00674 inx_bit = inx_bit >> 1;
00675 if (!(inx_bit)) {
00676 inx_byte_out = 11;
00677 inx_bit = 0x80;
00678 byte_cmm_rtc_05 = byte_in_rtc;
00679 byte_in_rtc = 0;
00680 }
00681 break;
00682 case 11:
00683 aux_byte = P2IN & BIT_LSB;
00684 byte_in_rtc = byte_in_rtc << 1;
00685 byte_in_rtc |= aux_byte;
00686
00687 inx_bit = inx_bit >> 1;
00688 if (!(inx_bit)) {
00689 inx_byte_out = 12;
00690 inx_bit = 0x80;
00691 byte_cmm_rtc_00 = byte_in_rtc;
00692 byte_in_rtc = 0;
00693
00694 f_stat &= ~F_OUT_ACTIVA;
00695 f_stat &= ~F_IRQ_CHGED;
00696 __low_power_mode_off_on_exit();
00697 _NOP();
00698 _NOP();
00699 }
00700 break;
00701 default:
00702 f_stat &= ~F_OUT_ACTIVA;
00703 f_stat &= ~F_IRQ_CHGED;
00704 __low_power_mode_off_on_exit();
00705 _NOP();
00706 _NOP();
00707 break;
00708 }
00709 }
00710
00711 P2IFG = 0x00;
00712 }
00713
00714
00715
00716
00717
00718 #if __VER__ < 200
00719 interrupt[WDT_VECTOR] void BaseTiempos(void)
00720 #else
00721 #pragma vector=WDT_VECTOR
00722 __interrupt void BaseTiempos(void)
00723 #endif
00724 {
00725 tics_1mseg +=1;
00726 timeout = CheckTimeout(_1_SEG, t_ref_segundos);
00727 if (timeout) {
00728 f_stat |= F_FIX_SEG;
00729 __low_power_mode_off_on_exit();
00730 _NOP();
00731 _NOP();
00732 P3OUT ^= 0x20;
00733 }
00734
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746