#include "Service_Interval.h" #include <stdio.h> #include <string.h> #include "Components.h" /** * @file Service_Interval.c * @brief 保养里程 * @details 保养里程 * @author myliu * @date 2022.05.15 * @version V1.0 * @copyright myliu */ typedef struct { Intlib_uint32_t Interval100m; /*设定的里程间隔 0.1km */ Intlib_uint32_t MilAfterReset; /*上次复位后里程值 0.1km */ Intlib_uint32_t IntervalDayEnable; Intlib_uint32_t Interval1s; /*设定的时间间隔 100ms */ Intlib_uint32_t CurODO_100m; /*当前里程值 0.1km */ Intlib_uint32_t CurTimer_1s; /*已走动时间 100ms */ } DataIntervalCalc_t; typedef struct { Intlib_uint32_t Flag; /*存储标志 7887A55A */ Intlib_uint32_t Interval100m; /*设定的里程间隔 0.1km */ Intlib_uint32_t Interval1s; /*设定的时间间隔 1s */ Intlib_uint32_t MilAfterReset; /*上次复位后里程值 0.1km */ Intlib_uint32_t TotalTimer; /*已走动时间 1s */ } DataIntervalSave_t; static Int_PowerSts g_PowerSts_Cbk; static Int_ReadODO g_ReadODO_Cbk; static Int_EEPromWrite g_EEPromWrite_Cbk; static Int_EEPromRead g_EEPromRead_Cbk; static Intlib_uint32_t g_TimerCnt = 0u; static Intlib_uint32_t g_InitCompleteFlag = 0u; static DataIntervalCalc_t *g_IntervalCalc; #pragma ghs section bss = ".myNonInitArea" static Intlib_uint32_t g_ServiceMil100m; static Intlib_uint32_t g_ServiceTimer1s; #pragma ghs section bss = default /** * @brief 保养服务初始化函数,KL30调用 * @param[in] pMemSpace 此功能库需要的内存空间,大小为Data_MEM_Block_Maintain,此内存需在休眠唤醒后不丢失 * @param[in] pInitData 初始化数据,详见Maintain_Init_t * @param[in] pFunc 回调函数,详见Maintain_Func_t * @return 参数错误类型 * * @warning 必须在EEPROM初始化之后调用 * * @since 1.0.0 */ void Service_Interval_KL30_Init(Intlib_uint8_t *pMemSpace, Maintain_Init_t *pInitData, Maintain_Func_t *pFunc) { DataIntervalSave_t DataIntervalSave; g_PowerSts_Cbk = pFunc->PowerSts_Cbk; g_ReadODO_Cbk = pFunc->ReadODO_Cbk; g_EEPromWrite_Cbk = pFunc->EEPromWrite_Cbk; g_EEPromRead_Cbk = pFunc->EEPromRead_Cbk; if ( pMemSpace != Intlib_NULL ) { g_IntervalCalc = ( DataIntervalCalc_t * )pMemSpace; if ( pInitData != Intlib_NULL ) { g_IntervalCalc->IntervalDayEnable = pInitData->IntervalDayEnable; if ( g_EEPromRead_Cbk != Intlib_NULL ) { g_EEPromRead_Cbk(( Intlib_uint32_t * )&DataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); if ( DataIntervalSave.Flag != 0x7887A55A ) { g_IntervalCalc->Interval100m = pInitData->IntervalKm * 10; g_IntervalCalc->MilAfterReset = g_ReadODO_Cbk( ); g_IntervalCalc->Interval1s = pInitData->IntervalDay * 24 * 60 * 60; g_IntervalCalc->CurTimer_1s = 0u; DataIntervalSave.Flag = 0x7887A55A; DataIntervalSave.Interval100m = g_IntervalCalc->Interval100m; DataIntervalSave.MilAfterReset = g_IntervalCalc->MilAfterReset; DataIntervalSave.Interval1s = g_IntervalCalc->Interval1s; DataIntervalSave.TotalTimer = g_IntervalCalc->CurTimer_1s; if ( g_EEPromWrite_Cbk != Intlib_NULL ) { g_EEPromWrite_Cbk(( Intlib_uint32_t * )&DataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); } } else { g_IntervalCalc->Interval100m = DataIntervalSave.Interval100m; g_IntervalCalc->MilAfterReset = DataIntervalSave.MilAfterReset; g_IntervalCalc->Interval1s = DataIntervalSave.Interval1s; g_IntervalCalc->CurTimer_1s = DataIntervalSave.TotalTimer; } } else { g_IntervalCalc->Interval100m = pInitData->IntervalKm * 10; g_IntervalCalc->MilAfterReset = g_ReadODO_Cbk( ); g_IntervalCalc->Interval1s = pInitData->IntervalDay * 24 * 60 * 60; g_IntervalCalc->CurTimer_1s = 0u; } } } g_TimerCnt = 0u; g_InitCompleteFlag = 0x78875AA5ul; } /** * @brief 保养服务初始化函数,唤醒时调用 * @param[in] pMemSpace 此功能库需要的内存空间,大小为Data_MEM_Block_Maintain,此内存需在休眠唤醒后不丢失 * @param[in] pFunc 回调函数,详见Maintain_Func_t * @return 参数错误类型 * * @warning 必须在EEPROM初始化之后调用 * * @since 1.0.0 */ void Service_Interval_Wakeup_Init(Intlib_uint8_t *pMemSpace, Maintain_Func_t *pFunc) { g_PowerSts_Cbk = pFunc->PowerSts_Cbk; g_ReadODO_Cbk = pFunc->ReadODO_Cbk; g_EEPromWrite_Cbk = pFunc->EEPromWrite_Cbk; g_EEPromRead_Cbk = pFunc->EEPromRead_Cbk; if ( pMemSpace != Intlib_NULL ) { g_IntervalCalc = ( DataIntervalCalc_t * )pMemSpace; } g_TimerCnt = 0u; g_InitCompleteFlag = 0x78875AA5ul; } /** * @brief 保养里程计算函数,100ms任务调用 * * @since 1.0.0 */ void Service_Interval_Processing(void) { DataIntervalSave_t DataIntervalSave; Intlib_uint32_t IntervalKm = 0; if ( g_PowerSts_Cbk( ) == Int_PowerON ) { if(g_IntervalCalc != Intlib_NULL) { g_IntervalCalc->CurODO_100m = g_ReadODO_Cbk( ); if ( g_IntervalCalc->CurODO_100m >= g_IntervalCalc->MilAfterReset ) { IntervalKm = g_IntervalCalc->CurODO_100m - g_IntervalCalc->MilAfterReset; } else { IntervalKm = 0; } if ( g_IntervalCalc->Interval100m >= IntervalKm ) { g_ServiceMil100m = g_IntervalCalc->Interval100m - IntervalKm; } else { g_ServiceMil100m = 0u; } if ( g_IntervalCalc->IntervalDayEnable ) { if ( g_IntervalCalc->Interval1s >= g_IntervalCalc->CurTimer_1s ) { g_ServiceTimer1s = g_IntervalCalc->Interval1s - g_IntervalCalc->CurTimer_1s; } else { g_ServiceTimer1s = 0u; } } } } else { g_IntervalCalc->CurODO_100m = g_ReadODO_Cbk( ); if ( g_IntervalCalc->CurODO_100m >= g_IntervalCalc->MilAfterReset ) { IntervalKm = g_IntervalCalc->CurODO_100m - g_IntervalCalc->MilAfterReset; } else { IntervalKm = 0; } if ( g_IntervalCalc->Interval100m >= IntervalKm ) { g_ServiceMil100m = g_IntervalCalc->Interval100m - IntervalKm; } else { g_ServiceMil100m = 0u; } } if ( g_IntervalCalc->IntervalDayEnable ) { if((g_IntervalCalc->CurTimer_1s % 216000) == 0) { DataIntervalSave.Flag = 0x7887A55A; DataIntervalSave.Interval100m = g_IntervalCalc->Interval100m; DataIntervalSave.MilAfterReset = g_IntervalCalc->MilAfterReset; DataIntervalSave.Interval1s = g_IntervalCalc->Interval1s; DataIntervalSave.TotalTimer = g_IntervalCalc->CurTimer_1s; g_EEPromWrite_Cbk(( Intlib_uint32_t * )&DataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); } } } /** * @brief 保养天数计算函数,100ms中断调用,如不支持此功能,可不调用 * * @since 1.0.0 */ void Service_Interval_TimerISR(void) { if ( g_InitCompleteFlag == 0x78875AA5ul ) { if(g_IntervalCalc != Intlib_NULL) { if ( g_IntervalCalc->IntervalDayEnable ) /*配置为显示保养天数*/ { g_TimerCnt++; if ( g_TimerCnt >= 10 ) { g_TimerCnt = 0u; if ( g_IntervalCalc->CurTimer_1s <= 0xFFFFFFFFul ) { g_IntervalCalc->CurTimer_1s++; } } } } } } /** * @brief 保养天数添加睡眠时间,请参数例程使用,如不支持此功能,可不调用 * Sleep之后停止计时 唤醒后 把这一阶段的时间差补正回来 * * @since 1.0.0 */ void Service_Interval_TimerSleepFix(Intlib_uint32_t FixTimer) { if ( g_InitCompleteFlag == 0x78875AA5ul ) { if(g_IntervalCalc != Intlib_NULL) { if ( g_IntervalCalc->IntervalDayEnable ) { if ( g_IntervalCalc->CurTimer_1s <= 0xFFFFFFFFul ) { g_IntervalCalc->CurTimer_1s += (FixTimer / 10); } } } } } /** * @brief 设置保养里程间隔,单位km * @param[in] IntervalKm 保养里程间隔,单位km * * @since 1.0.0 */ void Service_Interval_SetKm(Intlib_uint32_t IntervalKm) { DataIntervalSave_t DataIntervalSave; DataIntervalSave_t ReadDataIntervalSave; Intlib_uint8_t u8Errcount = 0; if (g_IntervalCalc != Intlib_NULL) { g_IntervalCalc->Interval100m = IntervalKm * 10; g_IntervalCalc->MilAfterReset = g_ReadODO_Cbk(); DataIntervalSave.Flag = 0x7887A55A; DataIntervalSave.Interval100m = g_IntervalCalc->Interval100m; DataIntervalSave.MilAfterReset = g_IntervalCalc->MilAfterReset; if (g_IntervalCalc->IntervalDayEnable) { DataIntervalSave.Interval1s = g_IntervalCalc->Interval1s; DataIntervalSave.TotalTimer = g_IntervalCalc->CurTimer_1s; } else { DataIntervalSave.Interval1s = 0u; DataIntervalSave.TotalTimer = 0u; } while (u8Errcount < 3) { if (g_EEPromWrite_Cbk != Intlib_NULL) { g_EEPromWrite_Cbk((Intlib_uint32_t *)&DataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); } if (g_EEPromRead_Cbk != Intlib_NULL) { g_EEPromRead_Cbk((Intlib_uint32_t *)&ReadDataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); } if (memcmp(&DataIntervalSave, &ReadDataIntervalSave, sizeof(DataIntervalSave_t)) == 0) { break; } u8Errcount++; if(u8Errcount >= 3) { break; } Gen_TimeDelay(10 * 1000u, 50u); } } } Intlib_uint32_t Get_Interval_SetKm(void) { Intlib_uint32_t Temp = 0; if(g_IntervalCalc != Intlib_NULL) { Temp = g_IntervalCalc->Interval100m; } else { Temp = 30000u; } return Temp; } /** * @brief 设置保养天数间隔,单位天,每个月按30天计算,如不支持此功能,可不调用 * @param[in] IntervalDay 保养天数间隔,单位天 * * @since 1.0.0 */ void Service_Interval_SetDay(Intlib_uint32_t IntervalDay) { DataIntervalSave_t DataIntervalSave; if ( g_IntervalCalc != Intlib_NULL ) { g_IntervalCalc->CurTimer_1s = 0u; g_IntervalCalc->Interval1s = IntervalDay * 24 * 60 * 60; DataIntervalSave.Flag = 0x7887A55A; DataIntervalSave.Interval100m = g_IntervalCalc->Interval100m; DataIntervalSave.MilAfterReset = g_IntervalCalc->MilAfterReset; DataIntervalSave.Interval1s = g_IntervalCalc->Interval1s; DataIntervalSave.TotalTimer = g_IntervalCalc->CurTimer_1s; if ( g_EEPromWrite_Cbk != Intlib_NULL ) { g_EEPromWrite_Cbk(( Intlib_uint32_t * )&DataIntervalSave, (Intlib_uint16_t)(sizeof(DataIntervalSave_t) / 4)); } } } /** * @brief 获取剩余保养里程,单位100m * @return 剩余保养里程,单位100m * * @since 1.0.0 */ Intlib_uint32_t Service_Interval_GetMil100m(void) { if((g_ServiceMil100m % 10) > 0) { return g_ServiceMil100m + 10u; } else { return g_ServiceMil100m; } } /** * @brief 获取剩余保养天数,单位天,如不支持此功能,可不调用 * @return 剩余保养天数,单位天 * * @since 1.0.0 */ Intlib_uint32_t Service_Interval_GetDay(void) { Intlib_uint32_t ServiceIntervalDay = 0u; ServiceIntervalDay = (g_ServiceTimer1s / 60 / 60 / 24) + 1; return ServiceIntervalDay; }