rtc_jz4740.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 519 行

C
519
字号
/********************** BEGIN LICENSE BLOCK ************************************ * * JZ4740  mobile_tv  Project  V1.0.0 * INGENIC CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Copyright (c) Ingenic Semiconductor Co. Ltd 2005. All rights reserved. *  * This file, and the files included with this file, is distributed and made  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.  *  * http://www.ingenic.cn  * ********************** END LICENSE BLOCK ************************************** * *  Author:  <dsqiu@ingenic.cn>  <jgao@ingenic.cn>  * *  Create:   2008-06-26, by dsqiu *             *  Maintain: 2008-06-26, by jgao *             * ******************************************************************************* */  #include <jz4740.h>#include <rtc.h>#ifdef USE_MIDWARE#include "ucos_ii.h"#include "midware.h"#endif#define RTC_ALM_READ 0#define RTC_ALM_SET 1#define RTC_RD_TIME 2#define RTC_SET_TIME 3#define RTC_EPOCH_READ 4#define RTC_EPOCH_SET 5  #define EINVAL 1#define EACCES 2#define EFAULT 3//extern spinlock_t rtc_lock;static __uint64_t st_time_atom;//get time base from RTC(unit second) static __uint64_t st_time_atom_base;//get time base from RTC(unit second) static ST_datetime st_EU_time;static ST_datetime st_EU_base={1900,1,0,1,0,0,0};//2008.02.13static ST_datetime st_EU_start={1921,2,0,8,0,0,0};//2021.02.8static ST_datetime st_EU_sample={2008,3,0,20,0,0,0};//2008.03.20static unsigned int u32_RTC_time_l;static unsigned int u32_RTC_time_h;const unsigned int sum_monthday[13] = {	0,	31,	31+28,	31+28+31,	31+28+31+30,	31+28+31+30+31,	31+28+31+30+31+30,	31+28+31+30+31+30+31,	31+28+31+30+31+30+31+31,	31+28+31+30+31+30+31+31+30,	31+28+31+30+31+30+31+31+30+31,	31+28+31+30+31+30+31+31+30+31+30,	365}; //the total day of the last monthvoid rtc_alarm_stop(void);const unsigned char monthday[12] = {31,28,31,30,31,30,31,31,30,31,30,31};//1 2  3  4  5  6  7  8  9  10 11 12//=====================================================================//function script get the month from yeardays//input yeardays y(years)//output return ST_monthday(month and day)//create date 2008.03.13//=====================================================================static void rtc_get_month_from_yeardays(unsigned int yeardays,unsigned short int y,ST_monthday *st_md){	unsigned char m_ret=0,m_f,m_i;	unsigned int tmpd;//ST_monthday st_md; //u8_month;//u8_day;	st_md->u8_month=1;	st_md->u8_day=1;	m_f=rtc_is_double_year(y);	for(m_i=1;m_i<13;m_i++)	{		tmpd=sum_monthday[m_i];		if(m_i>1&&m_f) tmpd+=1;		if(yeardays<=tmpd) 		{			st_md->u8_month=m_i;			tmpd=sum_monthday[m_i-1];  			if(m_i>2&&m_f) tmpd+=1;			st_md->u8_day=yeardays-tmpd;			break;		}  	}//for	if(13==m_i)	{		st_md->u8_month=12;		tmpd=sum_monthday[12];  		if(m_f) tmpd+=1;		st_md->u8_day=yeardays-tmpd;	}}//=====================================================================//function script get atom time from RTC//input//output return a format time//create date 2008.03.13//=====================================================================void atom_time_to_ymd(__uint64_t atom_time ,ST_datetime *st_time){	ST_datetime tmpt;	unsigned char tmp_i;  //tmpw,	__uint64_t tmpday,tmphour,tmpminute,tmpd,tmpdd,tmpy;	unsigned short int tmpdt[4];	ST_monthday tmpmdd;//tmpw=rtc_get_week_from_date(st_EU_base.u16_year,st_EU_base.u8_month,st_EU_base.u8_day);	tmpday=atom_time/86400;//24*60*60	tmphour=atom_time%86400;	tmpminute=tmphour%3600;//60*60	tmpt.u8_hour=tmphour/3600;	tmpt.u8_minute=tmpminute/60;	tmpt.u8_second=tmpminute%(60);	tmpd=tmpday/1461; //n 4 year //365*4+1	tmpdd=tmpday%1461;   //double year counter	tmpy=st_EU_base.u16_year+tmpd*4;	if(0==tmpdd) 	{		tmpy-=1;tmpt.u8_month=12;tmpt.u8_day=31;	}	else	{		for(tmp_i=0;tmp_i<4;tmp_i++)		{			tmpdt[tmp_i]=365*(tmp_i+1);			if(rtc_is_double_year(tmpy+tmp_i)) {tmpdt[tmp_i]+=1;break;}		}		for(;tmp_i<4;tmp_i++) tmpdt[tmp_i]=365*(tmp_i+1);		for(tmp_i=0;tmp_i<4;tmp_i++)		{			if(tmpdd<=tmpdt[tmp_i]) {				tmpy+=tmp_i;				if(tmp_i) tmpdd-=tmpdt[tmp_i-1];				break;			}		}		if(4==tmp_i)		{			tmpy+=3;tmpdd=tmpdt[3]-tmpdt[2];		}		rtc_get_month_from_yeardays(tmpdd,tmpy,&tmpmdd);		tmpt.u8_month=tmpmdd.u8_month;		if(tmpmdd.u8_day)			tmpt.u8_day=tmpmdd.u8_day;		else 			tmpt.u8_day=1;	}	tmpt.u16_year=tmpy;	tmpt.u8_week=rtc_get_week_from_date(tmpt.u16_year,tmpt.u8_month,tmpt.u8_day);	st_time->u16_year=tmpt.u16_year;	st_time->u8_month=tmpt.u8_month;	st_time->u8_week=tmpt.u8_week;	st_time->u8_day=tmpt.u8_day;	st_time->u8_hour=tmpt.u8_hour;	st_time->u8_minute=tmpt.u8_minute;	st_time->u8_second=tmpt.u8_second;}//=====================================================================//function script current time convert to ABS atom time//input current time//output return a atom time//create date 2008.03.13//=====================================================================__uint64_t ymd_time_to_atom(ST_datetime *currentime){	__uint64_t tempam_ret=0;	unsigned char f_d,tmp_i;	unsigned short int tmpdt[4],temp_p;	unsigned int tempam;	tempam=currentime->u16_year;	f_d=rtc_is_double_year(tempam);	if(tempam<st_EU_base.u16_year) 		return 0;	tempam-=st_EU_base.u16_year;//if(tempam<0) return 0;	temp_p=tempam%4;	tempam=(tempam/4);	tempam_ret=(unsigned int)tempam*1461; //365*4+1 day	tempam=tempam*4+st_EU_base.u16_year;	tmp_i=0;	tmpdt[tmp_i]=0;	for(;tmp_i<4;tmp_i++)	{		tmpdt[tmp_i]=365*(tmp_i);		if(rtc_is_double_year(tempam+tmp_i)) 		{			tmpdt[tmp_i]+=1;break;		}	}	for(;tmp_i<4;tmp_i++) 		tmpdt[tmp_i]=365*(tmp_i);	tempam_ret+=(__uint64_t)tmpdt[temp_p]; //	if(f_d &&currentime->u8_month>2)	{		tempam_ret+=(__uint64_t)(sum_monthday[currentime->u8_month-1]+1);		tempam_ret+=(__uint64_t)currentime->u8_day;	}	else 	{		tempam_ret+=(__uint64_t)sum_monthday[currentime->u8_month-1];		tempam_ret+=(__uint64_t)currentime->u8_day;	}	tempam_ret*=(__uint64_t)86400;//24*60*60	tempam_ret+=(__uint64_t)(currentime->u8_hour*3600) ;//60*60	tempam_ret+=(__uint64_t)(currentime->u8_minute*60) ;//60	tempam_ret+=(__uint64_t)(currentime->u8_second) ;//	return tempam_ret;}//=====================================================================//function script double year//input year//output return yes or no//create date 2008.03.12//=====================================================================unsigned char rtc_is_double_year(unsigned short int year){	unsigned char is_ret=0;	if(0==(year%400)||((year%100)!=0&&0==(year%4)))		is_ret=1;	return is_ret;}//=====================================================================//function script get week from date//input year month day//output return week//create date 2008.03.12//=====================================================================unsigned char rtc_get_week_from_date(unsigned short int year,unsigned char month,unsigned char day){	unsigned char w=1; //because 1901-01-01 is monday	unsigned short int y,d;	y=year-1+(year-1)/4-(year-1)/100+(year-1)/400;	d=day+sum_monthday[month-1];	if(month>2&&rtc_is_double_year(year))	{		d+=1;	}	y+=d;	w=y%7;	return w;}//=====================================================================//function script Get urtime//input//output current urtime//create date 2008.03.15//=====================================================================void rtc_get_cur_urtime(ST_datetime *st_sd){	unsigned long flags;	ST_datetime *tmp_st=&st_EU_time;	flags = spin_lock_irqsave();	__uint64_t tempam_cur=__rtc_get_second();	tempam_cur = tempam_cur +st_time_atom_base;	st_time_atom=tempam_cur;	atom_time_to_ymd(tempam_cur,st_sd);	memcpy(tmp_st,st_sd,sizeof(ST_datetime));//REG_RTC_RSAR = lval;	spin_unlock_irqrestore(flags);//return tmp_st;}//=====================================================================//function script Get abs time//input//output current urtime//create date 2008.03.15//=====================================================================__uint64_t rtc_get_atom_time(void){	unsigned long flags;	flags = spin_lock_irqsave();	__uint64_t tempam_cur =__rtc_get_second();	tempam_cur+=st_time_atom_base;	st_time_atom=tempam_cur;	spin_unlock_irqrestore(flags);	return tempam_cur;}//=====================================================================//function script Get urtime//input//output current urtime//create date 2008.03.15//=====================================================================void rtc_set_rtc_datetime(ST_datetime * st_time){//st_time_atom_base	unsigned long flags;	flags = spin_lock_irqsave();	__uint64_t tempam_cur=ymd_time_to_atom(st_time);	st_time_atom=tempam_cur;	__rtc_set_second(tempam_cur-st_time_atom_base);	spin_unlock_irqrestore(flags);}//=====================================================================//function script Set RTC from abs time//input//output current urtime//create date 2008.03.19//=====================================================================void rtc_set_rtc_abs(__uint64_t u64_time){//st_time_atom_base	unsigned long flags;	flags = spin_lock_irqsave();	st_time_atom=u64_time;	__rtc_set_second(u64_time-st_time_atom_base);	spin_unlock_irqrestore(flags);}//=====================================================================//function script Get base urtime//input//output current urtime//create date 2008.03.16//=====================================================================static ST_datetime *rtc_get_base_urtime(void){	return &st_EU_base;}//=====================================================================//function script Get base urtime//input//output current urtime//create date 2008.03.16//=====================================================================static ST_datetime *get_base_start_urtime(void){	return &st_EU_start;}#ifdef USE_MIDWARE//#if 0volatile static MIDSRC rtcsrc;static u32 rtcid;static void GetRequest(MIDSRCDTA *dat){//	printf("Up layer get :%d \n",res.Val);}static void Response(MIDSRCDTA *dat){	printf("dat->Val == %d\n",dat->Val);	if (dat->Val == 1)	{		cli();		jz_pm_hibernate();	}}static void info_low_power(){	printf("Send info low power!\n");	rtcsrc.Src = SRC_POWER_LOW;	rtcsrc.Event =  EVENT_BAT_LOW;	OSQPost(rtcsrc.CurEvent1 , (void *)&rtcid);	OSSemPost(rtcsrc.CurEvent);}static void info_set_alarm(){	printf("Send info set rtc alarm!\n");	rtcsrc.Src = SRC_SET_ALM;	rtcsrc.Event =  EVENT_SET_ALM;	OSQPost(rtcsrc.CurEvent1 , (void *)&rtcid);	OSSemPost(rtcsrc.CurEvent);}void rtc_power_check_init(){ 	rtcsrc.GetRequest = GetRequest;	rtcsrc.Response = Response;	rtcsrc.Name = "RTC";	printf("Register Midware SRC RTC! \n");	RegisterMidSrc((PMIDSRC)&rtcsrc);	rtcid = rtcsrc.ID;	printf("rtc ID %d \n",rtcsrc.ID);}#endifvoid do_bat_low(void){	printf("Now bat capacity too low, power off at once! \n");#ifdef USE_MIDWARE	info_low_power();#endif//	sys_shutdown(2);//	ShutLcd(0);}static void rtc_alarm_handler(void){	info_set_alarm();	}static void jz_rtc_interrupt(unsigned int arg){	REG_RTC_HCR = 0x0;	while(!__rtc_write_ready());	if ( (REG_RTC_RCR >> RTC_RCR_AF_BIT) & 0x1 ) 	/* rtc alarm interrupt */	{		__rtc_clear_alarm_flag();		printf("RTC alarm interrupt clean!\n");		rtc_alarm_handler();	}}void rtc_alarm_bat_start(){	printf("Rtc alarm for auto power off start! \n");	__rtc_clear_alarm_flag();	request_irq(IRQ_RTC, jz_rtc_interrupt, 0);	#if 0	rtc_alarm_handler();#endif}void rtc_alarm_stop(){	__rtc_clear_alarm_flag();	__rtc_disable_alarm_irq();	__rtc_disable_alarm();	printf("Rtc alarm for auto power off stop! \n");}//=====================================================================//function script RTC initial//input//output current urtime//create date 2008.03.19//=====================================================================void jz_rtc_init(void){	unsigned int tmpx=__rtc_get_scratch_pattern();	st_time_atom=ymd_time_to_atom(&st_EU_start); //set base time	st_time_atom_base=st_time_atom;//unsigned int temxs=0;	if((tmpx != 0x12345678) || (__rtc_get_nc1Hz_val() != 0x7fff)) // || (0 == __rtc_status_hib_reset_occur()))//&&0==(REG_CPM_RSR&CPM_RSR_HR) tmpx!= 0x12345678&&	{		printf("tmpx=%x\n",tmpx);		u32_RTC_time_l=0;		u32_RTC_time_h=0; 		atom_time_to_ymd(st_time_atom,&st_EU_time);  //get base time info		__rtc_unlock_RGR();		__rtc_set_nc1Hz_val(0x7fff);		__rtc_set_adjc_val(0);		__rtc_lock_RGR();				__rtc_set_scratch_pattern(0x12345678);		udelay(90);		__rtc_set_second(0);		rtc_set_rtc_abs(st_time_atom_base);		rtc_set_rtc_datetime(&st_EU_sample);		__rtc_enabled();//   temxs=__rtc_get_second();//   printf("REG_RTC_RSR=%x\n",temxs);	}	else	{		rtc_get_cur_urtime(&st_EU_time);	}			//__rtc_clear_hib_stat_all();/*ST_datetime st_tmpdt;//rtc_set_rtc_datetime(&st_EU_sample);st_tmpdt.u16_year=st_EU_sample.u16_year;st_tmpdt.u8_month=st_EU_sample.u8_month;st_tmpdt.u8_day=st_EU_sample.u8_day;st_tmpdt.u8_week=rtc_get_week_from_date(st_EU_sample.u16_year,st_EU_sample.u8_month,st_EU_sample.u8_day);st_tmpdt.u8_hour=st_EU_sample.u8_hour;st_tmpdt.u8_minute=st_EU_sample.u8_minute;st_tmpdt.u8_second=st_EU_sample.u8_second;rtc_set_rtc_datetime(&st_tmpdt);*/	rtc_alarm_bat_start();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?