/*
This program initialises the PICs internal RTCC (real-time calendar/clock)
and then reads it every second, transmitting the read values via USB.
Use the mikroElektronika HID Terminal (Tools menu)
to view the transmitted values.
The 32.768kHz external crystal needs to be soldered in before the RTCC
will work. Alternatively, the PICs internal oscillator could be used.
Note that the 32.768kHz may take a few seconds to stabilise after power-on,
which may result in the RTCC not counting during that time.
*/

//<USB>
char USBin[64];
char USBout[64];
//</USB>

//<RTCC>
char bytYear, bytMonth, bytDay, bytHour, bytMinute, bytSecond;
char bytWkDay;
//</RTCC>

void interrupt() {
  USB_Interrupt_Proc();
}

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

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
  }
  bytYear   = Bcd2Dec(RTCVALL);
  bytMonth  = Bcd2Dec(RTCVALH); //Just to decrement RTCPTR
  bytDay    = Bcd2Dec(RTCVALL);
  bytMonth  = Bcd2Dec(RTCVALH);
  bytHour   = Bcd2Dec(RTCVALL);
  bytWkDay  = Bcd2Dec(RTCVALH);
  bytSecond = Bcd2Dec(RTCVALL);
  bytMinute = Bcd2Dec(RTCVALH);
}

void RTCC_Write() { //Writes to the RTCC
  RTCC_WrEn();
  RTCCFG = 0b10100011; //Set RTCPTR to 11
  RTCVALL = Dec2Bcd(bytYear);
  RTCVALH = Dec2Bcd(bytMonth); //Just to decrement RTCPTR
  RTCVALL = Dec2Bcd(bytDay);
  RTCVALH = Dec2Bcd(bytMonth);
  RTCVALL = Dec2Bcd(bytHour);
  RTCVALH = Dec2Bcd(bytWkDay);
  RTCVALL = Dec2Bcd(bytSecond);
  RTCVALH = Dec2Bcd(bytMinute);
  RTCWREN_bit = 0;
}

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

void GenerateRTCCString(char *rtccstring) {
  char *pos;
  pos = rtccstring;
  strcpy(rtccstring, "00-00-00 00:00:00");
  GenerateDigits(bytYear, pos);
  pos += 3;
  GenerateDigits(bytMonth, pos);
  pos += 3;
  GenerateDigits(bytDay, pos);
  pos += 3;
  GenerateDigits(bytHour, pos);
  pos += 3;
  GenerateDigits(bytMinute, pos);
  pos += 3;
  GenerateDigits(bytSecond, pos);
  pos += 3;
  *pos = 0;
}

void USB_RTCC() {
  GenerateRTCCString(USBout);
  strcat(USBout, "\r\n"); //New line
  HID_Write(&USBout, 64);
}

void TestRTCC_Write() {
  bytYear = 86;
  bytMonth = 7;
  bytDay = 12;
  bytHour = 5;
  bytMinute = 8;
  bytSecond = 3;
  RTCC_Write();
}

void main() {
  OSCCON = 0b01110000; //8MHz
  PLLEn_bit = 1; //Enable PLL (now 48MHz)

  //Enable RTCC
  T1OSCEN_bit = 1;
  RTCC_WrEn();
  RTCEN_bit = 1;
  RTCWREN_Bit = 0;

  HID_Enable(&USBin, &USBout);
  strcpy(USBout, "Breeze RTCC\r\n");
  HID_Write(&USBout, 64);

  TestRTCC_Write();

  TRISC2_bit = 0;
  LATC2_bit = 0;

  while(1) {
    LATC2_bit = 1;
    RTCC_Read();
    USB_RTCC();
    delay_ms(100);
    LATC2_bit = 0;
    delay_ms(900);
  }
}