
//****************************************************************************
// @Module        Project Settings
// @Filename     Rtc.C
// @Project        Sem3000 
//----------------------------------------------------------------------------
// @Controller    SI1010
//
// @Compiler      KEIL uVision V
//
// @ Frequency   Using internal clock MHz
//
// @Codegenerator 0.1
//
// @Description   This file contains the Project voice recoding  function.
//
//----------------------------------------------------------------------------
// @Date          2013-05-28  
//
//****************************************************************************

#define _Rtc__C_


#include "PROJECT_INCLUDES.H"


U8 RTC0CN_Local;                       // Holds the desired RTC0CN settings

idata U8 fOne_Hour;
idata U8 fOne_Minute;
idata U8 f_Sec=0;

void RTC0CN_SetBits(U8 bits)
{
	RTC0CN_Local |= (bits & ~0x03);
	
	RTC_Write( RTC0CN, RTC0CN_Local | bits);
}


void Default_Set_Time_And_Day(void)
{
	#if 0
   	event1.seconds= SECOND_INIT=00;  
   	event1.minutes=MINUTE_INIT=01;
   	event1.hours= HOUR_INIT=00;
	#else
	SECOND_INIT=00;  
   	MINUTE_INIT=event1.minutes;
   	HOUR_INIT=event1.hours;
   	#endif
   	event1.years	=2016;
	
	#ifdef WEEK_START_MONDAY
	event1.Week=Mon;
	#else
	 event1.Week=Sun;
	#endif
	event1.Pm_Am=AM; 

  	Compute_365_Total_Day(event1.years, 3,8, & event1.days );

	
}

//-----------------------------------------------------------------------------
// Return Value : None
// Parameters   : None
//
// This function will initialize the RTC. First it unlocks the RTC interface, enables the RTC, clears ALRMn and CAPTUREn bits. Then it sets up the RTC
// to operate using a 32.768khZ crystal. Lastly it enables the alarm and interrupt. This function uses the RTC primitive functions to access 
// the internal RTC registers.
//
//-----------------------------------------------------------------------------


#define	RTC_Oscillator_Crystal_Mode_Select()  	RTC_Write (RTC0XCN, 0x60); 
#define	Enable_Automatic_Load_Capacitance() 	RTC_Write (RTC0XCF, 0x83); 
#define	RTC_Run_And_Alarm_With_Auto_Reset()	RTC_Write (RTC0CN, 0xDC);

