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;
|
|
}
|
|
|
|
//@}
|