ZDBMS/code_drv/ExtE2PRom.c

562 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
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;
}
}
}