void RTC_Init (void)
{
	unsigned int i;

	unsigned char CLKSEL_SAVE ; 

	CLKSEL_SAVE = CLKSEL;   

	if(RTC0KEY == 0x00)
	{
		RTC0KEY = 0xA5;                  // Unlock the smaRTClock interface
		RTC0KEY = 0xF1;
	}	  

	RTC_Oscillator_Crystal_Mode_Select();
	
	Enable_Automatic_Load_Capacitance();
	
	RTC_Write (RTC0CN, 0x80);           //1 0x80   Enable smaRTClock oscillator
											/*
											Bit Name Function
											7 RTC0EN SmaRTClock Enable.
																Enables/disables the SmaRTClock oscillator and associated bias currents.
																0: SmaRTClock oscillator disabled.
																1: SmaRTClock oscillator enabled.
											6 MCLKEN Missing SmaRTClock Detector Enable.
																Enables/disables the missing SmaRTClock detector.
																0: Missing SmaRTClock detector disabled.
																1: Missing SmaRTClock detector enabled.
											5 OSCFAIL SmaRTClock Oscillator Fail Event Flag.
																Set by hardware when a missing SmaRTClock detector timeout occurs. Must be
																cleared by software. The value of this bit is not defined when the SmaRTClock oscillator is disabled.
											4 RTC0TR SmaRTClock Timer Run Control.
																Controls if the SmaRTClock timer is running or stopped (holds current value).
																0: SmaRTClock timer is stopped.
																1: SmaRTClock timer is running.

													
											3 RTC0AEN SmaRTClock Alarm Enable.
																Enables/disables the SmaRTClock alarm function. Also clears the ALRM flag.
																0: SmaRTClock alarm disabled.
																1: SmaRTClock alarm enabled.
											2 ALRM SmaRTClock Alarm Event 	Flag and Auto Reset	Enable.
																Reads return the state of the	alarm event flag.Writes enable/disable the 	Auto Reset function.
																Read:
																		0: SmaRTClock alarm event flag is de-asserted.
																		1: SmaRTClock alarm	event flag is asserted.
																Write:
																		0: Disable Auto Reset.
																		1: Enable Auto Reset.
											1 RTC0SET SmaRTClock Timer Set.
																Writing 1 initiates a SmaRTClock timer set operation. This bit is cleared to 0 by hardware
																to indicate that the timer set operation is complete.
											0 RTC0CAP SmaRTClock Timer Capture.
															Writing 1 initiates a SmaRTClock timer capture operation. This bit is cleared to 0 by
															hardware to indicate that the timer capture operation is complete.
											Note: The ALRM flag will remain asserted for a maximum of one SmaRTClock cycle. See Section ¨Power
											Management〃 on page 157 for information on how to capture a SmaRTClock Alarm event using a flag which
											is not automatically cleared by hardware. 
											*/

	//----------------------------------
	// Wait for smaRTClock to start
	//----------------------------------

	CLKSEL    =  0x74;                  // Switch to 156 kHz low power internal oscillator
	                              
	for (i=0x150;i!=0;i--);   //1 Wait > 20 ms

	while ((RTC_Read (RTC0XCN) & 0x10)== 0x00);  //1 Wait for smaRTClock valid
	while ((RTC_Read (RTC0XCF) & 0x40)== 0x00); //1 Wait for Load Capacitance Ready 

	//----------------------------------
	// smaRTClock has been started
	//----------------------------------

	RTC_Write (RTC0XCN, 0xc0);     //1 0xC0 Enable Automatic Gain Control and disable bias doubling
											/*
											Bit 	Name Function
											7 	AGCEN SmaRTClock Oscillator Automatic Gain Control (AGC) Enable.
																0: AGC disabled.
																1: AGC enabled.
													
											6 XMODE SmaRTClock Oscillator Mode.
															Selects Crystal or Self Oscillate Mode.
															0: Self-Oscillate Mode selected.
															1: Crystal Mode selected.
											5 BIASX2 SmaRTClock Oscillator Bias Double Enable.
															Enables/disables the Bias Double feature.
															0: Bias Double disabled.
															1: Bias Double enabled.
											4 CLKVLD SmaRTClock Oscillator Crystal Valid Indicator.
															Indicates if oscillation amplitude is sufficient for maintaining oscillation.
															0: Oscillation has not started or oscillation amplitude is too low to maintain oscillation.
															1: Sufficient oscillation amplitude detected.

													
											3 LFOEN Low Frequency Oscillator Enable and Select.
															Overrides XMODE and selects the internal low frequency oscillator (LFO) as the SmaRTClock oscillator source. 
															Only available on ‘F912 and ‘F902 devices.
															0: XMODE determines SmaRTClock oscillator source.
															1: LFO enabled and selected as SmaRTClock oscillator source.
											2:0 Unused Read = 000b; Write = Don’t Care.   
											*/
	RTC_Write (RTC0CN, 0xC0);       //1 0xC0 Enable missing smaRTClock detector and leave smaRTClock oscillator enabled. 
											/*
											Bit Name Function
											7 RTC0EN SmaRTClock Enable.
													Enables/disables the SmaRTClock oscillator and associated bias currents.
													0: SmaRTClock oscillator disabled.
													1: SmaRTClock oscillator enabled.
											6 MCLKEN Missing SmaRTClock Detector Enable.
													Enables/disables the missing SmaRTClock detector.
													0: Missing SmaRTClock detector disabled.
													1: Missing SmaRTClock detector enabled.
											5 OSCFAIL SmaRTClock Oscillator Fail Event Flag.
													Set by hardware when a missing SmaRTClock detector timeout occurs. Must be
													cleared by software. The value of this bit is not defined when the SmaRTClock oscillator is disabled.
											4 RTC0TR SmaRTClock Timer Run Control.
													Controls if the SmaRTClock timer is running or stopped (holds current value).
													0: SmaRTClock timer is stopped.
													1: SmaRTClock timer is running.

													
											3 RTC0AEN SmaRTClock Alarm Enable.
													Enables/disables the SmaRTClock alarm function. Also clears the ALRM flag.
													0: SmaRTClock alarm disabled.
													1: SmaRTClock alarm enabled.
											2 ALRM SmaRTClock Alarm Event 	Flag and Auto Reset	Enable.
													Reads return the state of the	alarm event flag.Writes enable/disable the 	Auto Reset function.
													Read:
															0: SmaRTClock alarm event flag is de-asserted.
															1: SmaRTClock alarm	event flag is asserted.
													Write:
															0: Disable Auto Reset.
															1: Enable Auto Reset.
											1 RTC0SET SmaRTClock Timer Set.
															Writing 1 initiates a SmaRTClock timer set operation. This bit is cleared to 0 by hardware
															to indicate that the timer set operation is complete.
											0 RTC0CAP SmaRTClock Timer Capture.
															Writing 1 initiates a SmaRTClock timer capture operation. This bit is cleared to 0 by
															hardware to indicate that the timer capture operation is complete.
											Note: The ALRM flag will remain asserted for a maximum of one SmaRTClock cycle. See Section ¨Power
											Management〃 on page 157 for information on how to capture a SmaRTClock Alarm event using a flag which
											is not automatically cleared by hardware. 
											*/

	for (i=0x40;i!=0;i--);      //1 Wait > 2 ms

	PMU0CF = 0x20;                      //1 Clear PMU wake-up source flags

	CLKSEL = CLKSEL_SAVE;               // Restore system clock
	while(!(CLKSEL & 0x80));            //1 Poll CLKRDY


	// Initialize DATE_INFO struct

	Default_Set_Time_And_Day();

	
	RTC_SetTimer(TIME_INIT);  // 초기 시간 설정 
	
	RTC0CN_Local = 0xC0;                // Initialize Local Copy of RTC0CN

	RTC0CN_SetBits(RTC0TR+RTC0AEN+ALRM);// Enable Counter, Alarm, and Auto-Reset

	RTC_WriteAlarm(RTC_DAY);   // 24시  00분 00 초 가 되면  알람 과 동시  32bit  RTC 카운트를 초기화 한다 

   	RTC_Run_And_Alarm_With_Auto_Reset();
	
}

