/****************************************************************************
 *
 * Projekt			:	Glacier Batterieboxdeckel Prüfgerät
 * Dateiname		:	drvRtc.c
 * Autor			:	orginal MHoffmann, abgeändert für dieses Projekt Irene Saxer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Treiber fuer Zugriffe auf die externe RTC"
 *
 *
 * Versionsgeschichte
 * 	Revision 1.0	17.04.2019 SAI erste Version
 *
 ****************************************************************************/

/****************************************************************************/
/* COMPILER Direktiven */

/****************************************************************************/
/* INCLUDE Dateien */
#include "DrvRtc.h"

/****************************************************************************/
/* KONSTANTEN */

/****************************************************************************/
/* Globale Variablen */
static void DrvRtc_Xfer(uint8_t* pu8_Data, uint16_t u16_Len);

/****************************************************************************/
/* Funktionen */

void DrvRtc_Init(void)
{
	uint8_t u8_Tmp;

	RTC_NCS;			//CS fuer extRTC auf inaktiv setzen	
	
	//SPI des AVR initialisieren (1MHz)
	SPSR = (1<<SPI2X);
	SPCR = (0<<SPE)|(1<<MSTR)|(0<<SPR0)|(1<<SPR1)|(0<<CPOL)|(0<<CPHA)|(0<<DORD);

	//Status- und Datareg lesen, um ggf gesetztes INT-Flag zu loeschen
	u8_Tmp = SPSR;
	u8_Tmp = SPDR;
}

void DrvRtc_Write(uint8_t x)
{
	DrvRtc_Xfer(&x, 1);
}

//hw-communication (uebertraegt ohne nachzupruefen die uebergebenen Daten (~mengen))
static void DrvRtc_Xfer(uint8_t* pu8_Data, uint16_t u16_Len)
{
	uint16_t u16_i;
	uint8_t* pu8_x = pu8_Data;

	RTC_ENABLE;
	RTC_CS;

	//jedes Byte einzeln lesen
	for (u16_i=0; u16_i<u16_Len; u16_i++)
	{
		SPDR = (uint8_t)*(pu8_x);		//out-Daten in das SPI-Register kopieren
		while( !(SPSR & (1<<SPIF)));	//warten, bis daten uebertragen sind
		*(pu8_x) = SPDR;				//in-Daten aus dem SPI-Register holen
		pu8_x++;
	}

	RTC_NCS;
	RTC_DISABLE;
}

//Temperatur der RTC auslesen
int16_t DrvRtc_GetTemp(void)
{
	uint8_t buf[2];
	int16_t rv;
	
	buf[0] = BM_CMD_RTC_READ | 0x20;	//Temperaturregister lesen
	DrvRtc_Xfer(buf, 2);				//Datentransfer anstossen
	rv = (int16_t)buf[1];
	rv-= 60;
	
	return rv;
}

//Datum und Zeit von der RTC holen
uint8_t DrvRtc_GetDateTime(tDateTime* pDT)
{
	uint8_t u8_RetVal = 0;	//0==gueltige Zeit gelesen; 1==ungueltige Zeitangabe in pDT
	uint8_t buf[8];
	uint8_t i, u8_tmp;
	
	//Kommandobyte setzen  "Lesen" + Adresse des Sekundenzaehlers
	buf[0] = BM_CMD_RTC_READ | 0x08;
	
	//Feld mit Nullen beschreiben
	for (i=1; i<8; i++)
		buf[i] = 0;
	
	//Datentransfer anstossen
	DrvRtc_Xfer(buf, 8);
	
	//Daten aus Buffer holen und in uebergebene Struktur schreiben
	//Sekunden
	u8_tmp = buf[1];	
	pDT->sek = (u8_tmp&0x0f) + 10*(u8_tmp>>4);

	//Minuten
	u8_tmp = buf[2];	
	pDT->min = (u8_tmp&0x0f) + 10*(u8_tmp>>4);
	
	//Stunden
	u8_tmp = buf[3];	
	pDT->std = (u8_tmp&0x0f) + 10*(u8_tmp>>4);

	//Tag
	u8_tmp = buf[4];	
	pDT->tag = (u8_tmp&0x0f) + 10*(u8_tmp>>4);

	//Monat
	u8_tmp = buf[6];	
	pDT->mon = (u8_tmp&0x0f) + 10*(u8_tmp>>4);

	//Jahr
	u8_tmp = buf[7];	
	pDT->jhr = (u8_tmp&0x0f) + 10*(u8_tmp>>4);

	return u8_RetVal;
}


//Datum und Zeit in der RTC setzen
void DrvRtc_SetDateTime(tDateTime* pDT)
{
	uint8_t buf[8];
	
	//Kommandobyte setzen  "Schreiben" + Adresse des Sekundenzaehlers
	buf[0] = BM_CMD_RTC_WRITE | 0x08;

	//Zeit in Buffer legen
	buf[1] = (pDT->sek%10) + (pDT->sek/10)*0x10;
	buf[2] = (pDT->min%10) + (pDT->min/10)*0x10;
	buf[3] = (pDT->std%10) + (pDT->std/10)*0x10;
	buf[4] = (pDT->tag%10) + (pDT->tag/10)*0x10;
	buf[6] = (pDT->mon%10) + (pDT->mon/10)*0x10;
	buf[7] = (pDT->jhr%10) + (pDT->jhr/10)*0x10;
	
	//Datentransfer anstossen
	DrvRtc_Xfer(buf, 8);
}


uint8_t Stunden(tDateTime DT)
{
	return DT.std;
}


uint8_t Minuten(tDateTime DT)
{
	return DT.min;
}


uint8_t Sekunden(tDateTime DT)
{
	return DT.sek;
}


uint8_t Tag(tDateTime DT)
{
	return DT.tag;
}


uint8_t Monat(tDateTime DT)
{
	return DT.mon;
}


uint8_t Jahr(tDateTime DT)
{
	return DT.jhr;
}


