/*********************************************************************************************************
        rtc.c  -  This file contains function used to communicate with RTC                  
        
*********************************************************************************************************/

/*********************************************************************************************************
                       File description here 
                                                                                                                          
Filename               : rtc.c
Version                : V1.1
Last Modified		   : 09-05-17 
Programmer(s) initials : Amol Wadkar                         

All major MACROS used in this file are define in rtc.h	 */








#include "inc/hw_memmap.h"
#include "rtc.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "inc/hw_ints.h"
#include "hw_types.h"
#include "pins.h"
#include "global.h"
#include "io_expander.h"
#include "command.h"
#include "appl_ext_flash.h"
#include "pheripheral.h"

date_time current_time;
date_time date_time_variable;
date_time new_present_time;
date_time new_udp_present_time;
unsigned char rtc_Read(unsigned char slave_addr, unsigned char Reg);
void rtc_Write(unsigned char slave_addr, unsigned char Reg, unsigned char value );
long set_Current_Date_Time(date_time* new_Date_Time );
int current_day;

/*
This function will read the data from the slave device register and return its value
Parameters: 
slave_addr -> address of the slave device
Reg		   -> Address of the register to be read
Return Type:
The function will return the value stored in the register 
*/

unsigned char rtc_Read(unsigned char slave_addr, unsigned char Reg)
{
	int i;
	i2c_timeout_counter = 0;
	I2CMasterSlaveAddrSet(I2C0_MASTER_BASE,slave_addr , false);
	I2CMasterDataPut(I2C0_MASTER_BASE, Reg);
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    while(I2CMasterBusy(I2C0_MASTER_BASE) && (i2c_timeout_counter < 2));
	if(i2c_timeout_counter >= 2)
	{
		I2C0_init();
		for(i = 0; i<3; i++)
		{
			long_beep(500,2);
		}
	}
	i2c_timeout_counter = 0;
	I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, slave_addr , true);
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
 	while(I2CMasterBusy(I2C0_MASTER_BASE) && (i2c_timeout_counter < 2));
	if(i2c_timeout_counter >= 2)
	{
		I2C0_init();
		for(i = 0; i<3; i++)
		{
			long_beep(500,2);
		}
	}
	return(I2CMasterDataGet(I2C0_MASTER_BASE));
}

/*
This function will write the data to the slave device register
Parameters: 
slave_addr  ->  address of the slave device
Reg		    ->  Address of the register to be read
value	    ->  value that should be written to the register
*/

void rtc_Write(unsigned char slave_addr, unsigned char Reg, unsigned char value )
{
	int i;
	i2c_timeout_counter = 0;
	I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, slave_addr , false);
	I2CMasterDataPut(I2C0_MASTER_BASE, Reg);
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    while(I2CMasterBusy(I2C0_MASTER_BASE) && (i2c_timeout_counter < 2));
	if(i2c_timeout_counter >= 2)
	{
		I2C0_init();
		for(i = 0; i<3; i++)
		{
			long_beep(500,2);
		}
	}
	i2c_timeout_counter = 0;
	I2CMasterDataPut(I2C0_MASTER_BASE, value);
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
    while(I2CMasterBusy(I2C0_MASTER_BASE) && (i2c_timeout_counter < 2));
	if(i2c_timeout_counter >= 2)
	{
		I2C0_init();
		for(i = 0; i<3; i++)
		{
			long_beep(500,2);
		}
	}
}

/*
This function will return current date and time
Return Type:
date_time structure pointer
*/

date_time* get_Current_Date_Time()
{
//	int i=0;
	current_time.sec    = bcd_to_hex(rtc_Read(RTC_ADDR, SECOND ) & 0x7F);
	current_time.min    = bcd_to_hex(rtc_Read(RTC_ADDR, MINUTE ) & 0x7F);
	current_time.hour   = bcd_to_hex(rtc_Read(RTC_ADDR, HOUR   ) & 0x3F);
	current_time.date   = bcd_to_hex(rtc_Read(RTC_ADDR, DATE   ) & 0x3F);
	current_time.month  = bcd_to_hex(rtc_Read(RTC_ADDR, MONTH  ) & 0x1F);
	current_time.year   = bcd_to_hex(rtc_Read(RTC_ADDR, YEAR   ) & 0xFF);	
	current_day 		= bcd_to_hex(rtc_Read(RTC_ADDR, DAY    ) & 0x07);
	
	if(	(current_time.year<=100) && (current_time.date>=1)  && 
		(current_time.date<=31)  && (current_time.month>=1)	&& 
		(current_time.month<=12) && (current_time.hour<=23) && 
		(current_time.min<=59) 	 && (current_time.sec<=59)	   )
	{
		return &current_time;
	}
	else
	{
		I2C0_init();
		return 0;
	}
}

/*
This function will set date and time
Parameter:
new_Date_Time  -> date_time structure pointer
*/

long set_Current_Date_Time(date_time* new_Date_Time )
{
	if(validate_datetime(new_Date_Time))
	{
		if((new_Date_Time->year != date_time_variable.year) || (new_Date_Time->month != date_time_variable.month) ||(new_Date_Time->date != date_time_variable.date) ||(new_Date_Time->hour != date_time_variable.hour) ||(new_Date_Time->min != date_time_variable.min) )
		{
			rtc_Write (RTC_ADDR , SECOND , hex_to_bcd(new_Date_Time->sec)    );
			rtc_Write (RTC_ADDR , MINUTE , hex_to_bcd(new_Date_Time->min)    );
			rtc_Write (RTC_ADDR , HOUR   , hex_to_bcd(new_Date_Time->hour)   );
			rtc_Write (RTC_ADDR , DATE   , hex_to_bcd(new_Date_Time->date) 	 );
			rtc_Write (RTC_ADDR , MONTH  , hex_to_bcd(new_Date_Time->month)  );
			rtc_Write (RTC_ADDR , YEAR   , hex_to_bcd(new_Date_Time->year)	 );			
		}
		return(0);	
	}
	return(-1);	
}
