Files
LFP_48V_mBMS_FW/APP_R3221/App/Source/brtc.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>&copy; 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******/