-//RTC commands:
-#define RTC_EEREAD 0x03
-#define RTC_EEWRITE 0x02
-#define RTC_EEWRDI 0x04
-#define RTC_EEWREN 0x06
-#define RTC_SRREAD 0x05
-#define RTC_SRWRITE 0x01
-#define RTC_READ 0x13
-#define RTC_WRITE 0x12
-#define RTC_UNLOCK 0x14
-#define RTC_IDWRITE 0x32
-#define RTC_IDREAD 0x33
-#define RTC_CLRRAM 0x54
-
-//SPI function flags:
-#define ADDRFLAG 0x01
-#define WRITEFLAG 0x02
-#define READFLAG 0x04
-
-//7 segment display
-
-#define SEG_A 0xdf
-#define SEG_B 0xef // aaaa
-#define SEG_C 0xbf // f b
-#define SEG_D 0x7f // f b
-#define SEG_E 0xfd //hh gggg
-#define SEG_F 0xfb // e c
-#define SEG_G 0xf7 // e c
-#define SEG_H 0xfe // dddd
-
-#define SYMB_0 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_E & SEG_F )
-#define SYMB_1 ( SEG_B & SEG_C )
-#define SYMB_2 (SEG_A & SEG_B & SEG_D & SEG_E & SEG_G)
-#define SYMB_3 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_G)
-#define SYMB_4 ( SEG_B & SEG_C & SEG_F & SEG_G)
-#define SYMB_5 (SEG_A & SEG_C & SEG_D & SEG_F & SEG_G)
-#define SYMB_6 (SEG_A & SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)
-#define SYMB_7 (SEG_A & SEG_B & SEG_C )
-#define SYMB_8 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)
-#define SYMB_9 (SEG_A & SEG_B & SEG_C & SEG_F & SEG_G)
-#define SYMB_A (SEG_A & SEG_B & SEG_C & SEG_E & SEG_F & SEG_G)
-#define SYMB_B ( SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)
-#define SYMB_C ( SEG_D & SEG_E & SEG_G)
-#define SYMB_D ( SEG_B & SEG_C & SEG_D & SEG_E & SEG_G)
-#define SYMB_E (SEG_A & SEG_D & SEG_E & SEG_F & SEG_G)
-#define SYMB_F (SEG_A & SEG_E & SEG_F & SEG_G)
-#define SYMB_NUL (0xFF)
-#define SYMB_o (SEG_A & SEG_B & SEG_F & SEG_G)
-#define SYMB_n (SEG_A & SEG_B & SEG_F )
-#define SYMB_g (SEG_A & SEG_B & SEG_C & SEG_D & SEG_F & SEG_G)
-#define SYMB_MIN ( SEG_G)
-#define SYMB_DOT (SEG_H)
-
-//operation modes
-#define MODE_INIT 0
-#define MODE_TIME 1
-#define MODE_SETTIME 2
-#define MODE_SETALARM 3
-#define MODE_ALARM 4
-#define MODE_DATE 5
-#define MODE_SETDATE 6
-#define MODE_SETYEAR 7
-#define MODE_COUNTUP 8
-#define MODE_SETCOUNTDOWN 9
-#define MODE_COUNTDOWN 10
-#define MODE_CALIBRATE 11
-
+//RTC commands:\r
+#define RTC_EEREAD 0x03\r
+#define RTC_EEWRITE 0x02\r
+#define RTC_EEWRDI 0x04\r
+#define RTC_EEWREN 0x06\r
+#define RTC_SRREAD 0x05\r
+#define RTC_SRWRITE 0x01\r
+#define RTC_READ 0x13\r
+#define RTC_WRITE 0x12\r
+#define RTC_UNLOCK 0x14\r
+#define RTC_IDWRITE 0x32\r
+#define RTC_IDREAD 0x33\r
+#define RTC_CLRRAM 0x54\r
+\r
+//SPI function flags:\r
+#define ADDRFLAG 0x01\r
+#define WRITEFLAG 0x02\r
+#define READFLAG 0x04\r
+\r
+//7 segment display\r
+\r
+#define SEG_A 0xdf\r
+#define SEG_B 0xef // aaaa\r
+#define SEG_C 0xbf // f b\r
+#define SEG_D 0x7f // f b\r
+#define SEG_E 0xfd //hh gggg\r
+#define SEG_F 0xfb // e c\r
+#define SEG_G 0xf7 // e c\r
+#define SEG_H 0xfe // dddd \r
+\r
+#define SYMB_0 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_E & SEG_F )\r
+#define SYMB_1 ( SEG_B & SEG_C )\r
+#define SYMB_2 (SEG_A & SEG_B & SEG_D & SEG_E & SEG_G)\r
+#define SYMB_3 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_G)\r
+#define SYMB_4 ( SEG_B & SEG_C & SEG_F & SEG_G)\r
+#define SYMB_5 (SEG_A & SEG_C & SEG_D & SEG_F & SEG_G)\r
+#define SYMB_6 (SEG_A & SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_7 (SEG_A & SEG_B & SEG_C )\r
+#define SYMB_8 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_9 (SEG_A & SEG_B & SEG_C & SEG_F & SEG_G)\r
+#define SYMB_A (SEG_A & SEG_B & SEG_C & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_B ( SEG_C & SEG_D & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_C ( SEG_D & SEG_E & SEG_G)\r
+#define SYMB_D ( SEG_B & SEG_C & SEG_D & SEG_E & SEG_G)\r
+#define SYMB_E (SEG_A & SEG_D & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_F (SEG_A & SEG_E & SEG_F & SEG_G)\r
+#define SYMB_NUL (0xFF)\r
+#define SYMB_o (SEG_A & SEG_B & SEG_F & SEG_G)\r
+#define SYMB_n (SEG_A & SEG_B & SEG_F )\r
+#define SYMB_g (SEG_A & SEG_B & SEG_C & SEG_D & SEG_F & SEG_G)\r
+#define SYMB_MIN ( SEG_G)\r
+#define SYMB_DOT (SEG_H)\r
+\r
+//operation modes\r
+#define MODE_INIT 0\r
+#define MODE_TIME 1\r
+#define MODE_SETTIME 2\r
+#define MODE_SETALARM 3\r
+#define MODE_ALARM 4\r
+#define MODE_DATE 5\r
+#define MODE_SETDATE 6\r
+#define MODE_SETYEAR 7\r
+#define MODE_COUNTUP 8\r
+#define MODE_SETCOUNTDOWN 9\r
+#define MODE_COUNTDOWN 10\r
+#define MODE_CALIBRATE 11\r
+#define MODE_SHOWVERSION 12\r
+\r
#define ALARMVALUE 0xa5
\ No newline at end of file
unsigned char settime[3];\r
unsigned char mode;\r
unsigned char alarm[3];\r
+unsigned char lastcdn[2];\r
+unsigned char lastyear[2];\r
unsigned char digit;\r
unsigned char changed;\r
unsigned char run;\r
time[7]=inbuf[7];//year\r
leap=inbuf[6]&0x20;\r
\r
- spi(RTC_READ,0x0f,inbuf,outbuf,1);\r
+ spi(RTC_READ,0x0f,inbuf,outbuf,1); // <- because of RTC bug (?)\r
if(!((time[2]^alarm[1])|(time[3]^alarm[2])) && alarm[0])\r
{\r
mode=MODE_ALARM;\r
//P2DIR&= ~0x40;\r
//P2SEL&= ~0x40;\r
}\r
+ \r
+ if (time[7]!=lastyear[0])\r
+ {\r
+ if(time[7]<lastyear[0])\r
+ lastyear[1]=__bcd_add_short(lastyear[1],0x01);\r
+ \r
+ lastyear[0]=time[7];\r
+ \r
+ outbuf[0]=ALARMVALUE;\r
+ outbuf[1]=lastyear[0];\r
+ outbuf[2]=lastyear[1];\r
+ \r
+ spi(RTC_WRITE,0x26,inbuf,outbuf,3);\r
+ }\r
}\r
else if(P2IFG&0x02) // button A\r
{\r
else\r
{\r
mode=MODE_SETCOUNTDOWN;\r
- settime[1]=0x00;\r
- settime[2]=0x00;\r
+ settime[1]=lastcdn[0];\r
+ settime[2]=lastcdn[1];\r
digit=3;\r
}\r
break;\r
case MODE_SETCOUNTDOWN:\r
case MODE_COUNTDOWN:\r
- if((settime[1] | settime[2])||digit!=3||mode==MODE_COUNTDOWN)\r
+ if(((settime[1] | settime[2])&&((settime[1]^lastcdn[0])|(settime[1]^lastcdn[0])))||digit!=3||mode==MODE_COUNTDOWN)\r
{\r
mode=MODE_SETCOUNTDOWN;\r
settime[1]=0x00;\r
//case MODE_SETALARM:\r
//case MODE_ALARM:\r
//case MODE_CALIBRATE:\r
+ //case MODE_SHOWVERSION:\r
default:\r
mode=MODE_TIME;\r
break;\r
--digit;\r
else\r
{\r
+ lastcdn[0]=settime[1];\r
+ lastcdn[1]=settime[2];\r
+ \r
+ outbuf[0]=ALARMVALUE;\r
+ outbuf[1]=settime[1];\r
+ outbuf[2]=settime[2];\r
+ spi(RTC_WRITE,0x23,inbuf,outbuf,3);\r
+\r
mode=MODE_COUNTDOWN;\r
run=0;\r
}\r
{\r
if(changed)\r
{\r
- time[7]=settime[0];\r
- spi(RTC_WRITE,0x07,inbuf,settime,1);\r
+ time[7]=settime[1];\r
+ spi(RTC_WRITE,0x07,inbuf,settime+1,1);\r
+ \r
+ lastyear[0]=settime[1];\r
+ lastyear[1]=settime[2];\r
+ settime[0]=ALARMVALUE;\r
+ \r
+ spi(RTC_WRITE,0x26,inbuf,settime,3);\r
}\r
mode=MODE_DATE; \r
}\r
settime[2]=0x00;\r
break;\r
case MODE_COUNTDOWN:\r
+ settime[1]=lastcdn[0];\r
+ settime[2]=lastcdn[1];\r
mode=MODE_SETCOUNTDOWN;\r
digit=3;\r
break;\r
break;\r
case MODE_SETTIME:\r
case MODE_SETALARM:\r
+ case MODE_SETYEAR:\r
changed=1;\r
case MODE_SETCOUNTDOWN:\r
//these 4 lines replaced a larger switch structure\r
- if((settime[digit&0x02?2:1]&((digit&0x01)?0xf0:0x0f))<(digit==1?0x50:(digit==3?((mode==MODE_SETCOUNTDOWN)?0x90:0x20):((mode!=MODE_SETCOUNTDOWN&&digit==2&&settime[2]>0x19)?0x03:0x09))))\r
+ if((settime[digit&0x02?2:1]&((digit&0x01)?0xf0:0x0f))<(digit==1?((mode==MODE_SETYEAR)?0x90:0x50):(digit==3?((mode==MODE_SETCOUNTDOWN||mode==MODE_SETYEAR)?0x90:0x20):((mode!=MODE_SETCOUNTDOWN&&mode!=MODE_SETYEAR&&digit==2&&settime[2]>0x19)?0x03:0x09))))\r
settime[digit&0x02?2:1]+=((digit&0x01)?0x10:0x01);\r
else\r
settime[digit&0x02?2:1]&=((digit&0x01)?0x0f:0xf0);\r
break;\r
- case MODE_SETYEAR:\r
- changed=1;\r
- if(digit)\r
- {\r
- if(settime[0]<0x90)\r
- settime[0]+=0x10;\r
- else\r
- settime[0]&=0x0f;\r
- }\r
- else\r
- {\r
- if((settime[0]&0x0f)<0x09)\r
- ++settime[0];\r
- else\r
- settime[0]&=0xf0;\r
- }\r
- break;\r
+ //case MODE_SETYEAR:\r
+ // changed=1;\r
+ // if(digit)\r
+ // {\r
+ // if(settime[0]<0x90)\r
+ // settime[0]+=0x10;\r
+ // else\r
+ // settime[0]&=0x0f;\r
+ // }\r
+ // else\r
+ // {\r
+ // if((settime[0]&0x0f)<0x09)\r
+ // ++settime[0];\r
+ // else\r
+ // settime[0]&=0xf0;\r
+ // }\r
+ // break;\r
case MODE_SETDATE:\r
changed=1;\r
switch (digit)\r
break;\r
case MODE_DATE:\r
mode=MODE_SETYEAR;\r
- digit=1;\r
+ digit=3;\r
changed=0;\r
\r
- settime[0]=time[7];\r
+ settime[1]=time[7];\r
+ settime[2]=lastyear[1];\r
break;\r
case MODE_TIME:\r
mode=MODE_SETALARM;\r
case MODE_SETTIME:\r
case MODE_SETALARM:\r
case MODE_SETCOUNTDOWN:\r
- dispvalue[0]=(symbol[settime[1]&0x0f]|((digit!=0 && (time[1]&0x01))?SYMB_NUL:SYMB_8))&(((((time[1]+0x01)&0x02)^((time[1]&0x10)>>3))&&mode==MODE_SETCOUNTDOWN)?SYMB_NUL:SYMB_DOT);\r
- dispvalue[1]=(symbol[(settime[1]&0xf0)>>4]|((digit!=1 && (time[1]&0x01))?SYMB_NUL:SYMB_8))&((((time[1]&0x02)^((time[1]&0x10)>>3))&&mode==MODE_SETCOUNTDOWN)?SYMB_NUL:SYMB_DOT);\r
- dispvalue[2]=(symbol[settime[2]&0x0f]|((digit!=2 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
- dispvalue[3]=(symbol[(settime[2]&0xf0)>>4]|((digit!=3 && (time[1]&0x01))?SYMB_NUL:SYMB_8))&((mode!=MODE_SETALARM && alarm[0] || mode==MODE_SETALARM && !(time[1]&0x01))?SYMB_DOT:SYMB_NUL);\r
- break;\r
case MODE_SETYEAR:\r
- dispvalue[0]=(symbol[settime[0]&0x0f]|((digit!=0 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
- dispvalue[1]=(symbol[(settime[0]&0xf0)>>4]|((digit!=1 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
- dispvalue[2]=(SYMB_0|((time[1]&0x01)?SYMB_NUL:SYMB_8));\r
- dispvalue[3]=(SYMB_2|((time[1]&0x01)?SYMB_NUL:SYMB_8))&(alarm[0]?SYMB_DOT:SYMB_NUL);\r
+ dispvalue[0]=(symbol[settime[1]&0x0f] | ((digit!=0 && (time[1]&0x01))?SYMB_NUL:SYMB_8)) & ((((((time[1]+0x01)&0x02)^((time[1]&0x10)>>3))&&mode==MODE_SETCOUNTDOWN)||mode==MODE_SETYEAR)?SYMB_NUL:SYMB_DOT);\r
+ dispvalue[1]=(symbol[(settime[1]&0xf0)>>4] | ((digit!=1 && (time[1]&0x01))?SYMB_NUL:SYMB_8)) & (((((time[1]&0x02)^((time[1]&0x10)>>3))&&mode==MODE_SETCOUNTDOWN)||mode==MODE_SETYEAR)?SYMB_NUL:SYMB_DOT);\r
+ dispvalue[2]=(symbol[settime[2]&0x0f] | ((digit!=2 && (time[1]&0x01))?SYMB_NUL:SYMB_8)) ;\r
+ dispvalue[3]=(symbol[(settime[2]&0xf0)>>4] | ((digit!=3 && (time[1]&0x01))?SYMB_NUL:SYMB_8)) & ((mode!=MODE_SETALARM && alarm[0] || mode==MODE_SETALARM && !(time[1]&0x01))?SYMB_DOT:SYMB_NUL);\r
break;\r
+ //case MODE_SETYEAR:\r
+ // dispvalue[0]=(symbol[settime[0]&0x0f]|((digit!=0 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
+ // dispvalue[1]=(symbol[(settime[0]&0xf0)>>4]|((digit!=1 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
+ // dispvalue[2]=(SYMB_0|((time[1]&0x01)?SYMB_NUL:SYMB_8));\r
+ // dispvalue[3]=(SYMB_2|((time[1]&0x01)?SYMB_NUL:SYMB_8))&(alarm[0]?SYMB_DOT:SYMB_NUL);\r
+ // break;\r
case MODE_SETDATE:\r
dispvalue[0]=(symbol[settime[1]&0x0f]|((digit!=2 && (time[1]&0x01))?SYMB_NUL:SYMB_8));\r
dispvalue[1]=(symbol[(settime[1]&0xf0)>>4]|((digit!=2 && (time[1]&0x01))?SYMB_NUL:SYMB_8))&SYMB_DOT;\r
{\r
dispvalue[0]=symbol[time[7]&0x0f];\r
dispvalue[1]=symbol[(time[7]&0xf0)>>4];\r
- dispvalue[2]=SYMB_0;\r
- dispvalue[3]=SYMB_2&(alarm[0]?SYMB_DOT:SYMB_NUL);\r
+ dispvalue[2]=symbol[lastyear[1]&0x0f];\r
+ dispvalue[3]=symbol[(lastyear[1]&0xf0)>>4]&(alarm[0]?SYMB_DOT:SYMB_NUL);\r
}\r
else\r
{\r
dispvalue[2]=symbol[settime[2]&0x0f];\r
dispvalue[3]=((settime[2]&0xf0)?symbol[(settime[2]&0xf0)>>4]:SYMB_NUL)&(alarm[0]?SYMB_DOT:SYMB_NUL);\r
break;\r
+ case MODE_SHOWVERSION:\r
+ dispvalue[0]=SYMB_NUL;\r
+ dispvalue[1]=SYMB_2&SYMB_DOT;\r
+ dispvalue[2]=SYMB_1;\r
+ dispvalue[3]=SYMB_NUL;\r
+ break;\r
case MODE_ALARM:\r
case MODE_TIME:\r
if(((time[1]&0x01) && mode==MODE_ALARM) || (time[3]==0x04 && time[2]==0x33 && time[1]==0x00))\r
alarm[1]=inbuf[1];\r
alarm[2]=inbuf[2];\r
\r
+ spi(RTC_READ,0x0f,inbuf,outbuf,1); // <- because of RTC bug (?)\r
+ \r
+ //get last countdown value from RTC SRAM\r
+ spi(RTC_READ,0x23,inbuf,outbuf,3);\r
+ if(inbuf[0]==ALARMVALUE)\r
+ {\r
+ lastcdn[0]=inbuf[1];\r
+ lastcdn[1]=inbuf[2];\r
+ }\r
+ else\r
+ {\r
+ lastcdn[0]=0;\r
+ lastcdn[1]=0;\r
+ }\r
+ \r
+ spi(RTC_READ,0x0f,inbuf,outbuf,1); // <- because of RTC bug (?)\r
+ \r
+ //get last year value from RTC SRAM\r
+ spi(RTC_READ,0x26,inbuf,outbuf,3);\r
+ if(inbuf[0]==ALARMVALUE)\r
+ {\r
+ lastyear[0]=inbuf[1];\r
+ lastyear[1]=inbuf[2];\r
+ }\r
+ else\r
+ {\r
+ lastyear[0]=0x00;\r
+ lastyear[1]=0x20;\r
+ }\r
+ \r
//start oscillator\r
spi(RTC_READ,0x01,inbuf,outbuf,1);\r
if(!(inbuf[0]&0x80))\r
P2IES&= ~0x08; //RTC int. on rising edge\r
P2IFG=0x00;\r
\r
- if(P2IN&0x02) //button A pressed at start?\r
- mode=MODE_TIME;\r
- else\r
+ if(!(P2IN&0x02)) //button A pressed at start?\r
{\r
mode=MODE_CALIBRATE;\r
spi(RTC_READ,0x03,inbuf,outbuf,1);\r
settime[0]=inbuf[0];\r
digit=3;\r
}\r
- \r
+ else if(!(P2IN&0x20)) //button C pressed at start?\r
+ mode=MODE_SHOWVERSION;\r
+ else\r
+ mode=MODE_TIME;\r
+ \r
__enable_interrupt();\r
\r
\r