//-----------------------------------------------------------------------------
//
// Return Value : RTC0DAT
// Parameters   : 1) unsigned char reg - address of RTC register to read
//
// This function will read one byte from the specified RTC register.
// Using a register number greater that 0x0F is not permited.
//
//-----------------------------------------------------------------------------

unsigned char RTC_Read (unsigned char reg)
{
	reg &= 0x0F;      
	
	RTC0ADR  = reg;      
	
	RTC0ADR |= 0x80;                            //1 set BUSY bit to read
	
	while ((RTC0ADR & 0x80) == 0x80);   //1 poll on the BUSY bit
	
	return RTC0DAT;                       
}

//-----------------------------------------------------------------------------
// RTC_Write ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : 1) unsigned char reg - address of RTC register to write
//                2) unsigned char value - the value to write to <reg>
//
// This function will Write one byte to the specified RTC register.
// Using a register number greater that 0x0F is not permited.
//-----------------------------------------------------------------------------

void RTC_Write (unsigned char reg, unsigned char value)
{
	reg &= 0x0F;                        // mask low nibble
	
	RTC0ADR  = reg;                     // pick register
	
	RTC0DAT = value;                    // write data
	
	while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
}



//-----------------------------------------------------------------------------
// Leap_Year
//-----------------------------------------------------------------------------
//
// Return Value : '1' if a leap year, '0' if not a leap year
// Parameters   : U16 year - the current year in the counter
//
// This function will return a whether a year is a leap year or not
//
//-----------------------------------------------------------------------------

volatile U8 Leap_Year (U16 volatile year)
{
	if ((((year%4)==0) && ((year%100)!=0)) || ((year%400)==0))
	{
	 	return 1;
	}
	
	return 0;
}



/*
*********************************************************************************************************
*                                                              Compute_Month 
*
* Description:       RTC 의 total day 카운트를   month  days 로  계산 한다 
*
* Arguments  :  
* 				1) U16* month - pointer to month number variable (1-12)
*                		2) U16* days 	 - pointer to number of days  variable (1-31)
*                		3) U16 total     - total number of days to compute month and days from
*                		4) U16 total     - current year (in 20xx format)
*
* Returns      :   NONE

*********************************************************************************************************
*/

