581 lines
13 KiB
C
581 lines
13 KiB
C
/**
|
|
******************************************************************************
|
|
* @file brtc.c
|
|
* @author AMG Energy Solution Team
|
|
* @version V1.0.0
|
|
* @date 07-Feb-2022
|
|
* @brief This file provides all the code of the board realtime clock.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
|
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
|
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
|
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
|
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
|
*
|
|
* <h2><center>© COPYRIGHT 2022 AMG</center></h2>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/** @addtogroup mBMS2
|
|
* @{
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "brtc.h"
|
|
#include "includes.h"
|
|
#include "rtc_io.h"
|
|
#include "date_calc.h"
|
|
#include "app_ver.h"
|
|
#include "asutil.h"
|
|
#include "led.h"
|
|
#include "device_param.h"
|
|
#include "dflash_sf1.h"
|
|
#include "dflash_chg_ctrl.h"
|
|
#include "vi.h"
|
|
#include "io.h"
|
|
#include "calc_soc.h"
|
|
#include "alarm.h"
|
|
#include "afe_comm.h"
|
|
#include "task_manager.h"
|
|
#include "iwdg.h"
|
|
#include "delay.h"
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define FIRST_DATA 0x32F2
|
|
|
|
#define RTC_CH_END 7
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
uint8_t rtc_ch = 0;
|
|
|
|
uint32_t LocalTime; /* this variable is used to create a time reference incremented by 10ms */
|
|
|
|
uint32_t UnixTimeStamp, BakUnixTimeStamp, disUnixTimeStamp;
|
|
uint32_t BuildTimeStamp;
|
|
DateAndTime aDateAndTime;
|
|
uint32_t OptimeStamp, disOptimeStamp;
|
|
|
|
_TTIME DEVICE_TIME;
|
|
uint8_t bak_sec;
|
|
|
|
OS_TMR RTC_TMR;
|
|
|
|
uint8_t set_time_flag = 0;
|
|
uint8_t last_reboot_reason = 0;
|
|
|
|
uint32_t WarmingUp = WARMING_UP_TIME;
|
|
|
|
const uint8_t samurai[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
|
|
|
extern uint16_t aMonth[13];
|
|
extern uint16_t bMonth[13];
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
uint8_t ReadResetFlag(void);
|
|
|
|
uint32_t GetRealTimeStamp(void);
|
|
void Get_Time(void);
|
|
void RTC_TimeShow(void);
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
void InitTimer(void)
|
|
{
|
|
OS_ERR err;
|
|
|
|
#ifdef CONSOLE_DEBUG
|
|
BuildTimeStamp = GetBuildTimeStamp();
|
|
#endif // #ifdef CONSOLE_DEBUG
|
|
|
|
OSTmrCreate (&RTC_TMR, // Timer Pointer
|
|
"RTC Timer", // Timer Name
|
|
1, // Delay
|
|
1, // Period
|
|
OS_OPT_TMR_PERIODIC, // opt
|
|
(OS_TMR_CALLBACK_PTR)&Time_Update, // Callback function
|
|
NULL, // Callback arg
|
|
&err);
|
|
OSTmrStart (&RTC_TMR,
|
|
&err);
|
|
|
|
last_reboot_reason = ReadResetFlag();
|
|
// last_reboot_reason = RTC_ReadBackupRegister(RTC_BKP_DR1);
|
|
//
|
|
// if (last_reboot_reason == 0x0011)
|
|
// {
|
|
// SetDeepSleepMode(true);
|
|
// }
|
|
|
|
UnixTimeStamp = GetRealTimeStamp();
|
|
|
|
aDateAndTime.year = reverse16(2016);
|
|
aDateAndTime.month = 5;
|
|
aDateAndTime.day = 2;
|
|
aDateAndTime.hour = 10;
|
|
aDateAndTime.minutes = 46;
|
|
aDateAndTime.seconds = 30;
|
|
aDateAndTime.deci_seconds = 3;
|
|
aDateAndTime.UTC_direction = '+';
|
|
aDateAndTime.UTC_hours = 8;
|
|
aDateAndTime.UTC_minutes = 0;
|
|
|
|
OptimeStamp = 0;
|
|
}
|
|
|
|
uint8_t ReadResetFlag(void)
|
|
{
|
|
return rtc_read_nvr(0x01);
|
|
}
|
|
|
|
uint32_t GetLastRebootReason(void)
|
|
{
|
|
return last_reboot_reason;
|
|
}
|
|
|
|
uint16_t GetTimeYear(void)
|
|
{
|
|
return (DEVICE_TIME.year + UTC_YEAR);
|
|
}
|
|
|
|
uint16_t GetTimeMonth(void)
|
|
{
|
|
return DEVICE_TIME.month;
|
|
}
|
|
|
|
uint16_t GetTimeDate(void)
|
|
{
|
|
return DEVICE_TIME.date;
|
|
}
|
|
|
|
uint16_t GetTimeHour(void)
|
|
{
|
|
return DEVICE_TIME.hour;
|
|
}
|
|
|
|
uint16_t GetTimeMinute(void)
|
|
{
|
|
return DEVICE_TIME.min;
|
|
}
|
|
|
|
uint16_t GetTimeSec(void)
|
|
{
|
|
return DEVICE_TIME.sec;
|
|
}
|
|
|
|
uint16_t GetTimeSubSec(void)
|
|
{
|
|
return DEVICE_TIME.sub_sec;
|
|
}
|
|
|
|
uint32_t GetTimeStamp(void)
|
|
{
|
|
return UnixTimeStamp;
|
|
}
|
|
|
|
void RtcGetDateTime(_PTIME aTime)
|
|
{
|
|
switch (rtc_ch) {
|
|
case 0: aTime->year = rtc_get_year(); break;
|
|
case 1: aTime->month = rtc_get_month(); break;
|
|
case 2: aTime->date = rtc_get_date(); break;
|
|
case 3: aTime->wday = rtc_get_wday(); break;
|
|
case 4: aTime->hour = rtc_get_hour(); break;
|
|
case 5: aTime->min = rtc_get_min(); break;
|
|
case 6: aTime->sec = rtc_get_sec(); break;
|
|
default: rtc_ch %= RTC_CH_END; break;
|
|
}
|
|
rtc_ch++;
|
|
rtc_ch %= RTC_CH_END;
|
|
}
|
|
|
|
void CalcTimeStampToDateTime(uint32_t TimeStamp, void *datetime)
|
|
{
|
|
uint32_t DateTimeStamp;
|
|
uint32_t DivSec, ModSec, DivMin, ModMin, DivHour, ModHour;
|
|
uint32_t tDay, DivDay, ModDay, i;
|
|
_PTIME dt = (_PTIME)datetime;
|
|
|
|
ModSec = TimeStamp % 60;
|
|
DivSec = TimeStamp / 60;
|
|
ModMin = DivSec % 60;
|
|
DivMin = DivSec / 60;
|
|
ModHour = DivMin % 24;
|
|
DivHour = DivMin / 24;
|
|
|
|
dt->hour = ModHour;
|
|
dt->min = ModMin;
|
|
dt->sec = ModSec;
|
|
|
|
DateTimeStamp = DivHour;
|
|
DateTimeStamp++;
|
|
|
|
tDay = 0;
|
|
i = 0;
|
|
|
|
while (tDay < DateTimeStamp)
|
|
tDay += CalcOneYearToDay(UTC_YEAR + i++);
|
|
|
|
i--;
|
|
tDay -= CalcOneYearToDay(UTC_YEAR + i);
|
|
|
|
dt->year = i;
|
|
|
|
DivDay = DateTimeStamp - tDay;
|
|
|
|
if (CheckLeapYear(UTC_YEAR + dt->year)) {
|
|
for (i = 1; i < 13; i++)
|
|
if (DivDay <= bMonth[i]) break;
|
|
} else {
|
|
for (i = 1; i < 13; i++)
|
|
if (DivDay <= aMonth[i]) break;
|
|
}
|
|
|
|
dt->month = i;
|
|
|
|
if (CheckLeapYear(UTC_YEAR + dt->year)) ModDay = DivDay - bMonth[i - 1];
|
|
else ModDay = DivDay - aMonth[i - 1];
|
|
|
|
dt->date = ModDay;
|
|
}
|
|
|
|
void RTC_TimeSet(_TTIME *aTIME)
|
|
{
|
|
uint8_t setDateTime[10];
|
|
|
|
setDateTime[0] = aTIME->year; // year
|
|
setDateTime[1] = aTIME->month; // month
|
|
setDateTime[2] = aTIME->date; // date
|
|
setDateTime[3] = aTIME->hour; // hour
|
|
setDateTime[4] = aTIME->min; // min
|
|
setDateTime[5] = aTIME->sec; // sec
|
|
|
|
rtc_set_datetime(setDateTime);
|
|
}
|
|
|
|
uint32_t Get_Local_Time(void)
|
|
{
|
|
return LocalTime;
|
|
}
|
|
|
|
void Set_Local_Time(uint32_t localtime)
|
|
{
|
|
LocalTime = localtime;
|
|
}
|
|
|
|
uint32_t GetRealTimeStamp(void)
|
|
{
|
|
uint32_t DateTimeStamp;
|
|
uint32_t iTotalDays;
|
|
_TTIME aTime;
|
|
|
|
memcpy(&aTime, &DEVICE_TIME, sizeof(_TTIME));
|
|
/* Get the current date */
|
|
RtcGetDateTime(&aTime);
|
|
|
|
iTotalDays = CalcDay((uint32_t)aTime.year + UTC_YEAR, aTime.month, aTime.date);
|
|
|
|
DateTimeStamp = iTotalDays - UTC_TIMESTAMP;
|
|
|
|
return (DateStampToTimeStamp(DateTimeStamp, KOREA_ZONE) +
|
|
((uint32_t)aTime.hour * 60 * 60) +
|
|
((uint32_t)aTime.min * 60) +
|
|
((uint32_t)aTime.sec));
|
|
}
|
|
|
|
void *GetDateAndTimeEx(void)
|
|
{
|
|
return (void *)&aDateAndTime;
|
|
}
|
|
|
|
void Get_Time(void)
|
|
{
|
|
UnixTimeStamp = GetRealTimeStamp();
|
|
|
|
if (UnixTimeStamp != BakUnixTimeStamp) {
|
|
CalcTimeStampToDateTime(UnixTimeStamp + UTC_KOREA, &DEVICE_TIME);
|
|
BakUnixTimeStamp = UnixTimeStamp;
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------*/
|
|
/* Get time in UTC */
|
|
/*------------------------------------------*/
|
|
|
|
int rtc_getutc (uint32_t* tmr)
|
|
{
|
|
*tmr = UnixTimeStamp;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------*/
|
|
/* Get time in calendar form */
|
|
/*------------------------------------------*/
|
|
|
|
int rtc_gettime (_TTIME* rtc)
|
|
{
|
|
rtc->year = DEVICE_TIME.year + UTC_YEAR;
|
|
rtc->month = DEVICE_TIME.month;
|
|
rtc->date = DEVICE_TIME.date;
|
|
rtc->wday = DEVICE_TIME.wday;
|
|
|
|
rtc->hour = DEVICE_TIME.hour;
|
|
rtc->min = DEVICE_TIME.min;
|
|
rtc->sec = DEVICE_TIME.sec;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int rtc_gettime1 (_TTIME* rtc)
|
|
{
|
|
uint32_t utc, n, i, d;
|
|
|
|
if (!rtc_getutc(&utc)) return 0;
|
|
|
|
utc += (long)(UTC_KOREA);
|
|
|
|
rtc->sec = (uint8_t)(utc % 60); utc /= 60;
|
|
rtc->min = (uint8_t)(utc % 60); utc /= 60;
|
|
rtc->hour = (uint8_t)(utc % 24); utc /= 24;
|
|
rtc->date = (uint8_t)((utc + 4) % 7);
|
|
rtc->year = (uint16_t)(1970 + utc / 1461 * 4); utc %= 1461;
|
|
n = ((utc >= 1096) ? utc - 1 : utc) / 365;
|
|
rtc->year += n;
|
|
utc -= n * 365 + (n > 2 ? 1 : 0);
|
|
for (i = 0; i < 12; i++) {
|
|
d = samurai[i];
|
|
if (i == 1 && n == 2) d++;
|
|
if (utc < d) break;
|
|
utc -= d;
|
|
}
|
|
rtc->month = (uint8_t)(1 + i);
|
|
rtc->date = (uint8_t)(1 + utc);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the current time in milliseconds
|
|
* when LWIP_TIMERS == 1 and NO_SYS == 1
|
|
* @param None
|
|
* @retval Time
|
|
*/
|
|
uint32_t sys_now(void)
|
|
{
|
|
// return HAL_GetTick();
|
|
return LocalTime;
|
|
}
|
|
|
|
uint32_t GetWarmingUp(void)
|
|
{
|
|
return WarmingUp;
|
|
}
|
|
|
|
void WarmingUp_Process(uint16_t tick)
|
|
{
|
|
if ((WarmingUp - 2000) > tick) {
|
|
WarmingUp -= tick;
|
|
} else if (WarmingUp > tick) {
|
|
device_status.battery_status.bit.INIT = true;
|
|
WarmingUp -= tick;
|
|
} else if (tick > WarmingUp) {
|
|
WarmingUp = 0;
|
|
}
|
|
}
|
|
|
|
void Time_Update(void *ptmr, void *parg)
|
|
{
|
|
LocalTime += RTC_TMR_PERIOD_TIME;
|
|
|
|
DEVICE_TIME.sub_sec++;
|
|
|
|
if (DEVICE_TIME.sub_sec >= 100) {
|
|
OptimeStamp++;
|
|
DEVICE_TIME.sub_sec = 0;
|
|
|
|
BD_LED_Toggle();
|
|
}
|
|
|
|
WarmingUp_Process(RTC_TMR_PERIOD_TIME);
|
|
DecIOTaskTick(RTC_TMR_PERIOD_TIME);
|
|
|
|
Calculation_10ms_Current(RTC_TMR_PERIOD_TIME);
|
|
|
|
dec_cb_tick(RTC_TMR_PERIOD_TIME);
|
|
dec_soc_tick(RTC_TMR_PERIOD_TIME);
|
|
|
|
dec_relexation_tick(RTC_TMR_PERIOD_TIME);
|
|
dec_tapper_tick(RTC_TMR_PERIOD_TIME);
|
|
|
|
dec_alarm_tick(RTC_TMR_PERIOD_TIME);
|
|
|
|
IncFileCopyTimer(RTC_TMR_PERIOD_TIME);
|
|
|
|
#ifdef CONSOLE_DEBUG
|
|
CalOSTaskCtxSwCtrPerSec(RTC_TMR_PERIOD_TIME);
|
|
#endif // #ifdef CONSOLE_DEBUG
|
|
|
|
WDT_RefreshCounter();
|
|
}
|
|
|
|
/* RTC Task */
|
|
void AppTaskRTC(void)
|
|
{
|
|
rtc_init();
|
|
|
|
while (DEF_TRUE) {
|
|
Get_Time();
|
|
delay_os_ms(50);
|
|
}
|
|
}
|
|
|
|
/* Console Function *************************************************/
|
|
|
|
#ifdef CONSOLE_DEBUG
|
|
|
|
void RTC_TimeShow(void)
|
|
{
|
|
_TTIME aTime;
|
|
|
|
/* Get the current datetime */
|
|
RtcGetDateTime(&aTime);
|
|
|
|
printf("\r\nThe current datetime is : %0.2d/%0.2d/%0.2d %0.2d:%0.2d:%0.2d \r\n"
|
|
, aTime.year
|
|
, aTime.month
|
|
, aTime.date
|
|
, aTime.hour
|
|
, aTime.min
|
|
, aTime.sec
|
|
);
|
|
}
|
|
|
|
uint32_t GetBuildTimeStamp(void)
|
|
{
|
|
uint8_t datetime[15];
|
|
uint32_t DateTimeStamp;
|
|
uint32_t iTotalDays;
|
|
_TTIME aTime;
|
|
|
|
GET_BUILD_DATETIME(datetime);
|
|
datetime[14] = 0;
|
|
|
|
printf("Build : %s\r\n", datetime);
|
|
|
|
aTime.year = StrToInt32(&datetime[ 0], 4) - UTC_YEAR;
|
|
aTime.month = StrToInt32(&datetime[ 4], 2);
|
|
aTime.date = StrToInt32(&datetime[ 6], 2);
|
|
aTime.hour = StrToInt32(&datetime[ 8], 2);
|
|
aTime.min = StrToInt32(&datetime[10], 2);
|
|
aTime.sec = StrToInt32(&datetime[12], 2);
|
|
|
|
iTotalDays = CalcDay((uint32_t)aTime.year + UTC_YEAR,
|
|
aTime.month,
|
|
aTime.date);
|
|
|
|
DateTimeStamp = iTotalDays - UTC_TIMESTAMP;
|
|
|
|
return (DateStampToTimeStamp(DateTimeStamp, KOREA_ZONE) +
|
|
((uint32_t)aTime.hour * 60 * 60) +
|
|
((uint32_t)aTime.min * 60) +
|
|
((uint32_t)aTime.sec));
|
|
}
|
|
|
|
void Get_TimeStr(uint8_t *text)
|
|
{
|
|
Int32ToStr((DEVICE_TIME.year % 100) + 1970, &text[ 0], 4);
|
|
Int32ToStr((DEVICE_TIME.month % 100) , &text[ 4], 2);
|
|
Int32ToStr((DEVICE_TIME.date % 100) , &text[ 6], 2);
|
|
Int32ToStr((DEVICE_TIME.hour % 100) , &text[ 8], 2);
|
|
Int32ToStr((DEVICE_TIME.min % 100) , &text[10], 2);
|
|
Int32ToStr((DEVICE_TIME.sec % 100) , &text[12], 2);
|
|
}
|
|
|
|
/* input(ASCII) : YYYYMMDDhhmmss */
|
|
int8_t Set_Time(uint8_t *time)
|
|
{
|
|
uint16_t size, i;
|
|
uint8_t setDateTime[10];
|
|
|
|
size = 0;
|
|
|
|
while (time[size] != 0x00) size++; /* Measure total string length */
|
|
if (size != 14 ) return 1;
|
|
|
|
i = 0;
|
|
setDateTime[0] = (StrToInt(&time[i], 4)) - UTC_YEAR; i += 4; // year
|
|
setDateTime[1] = (StrToInt(&time[i], 2)) - 0; i += 2; // month
|
|
setDateTime[2] = (StrToInt(&time[i], 2)) - 0; i += 2; // date
|
|
setDateTime[3] = (StrToInt(&time[i], 2)) - 0; i += 2; // hour
|
|
setDateTime[4] = (StrToInt(&time[i], 2)) - 0; i += 2; // min
|
|
setDateTime[5] = (StrToInt(&time[i], 2)) - 0; i += 2; // sec
|
|
|
|
rtc_set_datetime(setDateTime);
|
|
|
|
RTC_TimeShow();
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t dis_last_reboot_reason = 0;
|
|
|
|
void ODisplayDateTime(uint8_t p)
|
|
{
|
|
uint8_t text[30];
|
|
|
|
if (p || (DEVICE_TIME.sec != bak_sec)) {
|
|
sprintf((char *)text, "%04d/%02d/%02d",
|
|
DEVICE_TIME.year + UTC_YEAR,
|
|
DEVICE_TIME.month,
|
|
DEVICE_TIME.date
|
|
);
|
|
GreenOutXY(70, 19, text);
|
|
|
|
sprintf((char *)text, "%02d:%02d:%02d",
|
|
DEVICE_TIME.hour,
|
|
DEVICE_TIME.min,
|
|
DEVICE_TIME.sec
|
|
);
|
|
GreenOutXY(71, 20, text);
|
|
bak_sec = DEVICE_TIME.sec;
|
|
}
|
|
|
|
if (p || (dis_last_reboot_reason != last_reboot_reason))
|
|
{
|
|
sprintf((char *)text, "%04X"
|
|
, last_reboot_reason
|
|
);
|
|
GreenOutXY(75, 21, text);
|
|
dis_last_reboot_reason = last_reboot_reason;
|
|
}
|
|
}
|
|
|
|
void SDisplayDateTime(uint8_t p)
|
|
{
|
|
uint8_t text[30];
|
|
|
|
if (p || (DEVICE_TIME.sec != bak_sec))
|
|
{
|
|
sprintf((char *)text, "%04d%02d%02d%02d%02d%02d",
|
|
DEVICE_TIME.year + UTC_YEAR,
|
|
DEVICE_TIME.month,
|
|
DEVICE_TIME.date,
|
|
DEVICE_TIME.hour,
|
|
DEVICE_TIME.min,
|
|
DEVICE_TIME.sec
|
|
);
|
|
GreenOutXY(65, 16, text);
|
|
|
|
bak_sec = DEVICE_TIME.sec;
|
|
}
|
|
}
|
|
|
|
#endif // #ifdef CONSOLE_DEBUG
|
|
|
|
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/
|