227 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include "kwrap/util.h"
 | |
| #include "GxTime.h"
 | |
| #include "DxPower.h"
 | |
| #include "PowerDef.h"
 | |
| #include "DxApi.h"
 | |
| #include "Dx.h"
 | |
| #include "DxType.h"
 | |
| #include <time.h>
 | |
| 
 | |
| #define THIS_DBGLVL         2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| #define __MODULE__          GxTm
 | |
| #define __DBGLVL__          THIS_DBGLVL
 | |
| //#define __DBGFLT__          "*" //*=All, [mark]=CustomClass
 | |
| #define __DBGFLT__          "[charge]" //*=All, [mark]=CustomClass
 | |
| #include "kwrap/debug.h"
 | |
| 
 | |
| extern DX_HANDLE power_obj;
 | |
| 
 | |
| //-----------------------------------------------------------------------------
 | |
| // Date-Time util
 | |
| //-----------------------------------------------------------------------------
 | |
| 
 | |
| static struct tm g_ctv_zero = {0};
 | |
| 
 | |
| void GxTime_GetTime(struct tm* p_ctv)
 | |
| {
 | |
| 	if (!p_ctv) return;
 | |
| 	if (!power_obj) {
 | |
| 		*(p_ctv) = g_ctv_zero;
 | |
| 		return;
 | |
| 	}
 | |
| 	
 | |
| 	Dx_Control(power_obj, DRVPWR_CTRL_CURRENT_TIME, 1, (UINT32)p_ctv);//1=read
 | |
| }
 | |
| 
 | |
| void GxTime_SetTime(struct tm ctv)
 | |