void Compute_Month (U8* month, U8* days, U16 total, U16 year)
{
   if (total < 32){         //1 First month does not depend on  leap year

		      (*month) = 1;      //1 January
		      (*days) = total;
   }
   else if (Leap_Year(year))
   {
			      //1 윤년에 따라 달을 계산
			      if (total < 61) {
				         (*month) = 2;                 // February
				         (*days) = total-31;
			      }
			      else if (total < 92) {
				         (*month) = 3;                 // March
				         (*days) = total-60;
			      }
			      else if (total < 122){
				         (*month) = 4;                 // April
				         (*days) = total - 91;
			      }
			      else if (total < 153){
				         (*month) = 5;                 // May
				         (*days) = total - 121;
			      }
			      else if (total < 183){
			        	 (*month) = 6;                 // June
			         	(*days) = total-152;
			      }
			      else if (total < 214) {
				         (*month) = 7;                 // July
				         (*days) = total - 182;
			      }
			      else if (total < 245)
			      {
				         (*month) = 8;                 // August
				         (*days) = total - 213;
			      }
			      else if (total < 275)
			      {
				         (*month) = 9;                 // September
				         (*days) = total - 244;
			      }
			      else if (total < 306)
			      {
				         (*month) = 10;                // October
				         (*days) = total-274;
			      }
			      else if (total < 336)
			      {
				         (*month) = 11;                // November
				         (*days) = total - 305;
			      }
			      else
			      {
				         (*month) = 12;                // December
				         (*days) = total - 335;
			      }

   }
   else {
		      //1 비 윤년에 따라 달을 계산
		      if (total < 60)
		      {
			         (*month) = 2;                 // February
			         (*days) = total-31;
		      }
		      else if (total < 91)
		      {
			         (*month) = 3;                 // March
			         (*days) = total-59;
		      }
		      else if (total < 121)
		      {
			         (*month) = 4;                 // April
			         (*days) = total - 90;
		      }
		      else if (total < 152)
		      {
			         (*month) = 5;                 // May
			         (*days) = total - 120;
		      }
		      else if (total < 182)
		      {
			         (*month) = 6;                 // June
			         (*days) = total-151;
		      }
		      else if (total < 213)
		      {
			         (*month) = 7;                 // July
			         (*days) = total - 181;
		      }
		      else if (total < 244)
		      {
			         (*month) = 8;                 // August
			         (*days) = total - 212;
		      }
		      else if (total < 274)
		      {
			         (*month) = 9;                 // September
			         (*days) = total - 243;
		      }
		      else if (total < 305)
		      {
			         (*month) = 10;                // October
			         (*days) = total-273;
		      }
		      else if (total < 335)
		      {
			         (*month) = 11;                // November
			         (*days) = total - 304;
		      }
		      else
		      {
			         (*month) = 12;                // December
			         (*days) = total - 334;
		      }
   }
}



/*
*********************************************************************************************************
*                                                              Compute_Month 
*
* Description:       month  days  를   RTC 의 total day 카운트 로  계산 한다 
*
* Arguments  :  
* 				1) U16* month - pointer to month number variable (1-12)
*                		2) U16* days 	 - pointer to number of days  variable (1-31)
*                		3) U16 total     - total number of days to compute month and days from
*                		4) U16 total     - current year (in 20xx format)
*
* Returns      :   NONE

*********************************************************************************************************
*/
enum MONTH_NUMBER_DEFINE{
	MONTH_1=1, MONTH_2,  MONTH_3,  MONTH_4,  MONTH_5 , MONTH_6, MONTH__7, MONTH_8, MONTH_9, MONTH_10, MONTH_11,MONTH_12
};


