//<RTCC>
typedef struct DateTime {
  char Year, Month, Day, Hour, Minute, Second;
} TDateTime;
TDateTime dtmRTCC;
char bytWkDay;
//</RTCC>

void RTCC_CalcWkDay() { // Calculates the correct weekday
  /*static const*/ char tbl[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
  unsigned int yr;
  yr = dtmRTCC.Year + 2000;
  if (dtmRTCC.Month < 2) {yr--;}
  bytWkDay = (yr + yr/4 - yr/100 + yr/400 + tbl[dtmRTCC.Month - 1] + dtmRTCC.Day) % 7;
}

void RTCC_WrEn() { //Enables writing to the RTCC registers
  EECON2 = 0x55;
  EECON2 = 0xAA;
  RTCWREN_bit = 1;
}

void RTCC_Init() {
  //Enable RTCC
  T1OSCEN_bit = 1;
  RTCC_WrEn();
  RTCEN_bit = 1;
  RTCWREN_Bit = 0;
}

void RTCC_Read() { //Reads from the RTCC
  RTCCFG = 0b10000011; //Set RTCPTR to 11
  while (RTCSYNC_bit = 1) {
    //Wait until rollover ripple cannot be a problem
  }
  dtmRTCC.Year   = Bcd2Dec(RTCVALL);
  dtmRTCC.Month  = Bcd2Dec(RTCVALH); //Just to decrement RTCPTR
  dtmRTCC.Day    = Bcd2Dec(RTCVALL);
  dtmRTCC.Month  = Bcd2Dec(RTCVALH);
  dtmRTCC.Hour   = Bcd2Dec(RTCVALL);
  bytWkDay  = Bcd2Dec(RTCVALH);
  dtmRTCC.Second = Bcd2Dec(RTCVALL);
  dtmRTCC.Minute = Bcd2Dec(RTCVALH);
}

void RTCC_Write() { //Writes to the RTCC
  RTCC_CalcWkDay();
  RTCC_WrEn();
  RTCCFG = 0b10100011; //Set RTCPTR to 11
  RTCVALL = Dec2Bcd(dtmRTCC.Year);
  RTCVALH = Dec2Bcd(dtmRTCC.Month); //Just to decrement RTCPTR
  RTCVALL = Dec2Bcd(dtmRTCC.Day);
  RTCVALH = Dec2Bcd(dtmRTCC.Month);
  RTCVALL = Dec2Bcd(dtmRTCC.Hour);
  RTCVALH = Dec2Bcd(bytWkDay);
  RTCVALL = Dec2Bcd(dtmRTCC.Second);
  RTCVALH = Dec2Bcd(dtmRTCC.Minute);
  RTCWREN_bit = 0;
}

void RTCC_GenerateDigits(char value, char *pos) {
  *pos = (value / 10) + 48;
  pos++;
  *pos = (value % 10) + 48;
}

void RTCC_GenerateDateStringYMD(TDateTime *dt, char *rtccstring) {
  // YY-MM-DD
  char *pos;
  char sep = '-';
  pos = rtccstring;
  RTCC_GenerateDigits((*dt).Year, pos);
  pos += 2; *pos = sep; pos++;
  RTCC_GenerateDigits((*dt).Month, pos);
  pos += 2; *pos = sep; pos++;
  RTCC_GenerateDigits((*dt).Day, pos);
  pos += 2; 
  *pos = 0;
}   

void RTCC_GenerateDateStringDMY(TDateTime *dt, char *rtccstring) {
  // DD/MM/YYYY
  char *pos;
  char sep = '/';
  pos = rtccstring;
  RTCC_GenerateDigits((*dt).Day, pos);
  pos += 2; *pos = sep; pos++;
  RTCC_GenerateDigits((*dt).Month, pos);
  pos += 2; *pos = sep; pos++;
  *pos = '2'; pos++;
  *pos = '0'; pos++;
  RTCC_GenerateDigits((*dt).Year, pos);
  pos += 2; 
  *pos = 0;
}

void RTCC_GenerateTimeString(TDateTime *dt, char *rtccstring, char incl_sec) {
  // hh:mm or hh:mm:ss
  char *pos;
  pos = rtccstring;
  RTCC_GenerateDigits((*dt).Hour, pos);
  pos += 2; *pos = ':'; pos++;
  RTCC_GenerateDigits((*dt).Minute, pos);
  if (incl_sec) {
    pos += 2; *pos = ':'; pos++;
    RTCC_GenerateDigits((*dt).Second, pos);
  }
  pos += 2;
  *pos = 0;
}

void RTCC_GenerateString(TDateTime *dt, char *rtccstring) { 
  RTCC_GenerateDateStringDMY(dt, rtccstring);
  rtccstring[10] = ' ';
  RTCC_GenerateTimeString(dt, rtccstring + 11, 0);
}