| {
 | |
| 	if (!power_obj) {
 | |
| 		return;
 | |
| 	}
 | |
| 	Dx_Control(power_obj, DRVPWR_CTRL_CURRENT_TIME, 0, (UINT32)&ctv); //0=write
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|     RTC Date
 | |
| */
 | |
| typedef union {
 | |
| 	// Format conformed to RTC register
 | |
| 	_PACKED_BEGIN struct {
 | |
| 		UBITFIELD   day: 5;     ///< Day
 | |
| 		UBITFIELD   month: 4;   ///< Month
 | |
| 		UBITFIELD   year: 12;   ///< Year
 | |
| 	} _PACKED_END s;
 | |
| 	UINT32      value;          ///< Date value all together Y:M:D
 | |
| } RTC_DATE, *PRTC_DATE;
 | |
| 
 | |
| static const UINT8      uiRTCDayOfMonth[2][12] = {
 | |
| 	// Not leap year
 | |
| 	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
 | |
| 	// Leap year
 | |
| 	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
 | |
| };
 | |
| 
 | |
| static const UINT32     uiRTCDayOfYear[2] = {365, 366};
 | |
| 
 | |
| // Base date
 | |
| static RTC_DATE         RTCBaseDate = {1, 1, 1900};
 | |
| 
 | |
| /**
 | |
|     Check if leap year
 | |
| 
 | |
|     This function is used to check if the specified year is a leap year.
 | |
| 
 | |
|     @param[in] uiYear   The year you want to check (0~0xFFFFFFFF)
 | |
|     @return
 | |
|         - @b TRUE   : Is a leap year
 | |
|         - @b FALSE  : Isn't a leap year
 | |
| */
 | |
| BOOL GxTime_IsLeapYear(UINT32 uiYear)
 | |
| {
 | |
| 	// New algorithm
 | |
| 	return (BOOL)((((uiYear % 4) == 0) && (((uiYear % 100) != 0) || ((uiYear % 400) == 0))));
 | |
| }
 | |
| 
 | |
| /**
 | |
|     Convert date to number of days to base date.
 | |
| 
 | |
|     Convert date to number of days to base date.
 | |
| 
 | |
|     @param[in] rtcDate      Absolute date
 | |
|     @return Days from base date
 | |
| */
 | |
| ///////// -- Chris -- Buggy if base date is not yyyy/01/01
 | |
| UINT32 GxTime_Time2Days(struct tm ctv)
 | |
| {
 | |
| 	UINT32 uiDays;
 | |
| 	UINT32 i;
 | |
| 	RTC_DATE rtcDate;
 | |
| 
 | |
| 	rtcDate.s.day = ctv.tm_mday;     /* day of the month - [1,31]         */
 | |
| 	rtcDate.s.month = ctv.tm_mon;    /* months since January - [0,11]     */
 | |
| 	rtcDate.s.year = ctv.tm_year;    /* years since 2000                  */
 | |
| 	uiDays = 0;
 | |
| 
 | |
| 	// Year
 | |
| 	for (i = RTCBaseDate.s.year; i < rtcDate.s.year; i++) {
 | |
| 		uiDays += uiRTCDayOfYear[GxTime_IsLeapYear(i)];
 | |
| 	}
 | |
| 
 | |
| 	// Month
 | |
| 	for (i = RTCBaseDate.s.month; i < rtcDate.s.month; i++) {
 | |
| 		uiDays += uiRTCDayOfMonth[GxTime_IsLeapYear(rtcDate.s.year)][i - 1];
 | |
| 	}
 | |
| 
 | |
| 	uiDays += rtcDate.s.day - RTCBaseDate.s.day;
 | |
| 
 | |
| 	return uiDays;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|     Convert days to date from base date.
 | |
| 
 | |
|     This function is used to convert days to date from base date.
 | |
| 
 | |
|     @param[in] uiDays   Number of days from base date
 | |
|     @return Converted absolute date
 | |
| */
 | |
| ///////// -- Chris -- Buggy if base date is not yyyy/01/01
 | |
| struct tm GxTime_Days2Time(UINT32 uiDays)
 | |
| {
 | |
| 	struct tm ctv = {0};
 | |
| 
 | |
| 	RTC_DATE Date;
 | |
| 	UINT32   uiYear, uiMonth;
 | |
| 
 | |
| 	for (uiYear = RTCBaseDate.s.year; uiDays >= uiRTCDayOfYear[GxTime_IsLeapYear(uiYear)]; uiYear++) {
 | |
| 		uiDays -= uiRTCDayOfYear[GxTime_IsLeapYear(uiYear)];
 | |
| 	}
 | |
| 
 | |
| 	for (uiMonth = RTCBaseDate.s.month; uiDays >= uiRTCDayOfMonth[GxTime_IsLeapYear(uiYear)][uiMonth - 1]; uiMonth++) {
 | |
| 		uiDays -= uiRTCDayOfMonth[GxTime_IsLeapYear(uiYear)][uiMonth - 1];
 | |
| 	}
 | |
| 
 | |
| 	Date.value      = 0;
 | |
| 	Date.s.day      = RTCBaseDate.s.day + uiDays;
 | |
| 	Date.s.month    = uiMonth;
 | |
| 	Date.s.year     = uiYear;
 | |
| 
 | |
| 	ctv.tm_mday = Date.s.day;     /* day of the month - [1,31]         */
 | |
| 	ctv.tm_mon = Date.s.month;    /* months since January - [0,11]     */
 | |
| 	ctv.tm_year = Date.s.year;    /* years since 2000                  */
 | |
| 	ctv.tm_hour = 0;
 | |
| 	ctv.tm_min = 0;
 | |
| 	ctv.tm_sec = 0;
 | |
| 	// NOT support the following function..
 | |
| 	ctv.tm_isdst = 0;
 | |
| 	ctv.tm_yday = 0;
 | |
| 	ctv.tm_wday = 0;
 | |
| 
 | |
| 	return ctv;
 | |
| }
 | |
| 
 | |
| INT32 GxTime_CalcMonthDays(INT32 year, INT32 month)
 | |
| {
 | |
| 	INT32 day = 31;
 | |
| 	INT32 year_ext = 0;
 | |
| 	if (GxTime_IsLeapYear(year) == TRUE) {
 | |
| 		year_ext = 1;
 | |
| 	}
 | |
| 	if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
 | |
| 		day = 30;
 | |
| 	}
 | |
| 	if (month == 2) {
 | |
| 		day = 28 + year_ext;
 | |
| 	}
 | |
| 	return day;
 | |
| }
 | |
| 
 | |
| struct tm GxTime_AddTime(struct tm ctv, struct tm diff)
 | |
| {
 | |
| 	INT32 maxday;
 | |
| 
 | |
| 	ctv.tm_sec += diff.tm_sec;   /* seconds after the minute - [0,59] */
 | |
| 	ctv.tm_min += diff.tm_min;   /* minutes after the hour - [0,59]   */
 | |
| 	ctv.tm_hour += diff.tm_hour;    /* hours since midnight - [0,23]     */
 | |
| 	ctv.tm_mday += diff.tm_mday;     /* day of the month - [1,31]         */
 | |
| 	ctv.tm_mon += diff.tm_mon;    /* months since January - [0,11]     */
 | |
| 	ctv.tm_year += diff.tm_year;    /* years since 2000                  */
 | |
| 
 | |
| 	if (ctv.tm_sec >= 60) {
 | |
| 		ctv.tm_min += ctv.tm_sec / 60;
 | |
| 		ctv.tm_sec = ctv.tm_sec % 60;
 | |
| 	}
 | |
| 	if (ctv.tm_min >= 60) {
 | |
| 		ctv.tm_hour += ctv.tm_min / 60;
 | |
| 		ctv.tm_min = ctv.tm_min % 60;
 | |
| 	}
 | |
| 	if (ctv.tm_hour >= 24) {
 | |
| 		ctv.tm_mday += ctv.tm_hour / 24;
 | |
| 		ctv.tm_hour = ctv.tm_hour % 24;
 | |
| 	}
 | |
| 	maxday = GxTime_CalcMonthDays(ctv.tm_year, ctv.tm_mon);
 | |
| 	while (ctv.tm_mday > maxday) {
 | |
| 		ctv.tm_mday -= maxday;
 | |
| 		ctv.tm_mon ++;
 | |
| 		//month range = [1,12]
 | |
| 		if (ctv.tm_mon > 12) {
 | |
| 			ctv.tm_year += (ctv.tm_mon - 1) / 12;
 | |
| 			ctv.tm_mon = ((ctv.tm_mon - 1) % 12) + 1;
 | |
| 		}
 | |
| 		maxday = GxTime_CalcMonthDays(ctv.tm_year, ctv.tm_mon);
 | |
| 	}
 | |
| 	//month range = [1,12]
 | |
| 	if (ctv.tm_mon > 12) {
 | |
| 		ctv.tm_year += (ctv.tm_mon - 1) / 12;
 | |
| 		ctv.tm_mon = ((ctv.tm_mon - 1) % 12) + 1;
 | |
| 	}
 | |
| 	return ctv;
 | |
| }
 | |
| 
 | |
| //@}
 | 