void Compute_365_Total_Day(U16 year,  U8 month, U8 days, U16 *Total_Day)
{

   if (month==1 ){         //1 First month does not depend on  leap year

		     if(days<32) (*Total_Day) = days;
		    else 	 (*Total_Day) = 31;
   }
   else if (Leap_Year(year))
   {
			      //1 윤년에 따라 달을 계산
		switch(month)
		{					
			  case MONTH_2:
			  				if( (days+ 31)< 61 )   (*Total_Day) =  days+ 31;     // February
			                  		else  (*Total_Day) =61-1;    
							break;    
			  case MONTH_3:  
			  				if( (days+ 60)< 92 )   (*Total_Day) =  days+ 60;     // March
			                  		else  (*Total_Day) =92-1;    
							break;    
			  
			  case MONTH_4:  
			  				if( (days+ 91)<122 )   (*Total_Day) =  days+ 91;     // April
			                  		else  (*Total_Day) =122-1;   
							break;    
			  
			  case MONTH_5: 
			  				if( (days+121)<153 )   (*Total_Day) =  days+121;    // May
			                  		else  (*Total_Day) =153-1;    
							break;    
			  
			  case MONTH_6:  if( (days+152)<183 )   (*Total_Day) =  days+152;    // June
			                  		else  (*Total_Day) =183-1;    
							break;    
			  
			  case MONTH__7:
			  				if( (days+182)<214 )   (*Total_Day) =  days+182;    // July
			                  		else  (*Total_Day) =214-1;    
							break;    
			  
			  case MONTH_8: 
			  				if( (days+213)<245 )   (*Total_Day) =  days+213;    // August
			                  		else  (*Total_Day) =245-1;    
							break;    
			  
			  case MONTH_9: 
			  				if( (days+244)<275 )   (*Total_Day) =  days+244;    // September
			                  		else  (*Total_Day) =275-1;    
							break;    
			  
			  case MONTH_10:
			  				if( (days+274)<306 )  (*Total_Day) =   days+274;    // October
			                  		else  (*Total_Day) =306-1;    
							break;    
			  
			  case MONTH_11: 
			  				if( (days+305)<336 )  (*Total_Day) =   days+305;    // November
			                  		else  (*Total_Day) =336-1;    
							break;    
			  
			  case MONTH_12: 
			  				if( (days+335)<366 )  (*Total_Day) =   days+335;    // December
			                  		else  (*Total_Day) =366-1;   
							break;    
		}

			     

   }
   else {
		      //1 비 윤년에 따라 달을 계산

		switch(month)
		{					
			  case MONTH_2:
			  				if( (days+ 31)< 60 )   (*Total_Day) =  days+ 31;     // February
			                  		else  (*Total_Day) =60-1;    
							break;    
			  case MONTH_3:  
			  				if( (days+ 59)< 91 )   (*Total_Day) =  days+ 59;     // March
			                  		else  (*Total_Day) =91-1;    
							break;    
			  
			  case MONTH_4:  
			  				if( (days+ 90)<121 )   (*Total_Day) =  days+ 90;     // April
			                  		else  (*Total_Day) =121-1;   
							break;    
			  
			  case MONTH_5: 
			  				if( (days+120)<152 )   (*Total_Day) =  days+120;    // May
			                  		else  (*Total_Day) =152-1;    
							break;    
			  
			  case MONTH_6:  if( (days+151)<182 )   (*Total_Day) =  days+151;    // June
			                  		else  (*Total_Day) =182-1;    
							break;    
			  
			  case MONTH__7:
			  				if( (days+181)<213 )   (*Total_Day) =  days+181;    // July
			                  		else  (*Total_Day) =213-1;    
							break;    
			  
			  case MONTH_8: 
			  				if( (days+212)<244 )   (*Total_Day) =  days+212;    // August
			                  		else  (*Total_Day) =244-1;    
							break;    
			  
			  case MONTH_9: 
			  				if( (days+243)<274 )   (*Total_Day) =  days+243;    // September
			                  		else  (*Total_Day) =274-1;    
							break;    
			  
			  case MONTH_10:
			  				if( (days+273)<305 )  (*Total_Day) =   days+273;    // October
			                  		else  (*Total_Day) =305-1;    
							break;    
			  
			  case MONTH_11: 
			  				if( (days+304)<335 )  (*Total_Day) =   days+304;    // November
			                  		else  (*Total_Day) =335-1;    
							break;    
			  
			  case MONTH_12: 
			  				if( (days+334)<366 )  (*Total_Day) =   days+334;    // December
			                  		else  (*Total_Day) =366-1;   
							break;    
		}

		     
   }
}




/*
*********************************************************************************************************
*                                                              Compute_Week_zeller 
*
* Description:      해당 년, 월, 일 의  요일을 출력 한다 
*
* Arguments  :  
*                		1) U16  year    - 해당 년도 
*                		2) U8    month -  월 
*                		3) U8   day      -  일 
*
* Returns      :   resultWeek- 요일 

*********************************************************************************************************
*/

 U8 Compute_Week_zeller(U16 year, U8 month, U8 day)
{
	idata U8 volatile resultWeek;

	if(month==1)         resultWeek=((U8)((21*((year-1)/100)/4)+(5*((year-1)%100)/4)+(26*(13+1)/10)+(day-1)))%7;  // 전년도 13월로 해서 
	else if(month==2) resultWeek=((U8)((21*((year-1)/100)/4)+(5*((year-1)%100)/4)+(26*(14+1)/10)+(day-1)))%7;  // 전년도 13월로 해서 
	else 			  resultWeek=((U8)((21*(year/100)/4)+(5*(year%100)/4)+(26*(month+1)/10)+(day-1)))%7;

#ifdef WEEK_START_MONDAY
	if(resultWeek == 0) return 6; // Mon : 0, Sun : 6
	return resultWeek - 1;
#else // WEEK_START_SUNDAY
	return resultWeek;
#endif
}


 /*
*********************************************************************************************************
*                                                              Compute_Month 
*
* Description:       month  days  를   RTC 의 total day 카운트 로  계산 한다 
*
* Arguments  :  
* 				1) U8  sWeek- 주 간  
*                		2) U16  year  - 해당 년도 
*                		3) U8 *month - 출력 월 
*                		4) U8 *day    -  출력 일 
*
* Returns      :   NONE

*********************************************************************************************************
*/

