#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;
}