562 lines
14 KiB
C
562 lines
14 KiB
C
/********************************************************************************
|
||
Copyright (C), Sinowealth Electronic. Ltd.
|
||
Author: Sino
|
||
Version: V0.0
|
||
Date: 2020/04/26
|
||
History:
|
||
V2.0 2020/04/26 Preliminary
|
||
********************************************************************************/
|
||
#include "Main.h"
|
||
|
||
BOOL bE2PProcessFlg; //EEPROM处理标志
|
||
BOOL bE2PBKDsgEnd; //放电结束标志,需要备份信息到外挂EEPROM
|
||
BOOL bE2PBKDsgEndValid;
|
||
BOOL bE2PBKChgStop; //充电结束标志,需要备份信息到外挂EEPROM
|
||
BOOL bE2PBKChgStart; //充电开始标志,需要备份信息到外挂EEPROM
|
||
BOOL bE2PBKRtc; //RTC定时备份标志,需要备份信息到外挂EEPROM
|
||
BOOL bE2PErase; //擦除外挂EEPROM标志
|
||
U8 xdata bUart0E2PRdData; //读取外挂EEPROM标志
|
||
U8 xdata bUart1E2PRdData; //读取外挂EEPROM标志
|
||
U8 xdata bUart2E2PRdData; //读取外挂EEPROM标志
|
||
BOOL bE2PRErr;
|
||
BOOL bE2PTwiRWErrFlg;
|
||
U8 xdata bUart0RTCRdTime; //读取RTC时间标志
|
||
U8 xdata bUart1RTCRdTime; //读取RTC时间标志
|
||
U8 xdata bUart2RTCRdTime; //读取RTC时间标志
|
||
BOOL bDsgToChgFlg; //放电转换为充电,需要备份数据
|
||
BOOL bChgToDsgFlg; //充电转换为放电,需要备份数据
|
||
U16 xdata uiE2PDataAddr;
|
||
U8 xdata ucE2PTwiRWErrDelayCnt;
|
||
U8 xdata ucRTCBKTime1;
|
||
U16 xdata uiRTCBKTime2;
|
||
U8 idata ucUpDataLimitTime;
|
||
U16 xdata uiCHGValidTime;
|
||
U8 xdata ucRTCBuf[7];
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: AFEI2CCheck
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 连续5S检测到AFE的I2C通讯错误,则置位bAfeErr=1
|
||
*************************************************************************************************/
|
||
void E2PRomTwiCheck(void)
|
||
{
|
||
if(bEnEEPRomBK)
|
||
{
|
||
if(bE2PTwiRWErrFlg)
|
||
{
|
||
if(++ucE2PTwiRWErrDelayCnt >= TIME_1S_5S)
|
||
{
|
||
bE2PRErr = 1;
|
||
ucE2PTwiRWErrDelayCnt = TIME_1S_5S;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ucE2PTwiRWErrDelayCnt = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomWrite
|
||
* 参 数: Addr:地址;Length:长度;WrBuf:写入存放的Buf
|
||
* 返回值: 无
|
||
* 描 述: 写入EEPROm
|
||
*************************************************************************************************/
|
||
BOOL E2PRomWrite(U16 WrAddr, U8 Length, U8 xdata *WrBuf)
|
||
{
|
||
BOOL Result = 0;
|
||
U8 i;
|
||
|
||
if(!bE2PRErr)
|
||
{
|
||
for(i=0; i<5; i++)
|
||
{
|
||
#ifdef TWI_Hardware_Module
|
||
if(TwiWrite(E2PROM_ID, WrAddr, TWI_ADDR_2B, Length, TWI_CRC_NO, WrBuf))
|
||
{
|
||
Result = 1;
|
||
break;
|
||
}
|
||
#else
|
||
if(TwiWrite(E2PROM_ID, WrAddr, Length, WrBuf))
|
||
{
|
||
Result = 1;
|
||
break;
|
||
}
|
||
#endif
|
||
Delay1ms(1);
|
||
}
|
||
}
|
||
bE2PTwiRWErrFlg = !Result; //标记通讯是否正常
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomRead
|
||
* 参 数: Addr:地址;Length:长度;RdBuf:读取存放的Buf
|
||
* 返回值: 无
|
||
* 描 述: 读取EEPROm
|
||
*************************************************************************************************/
|
||
BOOL E2PRomRead(U16 RdAddr, U8 Length, U8 xdata *RdBuf)
|
||
{
|
||
BOOL Result = 0;
|
||
U8 i;
|
||
|
||
if(!bE2PRErr)
|
||
{
|
||
for(i=0; i<5; i++)
|
||
{
|
||
#ifdef TWI_Hardware_Module
|
||
if(TwiRead(E2PROM_ID, RdAddr, TWI_ADDR_2B, Length, TWI_CRC_NO, RdBuf))
|
||
{
|
||
Result = 1;
|
||
break;
|
||
}
|
||
#else
|
||
if(TwiRead(E2PROM_ID, RdAddr, Length, RdBuf))
|
||
{
|
||
Result = 1;
|
||
break;
|
||
}
|
||
#endif
|
||
Delay1ms(1);
|
||
}
|
||
}
|
||
bE2PTwiRWErrFlg = !Result; //标记通讯是否正常
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomErase
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 擦除EEPROM
|
||
*************************************************************************************************/
|
||
void E2PRomErase(void)
|
||
{
|
||
U16 i;
|
||
U8 xdata WrBuf[8];
|
||
|
||
MemorySet(WrBuf, 0, 8); //clr Info.uiVCell[]
|
||
|
||
for(i=0; i<(E2PROM_SIZE/32-1); i++)
|
||
{
|
||
McuWDTClear();
|
||
E2PRomWrite(i*32+31, 1, WrBuf);
|
||
}
|
||
|
||
E2PRomWrite(E2PROM_BOOT_ADDR, 8, WrBuf);
|
||
uiE2PDataAddr = 0;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: InitE2PRom
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 初始化EEPROM的地址
|
||
*************************************************************************************************/
|
||
BOOL E2PRomInit(void)
|
||
{
|
||
BOOL Result = 0;
|
||
|
||
U8 xdata RdBuf[8];
|
||
|
||
Result = E2PRomRead(E2PROM_BOOT_ADDR, 8, RdBuf);
|
||
|
||
RdBuf[2] = RdBuf[0]+RdBuf[1];
|
||
RdBuf[6] = RdBuf[4]+RdBuf[5];
|
||
|
||
if(RdBuf[2] == RdBuf[3])
|
||
{
|
||
uiE2PDataAddr = ((U16)RdBuf[0]<<8) + RdBuf[1];
|
||
}
|
||
else if(RdBuf[6] == RdBuf[7])
|
||
{
|
||
uiE2PDataAddr = ((U16)RdBuf[4]<<8) + RdBuf[5];
|
||
}
|
||
else
|
||
{
|
||
uiE2PDataAddr = 0;
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomBKRTC
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 备份RTC
|
||
*************************************************************************************************/
|
||
void E2PRomBKRTC(void)
|
||
{
|
||
U8 xdata WrBuf[9];
|
||
U8 i, checksum = 0;
|
||
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&(RTC.Second), WrBuf, 7);
|
||
for(i=0; i<7; i++)
|
||
{
|
||
checksum += WrBuf[i];
|
||
}
|
||
WrBuf[7] = checksum;
|
||
WrBuf[8] = 0x5A;
|
||
|
||
E2PRomWrite(E2PROM_RTC_ADDR, 9, WrBuf);
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomBKBoot
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 备份EEPROM的Boot区
|
||
*************************************************************************************************/
|
||
void E2PRomBKBoot(void)
|
||
{
|
||
U8 xdata WrBuf[8];
|
||
|
||
WrBuf[0] = (uiE2PDataAddr>>8);
|
||
WrBuf[1] = uiE2PDataAddr;
|
||
WrBuf[3] = WrBuf[0]+WrBuf[1]; //Calculate checksum
|
||
|
||
WrBuf[4] = WrBuf[0];
|
||
WrBuf[5] = WrBuf[1];
|
||
WrBuf[7] = WrBuf[3];
|
||
|
||
E2PRomWrite(E2PROM_BOOT_ADDR, 8, WrBuf);
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomBKData
|
||
* 参 数: BKType:备份类型
|
||
* 返回值: 无
|
||
* 描 述: 读取外挂EEPROM
|
||
*************************************************************************************************/
|
||
void E2PRomBKData(U8 BKType)
|
||
{
|
||
U8 xdata WrBuf[32];
|
||
|
||
if(BKType == E2PROM_BKTYPE_CHG_START) //充电开始
|
||
{
|
||
MemoryCopy((U8 xdata *)&ucRTCBuf[0], WrBuf, 3);
|
||
MemoryCopy((U8 xdata *)&ucRTCBuf[4], WrBuf + 3, 3);
|
||
}
|
||
else
|
||
{
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&(RTC.Second), WrBuf, 3);
|
||
MemoryCopy((U8 xdata *)&(RTC.Date), WrBuf + 3, 3);
|
||
}
|
||
|
||
WrBuf[6] = (Info.uiPackStatus>>8);
|
||
WrBuf[7] = Info.uiPackStatus;
|
||
WrBuf[8] = (Info.uiBatStatus>>8);
|
||
WrBuf[9] = Info.uiBatStatus;
|
||
WrBuf[10] = (Info.ulFCC>>24);
|
||
WrBuf[11] = (Info.ulFCC>>16);
|
||
WrBuf[12] = (Info.ulFCC>>8);
|
||
WrBuf[13] = Info.ulFCC;
|
||
WrBuf[14] = (Info.ulRC>>24);
|
||
WrBuf[15] = (Info.ulRC>>16);
|
||
WrBuf[16] = (Info.ulRC>>8);
|
||
WrBuf[17] = Info.ulRC;
|
||
WrBuf[18] = (Info.ulVoltage>>24);
|
||
WrBuf[19] = (Info.ulVoltage>>16);
|
||
WrBuf[20] = (Info.ulVoltage>>8);
|
||
WrBuf[21] = Info.ulVoltage;
|
||
WrBuf[22] = (Info.slCurr>>24);
|
||
WrBuf[23] = (Info.slCurr>>16);
|
||
WrBuf[24] = (Info.slCurr>>8);
|
||
WrBuf[25] = Info.slCurr;
|
||
WrBuf[26] = (Info.uiTS[0]>>8);
|
||
WrBuf[27] = Info.uiTS[0];
|
||
WrBuf[28] = (Info.uiCycleCount>>8);
|
||
WrBuf[29] = Info.uiCycleCount;
|
||
WrBuf[30] = BKType;
|
||
WrBuf[31] = 0x5A;
|
||
|
||
E2PRomWrite(uiE2PDataAddr, 32, WrBuf);
|
||
|
||
uiE2PDataAddr += 32;
|
||
if(uiE2PDataAddr >= E2PROM_BOOT_ADDR)
|
||
{
|
||
uiE2PDataAddr = 0;
|
||
}
|
||
|
||
E2PRomBKBoot();
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: Uart0RdE2PRom
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取外挂EEPROM
|
||
*************************************************************************************************/
|
||
void Uart0RdE2PRom(void)
|
||
{
|
||
U16 RdAddr;
|
||
|
||
RdAddr = ((U16)ucUart0Buf[UART_CMD_NO]-CMD_RD_EEPROM)*128+((U16)ucSubClassID-0x80)*4096;
|
||
E2PRomRead(RdAddr, ucUart0Buf[UART_LENGTH], &ucUart0Buf[UART_DATA]);
|
||
|
||
ucUart0Buf[UART_DATA+ucUart0Buf[UART_LENGTH]] = CRC8cal(&ucUart0Buf,ucUart0Buf[UART_LENGTH]+UART_DATA);
|
||
Uart0SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: Uart1RdE2PRom
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取外挂EEPROM
|
||
*************************************************************************************************/
|
||
void Uart1RdE2PRom(void)
|
||
{
|
||
U16 RdAddr;
|
||
|
||
RdAddr = ((U16)ucUart1Buf[UART_CMD_NO]-CMD_RD_EEPROM)*128+((U16)ucSubClassID-0x80)*4096;
|
||
E2PRomRead(RdAddr, ucUart1Buf[UART_LENGTH], &ucUart1Buf[UART_DATA]);
|
||
|
||
ucUart1Buf[UART_DATA+ucUart1Buf[UART_LENGTH]] = CRC8cal(&ucUart1Buf,ucUart1Buf[UART_LENGTH]+UART_DATA);
|
||
Uart1SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: Uart2RdE2PRom
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取外挂EEPROM
|
||
*************************************************************************************************/
|
||
void Uart2RdE2PRom(void)
|
||
{
|
||
U16 RdAddr;
|
||
|
||
RdAddr = ((U16)ucUart2Buf[UART_CMD_NO]-CMD_RD_EEPROM)*128+((U16)ucSubClassID-0x80)*4096;
|
||
E2PRomRead(RdAddr, ucUart2Buf[UART_LENGTH], &ucUart2Buf[UART_DATA]);
|
||
|
||
ucUart2Buf[UART_DATA+ucUart2Buf[UART_LENGTH]] = CRC8cal(&ucUart2Buf,ucUart2Buf[UART_LENGTH]+UART_DATA);
|
||
Uart2SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: UartRdRTC
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取RTC时间:秒、分、时、日、月、年,并返回给UART
|
||
*************************************************************************************************/
|
||
void Uart0RdRTC(void)
|
||
{
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&(RTC.Second), &ucUart0Buf[UART_DATA], 7);
|
||
|
||
ucUart0Buf[UART_DATA+ucUart0Buf[UART_LENGTH]] = CRC8cal(&ucUart0Buf,ucUart0Buf[UART_LENGTH]+UART_DATA);
|
||
Uart0SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: Uart1RdRTC
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取RTC时间:秒、分、时、日、月、年,并返回给UART
|
||
*************************************************************************************************/
|
||
void Uart1RdRTC(void)
|
||
{
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&(RTC.Second), &ucUart1Buf[UART_DATA], 7);
|
||
|
||
ucUart1Buf[UART_DATA+ucUart1Buf[UART_LENGTH]] = CRC8cal(&ucUart1Buf,ucUart1Buf[UART_LENGTH]+UART_DATA);
|
||
Uart1SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: Uart2RdRTC
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 读取RTC时间:秒、分、时、日、月、年,并返回给UART
|
||
*************************************************************************************************/
|
||
void Uart2RdRTC(void)
|
||
{
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&(RTC.Second), &ucUart2Buf[UART_DATA], 7);
|
||
|
||
ucUart2Buf[UART_DATA+ucUart2Buf[UART_LENGTH]] = CRC8cal(&ucUart2Buf,ucUart2Buf[UART_LENGTH]+UART_DATA);
|
||
Uart2SendData(); //Start Send Data; Set UART REG
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomBKProcess
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 对外挂EEPROM进行相应处理
|
||
*************************************************************************************************/
|
||
void E2PRomBKProcess(void)
|
||
{
|
||
U8 BKType;
|
||
|
||
if(bEnEEPRomBK && bE2PProcessFlg)
|
||
{
|
||
bE2PProcessFlg = 0;
|
||
// E2PRomInit();
|
||
// RTCInitTime(&RTC);
|
||
|
||
if(bE2PErase)
|
||
{
|
||
bE2PErase = 0;
|
||
E2PRomErase();
|
||
}
|
||
|
||
if(bUart0E2PRdData||bUart1E2PRdData||bUart2E2PRdData)
|
||
{
|
||
if(bUart0E2PRdData )
|
||
{
|
||
bUart0E2PRdData = 0;
|
||
Uart0RdE2PRom();
|
||
}
|
||
if(bUart1E2PRdData)
|
||
{
|
||
bUart1E2PRdData = 0;
|
||
Uart2RdE2PRom();
|
||
}
|
||
if(bUart2E2PRdData)
|
||
{
|
||
bUart2E2PRdData = 0;
|
||
Uart2RdE2PRom();
|
||
}
|
||
|
||
}
|
||
|
||
if(bUart0RTCRdTime||bUart1RTCRdTime||bUart2RTCRdTime)
|
||
{
|
||
if(bUart0RTCRdTime)
|
||
{
|
||
bUart0RTCRdTime = 0;
|
||
Uart0RdRTC();
|
||
}
|
||
if(bUart1RTCRdTime)
|
||
{
|
||
bUart1RTCRdTime = 0;
|
||
Uart1RdRTC();
|
||
}
|
||
if(bUart2RTCRdTime)
|
||
{
|
||
bUart2RTCRdTime = 0;
|
||
Uart2RdRTC();
|
||
}
|
||
}
|
||
|
||
if(bE2PBKRtc)
|
||
{
|
||
bE2PBKRtc = 0;
|
||
E2PRomBKRTC();
|
||
}
|
||
|
||
if(bE2PBKChgStart)
|
||
{
|
||
bE2PBKChgStart = 0;
|
||
BKType = E2PROM_BKTYPE_CHG_START;
|
||
E2PRomBKData(BKType);
|
||
}
|
||
|
||
if(bE2PBKChgStop)
|
||
{
|
||
bE2PBKChgStop = 0;
|
||
BKType = E2PROM_BKTYPE_CHG_END;
|
||
E2PRomBKData(BKType);
|
||
}
|
||
|
||
if(bE2PBKDsgEnd)
|
||
{
|
||
bE2PBKDsgEnd = 0;
|
||
BKType = E2PROM_BKTYPE_DSG_END;
|
||
E2PRomBKData(BKType);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: E2PRomBKCheck
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 每1s检测是否需要备份RTC及EEPROM数据
|
||
*************************************************************************************************/
|
||
void E2PRomBKCheck(void)
|
||
{
|
||
if(bEnEEPRomBK)
|
||
{
|
||
// E2PRomInit();
|
||
// RTCInitTime(&RTC);
|
||
|
||
if(++ucRTCBKTime1 >= E2ucRTCBKDelay)
|
||
{
|
||
ucRTCBKTime1 = 0;
|
||
RTCReadTime(&RTC);
|
||
}
|
||
|
||
if(++uiRTCBKTime2 >= 3600) //1h
|
||
{
|
||
uiRTCBKTime2 = 0;
|
||
bE2PProcessFlg = 1;
|
||
bE2PBKRtc = 1;
|
||
}
|
||
|
||
if(!bCHGING)
|
||
{
|
||
bDsgToChgFlg = 1;
|
||
if(bChgToDsgFlg)
|
||
{
|
||
bChgToDsgFlg = 0;
|
||
bE2PProcessFlg = 1;
|
||
bE2PBKChgStop = 1;
|
||
}
|
||
if(bUV && bE2PBKDsgEndValid)
|
||
{
|
||
bE2PBKDsgEndValid = 0;
|
||
bE2PProcessFlg = 1;
|
||
bE2PBKDsgEnd = 1;
|
||
}
|
||
else if(!bUV)
|
||
{
|
||
bE2PBKDsgEndValid = 1;
|
||
}
|
||
}
|
||
|
||
if((bDsgToChgFlg && Info.slCurr>=E2siChgBKCur))
|
||
{
|
||
if(!uiCHGValidTime)
|
||
{
|
||
RTCReadTime(&RTC);
|
||
MemoryCopy((U8 xdata *)&RTC, ucRTCBuf, 7);
|
||
}
|
||
|
||
if(++uiCHGValidTime > ((U16)E2ucChgBKDelay*60)) //1分钟
|
||
{
|
||
uiCHGValidTime = 0;
|
||
bChgToDsgFlg = 1;
|
||
bDsgToChgFlg = 0;
|
||
bE2PProcessFlg = 1;
|
||
bE2PBKChgStart = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
uiCHGValidTime = 0;
|
||
}
|
||
}
|
||
}
|