/** ****************************************************************************** * @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. * *

© COPYRIGHT 2022 AMG

****************************************************************************** */ /** @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******/