/*  HT1381 RealTimeClock routines
 *  Designed by Paolo Subiaco psubiaco@creasol.it
 */

#include "main.h"
#include "ht1381.h"

RTCDATE rtcdate;
         
void ht1381write(uchar addr, uchar data) {
  // Write a byte to the RTC on the specified address
  uchar i;
  rtcrst=1;        
  addr<<=1;
  addr|=0x80;    
  // Write command byte
  for (i=8;i;i--) {
    if (addr&0x01)
      rtcio=1;
    else
      rtcio=0;
    rtcsck=1;
    addr>>=1;
    rtcsck=0;  
  } 
  for (i=8;i;i--) {
    if (data&0x01)
      rtcio=1;
    else
      rtcio=0;
    rtcsck=1;
    data>>=1;
    rtcsck=0;  
  }
  rtcrst=0;
  rtcio=0;  
}
          
uchar ht1381read(uchar addr) {
  // Read a byte from the RTC on the specified address
  uchar i;
  uchar data;
  rtcrst=1;            
  addr<<=1;
  addr|=0x81;    
  // Write command byte
  for (i=8;i;i--) {
    rtcsck=0;  
    if (addr&0x01)
      rtcio=1;
    else
      rtcio=0;
    rtcsck=1;
    addr>>=1;
  } 
  rtciom=1;
  for (i=8;i;i--) {
    rtcsck=0;  
    data>>=1;
    if (rtcio)
      data|=0x80;
    rtcsck=1;
  }
  rtcsck=0;
  rtcrst=0;  
  rtcio=0;
  rtciom=0;
  return data;
}                       

uchar rtcGetSeconds(void) {
  uchar value;
  value=ht1381read(0);  // read seconds
  return (((value>>4)&0x07)*10+(value&0x0f));
}
  
uchar rtcGetMinutes(void) {
  uchar value;
  value=ht1381read(1);  
  return (((value>>4)&0x07)*10+(value&0x0f));
}

uchar rtcGetHours(void) {
  uchar value;
  value=ht1381read(2);  
  return (((value>>4)&0x03)*10+(value&0x0f));
}
  
uchar rtcGetDate(void) {
  uchar value;
  value=ht1381read(3);  
  return (((value>>4)&0x03)*10+(value&0x0f));
}
  
uchar rtcGetMonth(void) {
  uchar value;
  value=ht1381read(4);  
  return (((value>>4)&0x01)*10+(value&0x0f));
}
  
uchar rtcGetYear(void) {
  uchar value;
  value=ht1381read(6);  
  return (((value>>4)&0x0f)*10+(value&0x0f));
}
  
uchar rtcGetDay(void) {
  uchar value;
  value=ht1381read(5);  
  return (value&0x0f);  // 1..7
}

void rtcGetDateTime(void) {
  rtcdate.seconds=rtcGetSeconds();
  rtcdate.minutes=rtcGetMinutes();
  rtcdate.hours=rtcGetHours();                    
  rtcdate.day=rtcGetDay();
  rtcdate.date=rtcGetDate();
  rtcdate.month=rtcGetMonth();
  rtcdate.year=rtcGetYear();  
}                  
 
void rtcSetDateTime(uchar firstTime) {
  #ifdef DEBUGRTC
  rs232puts("Start RTC oscillator and initialize date/time!\n");
  #endif
  ht1381write(7,0);
  ht1381write(0,(rtcdate.seconds%10)|((rtcdate.seconds/10)<<4));
	if (firstTime) msleep(3000); //wait until 32KHz ckock start
  ht1381write(1,(rtcdate.minutes%10)|((rtcdate.minutes/10)<<4));
  ht1381write(2,(rtcdate.hours%10)|((rtcdate.hours/10)<<4));
  ht1381write(3,(rtcdate.date%10)|((rtcdate.date/10)<<4));
  ht1381write(4,(rtcdate.month%10)|((rtcdate.month/10)<<4));
  ht1381write(5,rtcdate.day);
  ht1381write(6,(rtcdate.year%10)|((rtcdate.year/10)<<4));
}
                 
void rtcInit(void) {
  // Init HT1381
  rtcrst=0;
  rtcio=1;
  rtcsck=0;
  rtcrstm=0;
  rtciom=0;
  rtcsckm=0;  
	rtcGetDateTime();	//read current date/time
	// check date/time and initialize if it's wrong
	if (rtcdate.seconds>=60 || rtcdate.minutes>=60 || rtcdate.hours>=24 || rtcdate.date==0 || rtcdate.date>31 || rtcdate.day>7 || rtcdate.month>12 || rtcdate.year<7 ) {
		rtcdate.seconds=0;
		rtcdate.minutes=0;
		rtcdate.hours=12;
		rtcdate.date=5;
		rtcdate.month=12;
		rtcdate.year=7;
		rtcdate.day=3;
		rtcSetDateTime(1);
	}
}                                                  