#define SATURDAY  6
#define SUNDAY  0	//주단위가 0부터 시작인지 확인



void Search_Weekly_SunDay( POWR_DATA* Search, U8 fGet) //U8  sWeek, U16  year, U8 *month, U8 *day)
{
	idata U8  Month_Count,  Day_Count;
	idata U8  Week;
	idata U8  Week_52;
	idata U16 Year;

      Year=(2000 + Search -> Year); //printf(" \n              dddd=%d" , Year);
	  
	Week_52=0;
	
	for(Month_Count=1; Month_Count<13; Month_Count++){
		Day_Count=0;
		do
		{							
				Day_Count++;

			     	Week= Compute_Week_zeller (Year , Month_Count, Day_Count);

				if(Week==SUNDAY){
					
					Week_52++;

					if(fGet==DAY_){
                                                
						if(Week_52>=Search-> Week){
							
							Search->Month = Month_Count;
							
							Search ->Day=Day_Count;
							
							//printf("\n %dW=%d.%d ", (U16)Week_52, (U16)Month_Count,(U16)Day_Count);
							
							return;
						}
					}
				}
				
				if(fGet==WEEK_){
                                            
					if(Search->Month==Month_Count && Search->Day==Day_Count){
						
					 Search->Week=Week_52;													
						
						//printf("\n %dW=%d.%d ", (U16)Week_52, (U16)Month_Count,(U16)Day_Count);
						
						return;
					}
				}
				
				if(Month_Count== 4|| Month_Count==6|| Month_Count== 9|| Month_Count== 11) {
					
					if(Day_Count>=30)Day_Count=31;  // 4,6,9,11월은  30 일 까지
				}

				else if(Month_Count==2){
					
					if(Leap_Year( Year ) ) {
							if(Day_Count==29)Day_Count=31;  // 윤년은  29 일 까지
					}
					else { 		
							if(Day_Count>=28)Day_Count=31; // 평년은  28 일 까지
					}
				}

		}while(Day_Count !=31);
						
	}
}

void Chk_One_Day(void)
{	
	if(event1.hours==0&&event1.minutes==0&&( event1.seconds<=10))
	{
		
		if(fWeek_Set==0){
			             fWeek_Set=1;
					#ifdef WEEK_START_MONDAY
					event1.Week++; if(event1.Week>Sun)event1.Week=Mon; // thhan 
					#else
					event1.Week++; if(event1.Week>Sat)event1.Week=Sun;
					#endif
		}
	}
	else fWeek_Set=0;	
}


void Put_One_Hour_Chk(U8 One_Hour)
{
	fOne_Hour=One_Hour;
}


U8 Get_One_Hour_Chk(void)
{
	return fOne_Hour;
}


void Chk_One_Hour(void)
{
	static bit fHour_Set=0;
	
	if(event1.minutes==0&&( event1.seconds<=10))
	{		
		if(fHour_Set==0){
			             	fHour_Set=1;
					Put_One_Hour_Chk(FLAG_SET);
		}
	}
	else fHour_Set=0;	
}

///////////////
void Put_One_Minute_Chk(U8 One_Minute)
{
	fOne_Minute=One_Minute;
}


U8 Get_One_Minute_Chk(void)
{
	return fOne_Minute;
}


void Chk_One_Minute(void)
{
	static bit fMinute_Set=0;
	
	if(( event1.seconds<=3))
	{		
		if(fMinute_Set==0){
			             	fMinute_Set=1;
					Put_One_Minute_Chk(FLAG_SET);
		}
	}
	else fMinute_Set=0;	
}

///////////////


void Put_Sec_Chk(U8 Sec)
{
	f_Sec=Sec;
}


U8 Get_Sec_Chk(void)
{
	return f_Sec;
}


void Chk_Sec(U8 Check_Time_Sec)
{
	static bit f_Sec_Set=0;
	
	if( ( event1.seconds % Check_Time_Sec )==0) 
	{		
		if(f_Sec_Set==0){
			             	f_Sec_Set=1;
					Put_Sec_Chk(FLAG_SET);
		}
	}
	else f_Sec_Set=0;	
}


