/* ---------------------------------------------------------------------------
 * rtc.c - v0.1                                         (c) 2007 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: Real time clock functionality
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, 28-11-2007, fvds.
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include "LPC23xx.h"
#include "types.h"

/* FreeRTOS includes */
#include "FreeRTOS.h"
/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "rtc.h"
#include "dio.h"

#include "BusProtocol.h"
/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */
#define IMSEC       0x00000001
#define IMMIN       0x00000002
#define IMHOUR      0x00000004
#define IMDOM       0x00000008
#define IMDOW       0x00000010
#define IMDOY       0x00000020
#define IMMON       0x00000040
#define IMYEAR      0x00000080

#define AMRSEC      0x00000001  /* Alarm mask for Seconds */
#define AMRMIN      0x00000002  /* Alarm mask for Minutes */
#define AMRHOUR     0x00000004  /* Alarm mask for Hours */
#define AMRDOM      0x00000008  /* Alarm mask for Day of Month */
#define AMRDOW      0x00000010  /* Alarm mask for Day of Week */
#define AMRDOY      0x00000020  /* Alarm mask for Day of Year */
#define AMRMON      0x00000040  /* Alarm mask for Month */
#define AMRYEAR     0x00000080  /* Alarm mask for Year */

#define PREINT_RTC  0x000001C8  /* Prescaler value, integer portion, PCLK = 15Mhz */
#define PREFRAC_RTC 0x000061C0  /* Prescaler value, fraction portion,PCLK = 15Mhz */
#define ILR_RTCCIF  0x01
#define ILR_RTCALF  0x02

#define CCR_CLKEN   0x01
#define CCR_CTCRST  0x02
#define CCR_CLKSRC  0x10


/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
extern UINT32 interruptcounter;
/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
void rtcISR (void) __attribute__ ((naked));

/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */
/** \brief Initialize RTC interface.*/
void rtcInit(void)
{
    /*--- Initialize registers ---*/
    RTC_AMR = 0;
    RTC_CIIR = 0;
    //RTC_CCR = 0;
    //RTC_PREINT = PREINT_RTC;
    //RTC_PREFRAC = PREFRAC_RTC;

    RTC_CCR = (CCR_CLKEN | CCR_CLKSRC);

    
    /* Enable RTC interrupt and register it to the VIC                      */
    //portENTER_CRITICAL();
    //    {
    //    VICIntSelect &= ~(VIC_CHAN_TO_MASK(VIC_CHAN_NUM_RTC));
    //    VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_RTC);
    //    VICVectAddr13 = (void *)rtcISR;
    //    VICVectCntl3 = 0x06;
    //    VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_RTC);
    //    }
    //portEXIT_CRITICAL();
    
    //RTC_CIIR |= 0x01;                  /* Enable Interrupt every Second    */
    //RTC_CISS = 0x80;                    /* Enable SubSecond Interrupt (488u)*/
   
}

/** \brief Read real time clock.*/
void rtcRead(t_rtc * time)
{
    time->sec = RTC_SEC;
    time->min = RTC_MIN;
    time->hour = RTC_HOUR;
    time->day = RTC_DOM;
    time->dom = RTC_DOM;
    time->dow = RTC_DOW;
    time->doy = RTC_DOY;
    time->mon = RTC_MONTH;
    time->year = RTC_YEAR;
}

/** \brief Write to real time clock.*/
void rtcWrite(t_rtc * time)
{
    RTC_SEC = time->sec;
    RTC_MIN = time->min;
    RTC_HOUR = time->hour;
    RTC_DOM = time->day;
    RTC_DOW = time->dow;
    RTC_DOY = time->doy;
    RTC_MONTH = time->mon;
    RTC_YEAR = time->year;
}
// Alarms


/* RTC INTERRUPT SERVICE ROUTINE                                            */
void rtcISR ()
{
    portSAVE_CONTEXT();                 /* Save context of interrupted task */
        {

        if (RTC_ILR & 0x01)             /* Check for Seconds Interrupt      */
            {
            RTC_ILR = 0x1;              /* Clear Seconds Interrupt          */
            }
        if (RTC_ILR & 0x04)             /* Check for SubSecond Interrupt    */
            {
            RTC_ILR = 0x4;              /* Clear SubSeconds Interrupt       */
            }
   
        VICVectAddr = 0x00000000;       /* clear Interrupts from the VIC    */
        }
    /* Restore the context of whichever task is going to run once the interrupt
     * completes. 
     */
    portRESTORE_CONTEXT();
}
