#include "pcf8583.h"
#include "main.h"
#include "i2c.h"
#include "timer128.h"
#define PCF8583Addr 0xA0 //Adres PCF8583
#define control_register 0x00 //controle register aanspreken
#define second_register 0x02 //seconde register
#define minute_register 0x03 //minuten register
#define hour_register 0x04 //uren register
#define date_register 0x05 //datum register
#define week_month_register 0x06 //weekdag, maand register
#define clock_calendar_register 0x08 //
#define year_register 0xFF //Jaartal register
volatile u08 PCF8583_status;
volatile u08 PCF8583_alarm;
unsigned char pcf8583data[2];
unsigned char *ptpcf8583data = &pcf8583data[0]; //Pointer naar PCF8583 data
u08 bcd2bin(u08 bcd)
{
#ifdef OPTIMIZE_SPEED
return (10*(bcd>>4)|(bcd&0x0f));
#else
u08 Temp = bcd & 0x0F;
while (bcd>=0x10)
{
Temp += 10;
bcd -= 0x10;
}
return Temp;
#endif
}
u08 bin2bcd(u08 bin)
{
#ifdef OPTIMIZE_SPEED
return (((bin/10)<<4)|(bin%10));
#else
u08 Temp = 0;
while(bin>9)
{
Temp += 0x10;
bin-=10;
}
return Temp+bin;
#endif
}
void PCF8583_init(void)
{
PCF8583_status=0;
PCF8583_alarm=0;
pcf8583data[0] = control_register; // control_register 0x00
PCF8583_write(0x01, ptpcf8583data);
pcf8583data[0] = control_register; // control_register 0x00
pcf8583data[1] = PCF8583_read(4)&0x3f; // hour_register 0x04
PCF8583_write(0x02, ptpcf8583data);
pcf8583data[0] = clock_calendar_register; // clock_calendar_register 0x08
pcf8583data[1] = 0x90; // 1011010
PCF8583_write(0x02, ptpcf8583data);
}
void PCF8583_stop(void)
{
pcf8583data[0] = control_register; // control_register 0x0
pcf8583data[1] = 0x80;
PCF8583_write(0x02, ptpcf8583data);
}
void PCF8583_start(void)
{
pcf8583data[0] = control_register;
pcf8583data[1] = 0x00;
PCF8583_write(0x02, ptpcf8583data);
}
void PCF8583_write(u08 lenght,unsigned char data[2])
{
i2cMasterSend(PCF8583Addr, lenght, ptpcf8583data);
}
void PCF8583_write_bcd(u08 address,u08 data)
{
pcf8583data[0] = address;
pcf8583data[1] = bin2bcd(data);
PCF8583_write(0x02,pcf8583data);
}
void PCF8583_write_date(u08 address,u08 day,u16 year)
{
pcf8583data[0] = address;
pcf8583data[1] = bin2bcd(day)|(((u08) year&3)<<6);
PCF8583_write(0x02,pcf8583data);
// PCF8583_write(address,bin2bcd(day)|(((u08) year&3)<<6));
}
void PCF8583_write_word(u08 address,u16 data)
{
pcf8583data[0] = address;
pcf8583data[1] = (u08) data&0xff;
PCF8583_write(0x02, pcf8583data);
pcf8583data[0] = ++address;
pcf8583data[1] = (u08)(data>>8);
PCF8583_write(0x02,pcf8583data);
// PCF8583_write(address,(u08) data&0xff);
// PCF8583_write(++address,(u08)(data>>8));
}
void PCF8583_set_time(u08 hour,u08 min,u08 sec,u08 hsec)
{
// if (hour>23) hour=0;
// if (min>59) min=0;
// if (sec>59) sec=0;
// if (hsec>100) hsec=0;
//PCF8583_stop();
PCF8583_write_bcd(1,hsec);
PCF8583_write_bcd(2,sec);
PCF8583_write_bcd(3,min);
PCF8583_write_bcd(4,hour);
//PCF8583_start();
}
void PCF8583_set_date(u08 day,u08 month,u16 year)
{
PCF8583_write_word(16,year);
PCF8583_stop();
PCF8583_write_date(5,day,year);
PCF8583_write_bcd(6,month);
PCF8583_start();
}
void PCF8583_set_alarm_time(u08 hour,u08 min,u08 sec,u08 hsec)
{
PCF8583_write_bcd(0x9,hsec);
PCF8583_write_bcd(0xa,sec);
PCF8583_write_bcd(0xb,min);
PCF8583_write_bcd(0xc,hour);
}
void PCF8583_set_alarm_date(u08 day,u08 month)
{
PCF8583_write_date(0xd,day,0);
PCF8583_write_bcd(0xe,month);
}
u08 PCF8583_read_bcd(u08 address)
{
return bcd2bin(PCF8583_read(address));
}
unsigned char PCF8583_read(u08 address)
{
pcf8583data[0] = address;
PCF8583_write(0x01, ptpcf8583data);
timerPause(5);
i2cMasterReceive(PCF8583Addr, 0x1, ptpcf8583data);
return pcf8583data[0];
}
void PCF8583_hold_on(void)
{
PCF8583_get_status();
PCF8583_status|=0x40;
pcf8583data[0] = 0;
pcf8583data[1] = PCF8583_status;
PCF8583_write(0x02,pcf8583data);
}
void PCF8583_hold_off(void)
{
PCF8583_get_status();
PCF8583_status&=0xbf;
pcf8583data[0] = 0;
pcf8583data[1] = PCF8583_status;
PCF8583_write(0x02,pcf8583data);
}
void PCF8583_get_time(u08 *hour,u08 *min,u08 *sec,u08 *hsec)
{
PCF8583_hold_on();
*hsec=PCF8583_read_bcd(1);
*sec=PCF8583_read_bcd(2);
*min=PCF8583_read_bcd(3);
*hour=PCF8583_read_bcd(4);
PCF8583_hold_off();
}
u08 PCF8583_get_status(void)
{
pcf8583data[0] = 0;
PCF8583_status = PCF8583_read(0);
PCF8583_alarm=(PCF8583_status & 2);
return PCF8583_status;
}
void PCF8583_get_date(u08 *day,u08 *month,u16 *year)
{
u08 dy;
u16 y1;
PCF8583_hold_on();
pcf8583data[0] = 0;
pcf8583data[1] = 0;
dy=PCF8583_read(date_register); // date_register 0x05
pcf8583data[0] = 0;
pcf8583data[1] = 0;
*month=bcd2bin(PCF8583_read(week_month_register)&0x1f); // week_month_register 0x06
PCF8583_hold_off();
*day=bcd2bin(dy&0x3f);
dy>>=6;
pcf8583data[0] = 0;
pcf8583data[1] = 0;
y1=PCF8583_read(16)|((u16) PCF8583_read(17)<<8);
if (((u08) y1&3)!=dy)
PCF8583_write_word(16,++y1);
*year=y1;
}
void PCF8583_get_alarm_time(u08 *hour,u08 *min,u08 *sec,u08 *hsec)
{
*hsec=PCF8583_read_bcd(0x9);
*sec=PCF8583_read_bcd(0xa);
*min=PCF8583_read_bcd(0xb);
*hour=PCF8583_read_bcd(0xc);
}
void PCF8583_get_alarm_date(u08 *day,u08 *month)
{
*day=bcd2bin(PCF8583_read(0xd)&0x3f);
*month=bcd2bin(PCF8583_read(0xe)&0x1f);
}
void PCF8583_alarm_on(void)
{
PCF8583_get_status();
// PCF8583_status|=4;
pcf8583data[0] = 0;
pcf8583data[1] = PCF8583_status|=4; // set 00000100
PCF8583_write(0x02,pcf8583data);
}
void PCF8583_alarm_off(void)
{
PCF8583_get_status();
//PCF8583_status&=0xfb;
pcf8583data[0] = 0;
pcf8583data[1] = PCF8583_status&= 0x03; // set 00000011
PCF8583_write(0x02,pcf8583data);
}