/****************************************************************************/
/* Copyright 2011 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include "ex_rtc.h"
#include "spi.h"
#include <string.h>
#include <stdio.h>

unsigned char dec2Bcd(unsigned char dec);
unsigned char bcd2Dec(unsigned char bcd);


void rtcInit()
{
    spiCS2(1);
    
    /* set the clock conifg */
    spiReadWrite(0x8E);
    spiReadWrite(0x00);
    
    spiCS2(0);
    
    return;
}

int rtcSet(RtcTime* time)
{ 
    unsigned char reg;

    spiCS2(1);
    
    /* setup for write to seconds reg */
    spiReadWrite(0x80);

    /* write seconds */
    reg = dec2Bcd(time->seconds);
    spiReadWrite(reg);
    
    /* write minutes */
    reg = dec2Bcd(time->minutes);
    spiReadWrite(reg);
    
    /* write hours in 24 hour mode */
    reg = dec2Bcd(time->hours);
    spiReadWrite(reg);
    
    /* write day of week */
    spiReadWrite(time->day);
    
    /* write date */
    reg = dec2Bcd(time->date);
    spiReadWrite(reg);
    
    /* write month */
    reg = dec2Bcd(time->month);
    spiReadWrite(reg);

    /* write year */
    reg = dec2Bcd(time->year);
    spiReadWrite(reg);
    
    spiCS2(0);

    
    
    return 0;
}

int rtcRead(RtcTime* time)
{ 
    unsigned char reg;

    spiCS2(1);
    
    /* setup for read from seconds reg */
    spiReadWrite(0x00);

    /* read seconds */
    reg = spiReadWrite(0x55);
    time->seconds = bcd2Dec(reg);
    
    /* read minutes */
    reg = spiReadWrite(0x55);
    time->minutes = bcd2Dec(reg);
    
    /* read hours in 24 hour mode */
    reg = spiReadWrite(0x55);
    time->hours = bcd2Dec(reg);
    
    /* read day of week */
    time->day = spiReadWrite(0x55);
    
    /* read date */
    reg = spiReadWrite(0x55);
    time->date = bcd2Dec(reg);
    
    /* read month */
    reg = spiReadWrite(0x55);
    time->month = bcd2Dec(reg);

    /* read year */
    reg = spiReadWrite(0x55);
    time->year = bcd2Dec(reg);
    
    spiCS2(0);

    return 0;
}

int rtcTimeDateStr(char* tm_str)
{
    RtcTime rtc;
    char buff[64];

    rtcRead(&rtc);

    switch ( rtc.day )
    {
        case 1: strcpy(tm_str, "Sun "); break;
        case 2: strcpy(tm_str, "Mon "); break;
        case 3: strcpy(tm_str, "Tue "); break;
        case 4: strcpy(tm_str, "Wed "); break;
        case 5: strcpy(tm_str, "Thu "); break;
        case 6: strcpy(tm_str, "Fri "); break;
        case 7: strcpy(tm_str, "Sat "); break;
        default: strcpy(tm_str, "??? ");
    }

    switch ( rtc.month )
    {
        case 1: strcat(tm_str, "Jan "); break;
        case 2: strcat(tm_str, "Feb "); break;
        case 3: strcat(tm_str, "Mar "); break;
        case 4: strcat(tm_str, "Apr "); break;
        case 5: strcat(tm_str, "May "); break;
        case 6: strcat(tm_str, "Jun "); break;
        case 7: strcat(tm_str, "Jul "); break;
        case 8: strcat(tm_str, "Aug "); break;
        case 9: strcat(tm_str, "Sep "); break;
        case 10: strcat(tm_str, "Oct "); break;
        case 11: strcat(tm_str, "Nov "); break;
        case 12: strcat(tm_str, "Dec "); break;
        default: strcat(tm_str, "??? ");
    }

    sprintf(buff, "%d %02d:%02d:%02d %d", 
            rtc.date, rtc.hours, rtc.minutes, rtc.seconds, (2000 + rtc.year));

    strcat(tm_str, buff);
    
    return 0;
}

int rtcTimeStampStr(char* tm_str)
{
    RtcTime rtc;

    rtcRead(&rtc);
    
    sprintf(tm_str, "%d/%d/%d %02d:%02d:%02d", 
            rtc.month, rtc.date, (2000 + rtc.year), 
            rtc.hours, rtc.minutes, rtc.seconds);

    return 0;
}

unsigned char dec2Bcd(unsigned char dec)
{
    unsigned char bcd;
    
    /* convert the upper nibble */
    bcd = (dec / 10) << 4;
    
    /* convert and add the lower nibble */
    bcd += (dec % 10);
    
    return bcd;
}

unsigned char bcd2Dec(unsigned char bcd)
{
    unsigned char dec;

    /* convert the lower nibble */
    dec = (bcd & 0x0F); 
    
    /* convert and add the upper nibble */
    dec += ((bcd & 0xF0) >> 4) * 10;
    
    return dec;
}

