//===========================================================================
//文件名称：task_RTC.c
//功能概要：定义task_rtc任务,接收PC控制命令校准RTC时间,并回发相对时间(相对于
//2014年5月1日0时0分0秒0毫秒所过去的毫秒数)
//版权所有：苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)
//版本更新：2014-7-12  V2.0
//===========================================================================
#include "app_inc.h"

static void install_interrupt(void);

void task_RTC(uint_32 initial_data)
{	
    //选择参考时间的原因,减小发送的相对时间的秒数的数据大小
    DATE_STRUCT   time_rtc;    //存放设置的公共(另一方为PC)参考时间(时间格式为日期格式)
    TIME_STRUCT   time_mqx;    //存放设置的公共参考时间(时间格式为时间格式，由秒、毫秒两部分组成)
    TIME_STRUCT   mod_time_mqx;//存放参考时间与偏差时间之和(时间格式为时间格式)
    uint_32       lenth=0,i=0; //length用于存放帧长，i用于循环遍历
    TIME_STRUCT   PC_offset;   //存放PC端发来的偏差时间(偏差时间=获取的Now时间-参考时间)
    
    DATE_STRUCT   output_rtc;  //时间输出(时间格式为日期格式),存放获取的RTC时间
    TIME_STRUCT   output_mqx;  //时间输出(时间格式为时间格式),存放 
        
    //使能RTC模块的时钟门,成功后初始化RTC模块，并用RTC时间同步MQX时间
    if (MQX_OK == _bsp_rtc_io_init())   {       
        _rtc_init (RTC_INIT_FLAG_ENABLE);
        _rtc_sync_with_mqx (TRUE);    
    }
    
    //初始化公共参考时间
    time_rtc.YEAR     = 2014;
    time_rtc.MONTH    = 05;
    time_rtc.DAY      = 1;
    time_rtc.HOUR     = 0;
    time_rtc.MINUTE   = 0;
    time_rtc.SECOND   = 0;
    time_rtc.MILLISEC = 0;
    
    //将时间转化为以秒为单位
    _time_from_date (&time_rtc, &time_mqx);  
 
    //注册中断服务历程
    install_interrupt();    
 
    //无限等待UART的事件位置位
    _lwevent_wait_for(&lwevent_group, Event_RTC, FALSE, NULL); 
  	while(TRUE)
  	{
  		//1.延时
  		_time_delay(500);       
  		
		//2.根据帧头、帧尾判断RTC帧的正确性
		lenth=gRTC_Buff[1];                            
		if((gRTC_Buff[0]==FrameHead)&&(gRTC_Buff[lenth-1]==FrameTail))
		{
			//(1)时间校准
			if(gRTC_Buff[3]==0x01) 
			{
				//从PC端获取时间偏差，单位是秒
				PC_offset.SECONDS=(gRTC_Buff[4]<<24)+(gRTC_Buff[5]<<16)+
						(gRTC_Buff[6]<<8)+gRTC_Buff[7];
				PC_offset.MILLISECONDS=0;
				mod_time_mqx.SECONDS=time_mqx.SECONDS+PC_offset.SECONDS; 
				mod_time_mqx.MILLISECONDS=time_mqx.MILLISECONDS+
						                          PC_offset.MILLISECONDS; 
				
				//设置MQX时间
				_time_set( &mod_time_mqx);
				
				//同步,用MQX时间同步RTC时间
				_rtc_sync_with_mqx(FALSE);
			}
			//(2)更新后的时间数据回发给PC
			else if(gRTC_Buff[3]==0x02)
			{
				//换算当前时间
				_rtc_get_time_mqxd (&output_rtc);
				_time_from_date (&output_rtc, &output_mqx);
				output_mqx.SECONDS-=time_mqx.SECONDS;
				gRTC_Buff[4]=output_mqx.SECONDS>>24;
				gRTC_Buff[5]=output_mqx.SECONDS>>16;
				gRTC_Buff[6]=output_mqx.SECONDS>>8;
				gRTC_Buff[7]=output_mqx.SECONDS;
					
				//将待回发给PC的数据放入到轻量级消息队列send_queue中
				DISABLE_INTERRUPTS;			
				_lwmsgq_send((pointer)send_queue, gRTC_Buff, 
						                          LWMSGQ_SEND_BLOCK_ON_FULL);
				ENABLE_INTERRUPTS;			
			}		
		}
		else 
		{
			_lwevent_clear(&lwevent_group, Event_RTC); 
		}		
  	} 		
}

//===========================================================================
//函数名称：install_interrupt
//功能概要：注册RTC中断
//函数参数：无
//函数返回：
//===========================================================================
static void install_interrupt(void)
{
    _rtc_int_install (RTC_ISR);   

    //清空中断请求
    _rtc_clear_requests (RTC_RTCISR_SW | RTC_RTCISR_ALM);
    //使能SW和ALARM中断
    _rtc_int_enable (TRUE, RTC_RTCIENR_SW | RTC_RTCIENR_ALM);
}