void RTC_ReadTime(void)
{
	RTC_Write (RTC0CN, 0xDD);        // Initiate smaRTClock timer
	while ((RTC_Read (RTC0CN) & 0x01)== 0x01); // Wait for smaRTClock timer capture valid

	// Copy the RTC capture timer to the RTC capture variable
	RTC_Time.U8[b0] = RTC_Read (CAPTURE0);    // LSB
	RTC_Time.U8[b1] = RTC_Read (CAPTURE1);
	RTC_Time.U8[b2] = RTC_Read (CAPTURE2);
	RTC_Time.U8[b3] = RTC_Read (CAPTURE3);    // MSB


	event1.hours = (RTC_Time.U32)/RTC_HOUR;	
					
	(RTC_Time.U32) = (RTC_Time.U32)%RTC_HOUR;
				
	event1.minutes = (RTC_Time.U32)/RTC_MINUTE;
						
	(RTC_Time.U32) = (RTC_Time.U32)%RTC_MINUTE;
					
	event1.seconds = (RTC_Time.U32)/RTC_SECOND;	
					
	(RTC_Time.U32) = (RTC_Time.U32)%RTC_SECOND;
					
	//event1.hundreths = (RTC_Time.U32)/RTC_HUNDRETH;
					
	Compute_Month(&event1.output_month, &event1.output_days,    event1.days, event1.years);

//	printf(" %d year  %d month %d day ", event1.years,  event1.output_month, event1.output_days);

	Chk_One_Day();

	Chk_One_Hour();
	Chk_One_Minute();
	Chk_Sec(6);
				   
}


void RTC_Timer_Stop(void)
{
	RTC_Write(RTC0CN, 0xc5) ;     
	fRTC_Run=RTC_STOP;
}


void RTC_Timer_Run(void)
{
	RTC_Write(RTC0CN, 0xD5) ;     
	
	
	fRTC_Run=RTC_RUN;
															
}


U8 RTC_SetTimer(U32 time)
{
	UU32 value;
	U8 control;

	value.U32 = time;

	SFRPAGE = LEGACY_PAGE;
	control = RTC_Read(RTC0CN);

	if((control&0x80)==0) return 0xFF;                     // error RTC must be enabled

	// write using auto-increment
	RTC0ADR = 0x00;
	RTC0DAT = value.U8[b0];
	RTC0DAT = value.U8[b1];
	RTC0DAT = value.U8[b2];
	RTC0DAT = value.U8[b3];

	RTC_Write(RTC0CN, (control|0x06));  // set using F960 fast mode

	while(((RTC_Read(RTC0CN))&0x02)==0x02);  // wait for set bit to go to zero

	return 0;
}


//-----------------------------------------------------------------------------
// RTC_WriteAlarm ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : 1) U32 alarm - the value to write to <ALARM>
//
// This function writes a value to the <ALRM> registers
//
// Instruction timing of multi-byte write with short bit set
//
//       mov      RTC0ADR, #010h
//       mov      RTC0DAT, #05h
//       nop
//       mov      RTC0DAT, #06h
//       nop
//       mov      RTC0DAT, #07h
//       nop
//       mov      RTC0DAT, #08h
//       nop
//
//-----------------------------------------------------------------------------

void RTC_WriteAlarm (U32 alarm)
{   
	UU32 alarm_value;

	alarm_value.U32 = alarm;   

	// Temporarily disable alarm while updating registers
	RTC0ADR = (0x10 | RTC0CN);
	RTC0DAT = (RTC0CN_Local & ~RTC0AEN);   

	NOP();

	// Write the value to the alarm registers
	RTC0ADR = (0x10 | ALARM0);       
	RTC0DAT = alarm_value.U8[b0];    // write data
	NOP();
	RTC0DAT = alarm_value.U8[b1];    // write data
	NOP();
	RTC0DAT = alarm_value.U8[b2];    // write data
	NOP(); 
	RTC0DAT = alarm_value.U8[b3];    // write data
	NOP(); 

	// Restore alarm state after registers have been written
	RTC0ADR = (0x10 | RTC0CN);
	RTC0DAT = RTC0CN_Local;  
}

