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