U32 RTC_GetCurrentTime(void)
{
	UU32 current_time;   

	RTC_Write( RTC0CN, RTC0CN_Local | RTC0CAP);   // Write '1' to RTC0CAP   
	while((RTC_Read(RTC0CN) & RTC0CAP));          // Wait for RTC0CAP -> 0

	RTC0ADR = (0xD0 | CAPTURE0);
	NOP(); NOP(); NOP();
	current_time.U8[b0] = RTC0DAT;               // Least significant byte
	NOP(); NOP();
	current_time.U8[b1] = RTC0DAT;
	NOP(); NOP();
	current_time.U8[b2] = RTC0DAT;
	NOP(); NOP();
	current_time.U8[b3] = RTC0DAT;               // Most significant byte

	return current_time.U32;

}

void RTC0CN_ClearBits(U8 bits)
{
	RTC0CN_Local &= bits;
	
	RTC_Write( RTC0CN, RTC0CN_Local);
}  

void RTC_SleepTicks(U32 ticks)
{
	UU32 current_time;

	Global_Interrupt_Disable();     // cmlee
	
	//RF_Shot_Down_Pin_Disable();

	RTC0CN_ClearBits(~ALRM);  // Disable Auto Reset

	current_time.U32 = RTC_GetCurrentTime();
	          
	RTC_WriteAlarm(current_time.U32 +WAKE_INTERVAL_TICKS(ticks) );   
	
	EA = 1;

}


#define Rtc_Alarm_Falg	0x04

void RTC_Processing_Year_Day(void)
{
	if(PMU0CF&Rtc_Alarm_Falg)
	{
	//	printf("\n PMU0CF"); 
		PMU0CF=0x20;

		if ((event1.days == 365) && (Leap_Year(event1.years)))      //  cmlee it is strange, &&(cmlee)  insted of &(original)
		{
		      event1.days++;       // Check for leap year, increment days
		}
		else if (event1.days >= 365)
		{
		      event1.days = 1;     // If non-leap year, reset days,
		      event1.years ++;     // increment years
		}
		else
		{
		      event1.days ++;
		}		
	
	}
}




/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/*

public static void main(String[] ar) throws IOException { 

  BufferedReader in = new BufferedReader( 

  new InputStreamReader(System.in)); 

  int year = 0, month = 0; 

  int start = 0, end = 0; 

  boolean bool = false; //윤년 여부 ture : 윤년 

  int base = 2006; // 2006년 1월 1일은 일요일 --> 기준 

  int pos = 0; 

  

  do { 

   System.out.print("1. 연도를 입력하세요(예 : 2004) => "); 

   year = Integer.parseInt(in.readLine()); 

  }while (year < 0 || year > 9999); 

  System.out.println(); 

  do { 

   System.out.print("2. 월을 입력하세요(예 : 6) => "); 

    month = Integer.parseInt(in.readLine()); 

  }while(month < 1 || month > 12); 

  

  if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)  bool = true;  

  

  switch(month) { 

  case 1: case 3: case 5: case 7: case 8: 

  case 10: case 12: 
  				end = 31; 
				break; 

  case 4: case 6: case 9: case 11: 
  				end = 30; 
				break; 

  case 2: 
  		if(bool) end = 29; 
		else end = 28; 

  } 

  

	if(year < base) { 

		start = base - year; 

		for(int i = year; i < base; ++i) 

		if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0)  start++;   

		start = 7 - start % 7; 

		if(start == 7) start = 0; 

	} 

	else { 

		start = year - base; 

		for(int i = base; i < year; ++i) 

		if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0)  start++;   

		start %= 7; 

	} 

  for(int i = 1; i < month; ++i) { 

			switch(i) { 

			case 1: case 3: case 5: case 7: 
			case 8: case 10: case 12: 
							start += 31; 
							break; 

			case 4: case 6: case 9: case 11:
							start += 30; 
							break; 

			case 2: 
						if(bool) start += 29; 
						else start += 28; 

			} 

    } 

  start %= 7; 

  

  System.out.println(); 

  System.out.print("================= < "); 

  if(year < 10) System.out.print("000"); 

  else if(year < 100) System.out.print("00"); 

  else if(year < 1000) System.out.print("0"); 

  System.out.print(year + "년 "); 

  if(month < 10) System.out.print("0"); 

  System.out.println(month + "월 > ================="); 

  System.out.println("일\t월\t화\t수\t목\t금\t토"); 

for(int i = 0; i < start; ++i, ++pos) System.out.print("\t"); 

  for(int i = 1; i <= end; ++i) { 

  if(i < 10) System.out.print(' '); 

   System.out.print(i); 

   ++pos; 

   if(pos % 7 == 0) System.out.println(); 

   else System.out.print("\t"); 

  } 

  if(pos % 7 != 0) System.out.println(); 

  System.out.println( 

"=================================================="); 

} 

} 

  

*/
