/******************************************************************************** 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 bMcuFlashWrWaitFlg; BOOL bMcuFlashWrFlg; BOOL bMcuFlashErr; U8 xdata ucMcuFlashWrValid; U8 xdata bMcuFlashWrWaitCnt; /************************************************************************************************* * 函数名: McuFlashWrOneByte * 参 数: McuFlashAddr:起始地址;WrData:写入的注释 * 返回值: 无 * 描 述: 写1个字节 *************************************************************************************************/ void McuFlashWrOneByte(U16 McuFlashAddr, U8 WrData) { IrqDis(); McuFlashEn(); XPAGE = McuFlashAddr>>8; IB_OFFSET = McuFlashAddr % 256; IB_DATA = WrData; IB_CON1 = 0x6E; IB_CON2 = 0x05; IB_CON3 = 0x0A; IB_CON4 = 0x09; if(XPAGE == (McuFlashAddr>>8)) { IB_CON5 = 0x06; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } McuFlashDis(); IrqEn(); } /************************************************************************************************* * 函数名: McuFlashBlankCheck * 参 数: McuFlashAddr:起始地址 * 返回值: 0:非全0,Erase失败;1:全0,Erase成功 * 描 述: 当Erase完1个Sector,需检查是否全为0 *************************************************************************************************/ BOOL McuFlashBlankCheck(U16 McuFlashAddr) { BOOL Result = 1; U16 i; for(i=0; i>8; IB_DATA = *(ptr+i); IB_CON1 = 0x6E; if(!EA) { IB_CON2 = 0x05; if(FLASHCON) { IB_CON3 = 0x0A; if(ucMcuFlashWrValid == 0x55) { IB_CON4 = 0x09; if(XPAGE == ((McuFlashAddr+i)>>8)) { IB_CON5 = 0x06; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Result = 1; } else { Result = 0; break; } } else { Result = 0; break; } } else { Result = 0; break; } } else { Result = 0; break; } } return Result; } /************************************************************************************************* * 函数名: McuFlashWrite * 参 数: McuFlashAddr:写入的地址,长度固定为1个Sector * 返回值: 0:写入失败;1:写入成功 * 描 述: 写MCU Flash的1个Sector: 1.Erase Sector 2.检查当前Sector是否全为0 3.将XRAM数据写入 4.校验XRAM和MCU Flash区数据是否一致 *************************************************************************************************/ BOOL McuFlashWrite(U16 McuFlashAddr, U16 XramAddr) { BOOL Result = 0; McuWDTClear(); //清看门狗 IrqDis(); //关闭中断源 McuFlashEn(); XPAGE = McuFlashAddr >> 8; IB_CON1 = 0xE6; if(!EA) { IB_CON2 = 0x05; if(FLASHCON) { IB_CON3 = 0x0A; if(ucMcuFlashWrValid == 0x55) { IB_CON4 = 0x09; if(XPAGE == (McuFlashAddr >> 8)) { IB_CON5 = 0x06; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); if(McuFlashBlankCheck(McuFlashAddr)) //查空 { if(McuFlashWrSector(McuFlashAddr, XramAddr)) //写入 { if(McuFlashDataCheck(McuFlashAddr, XramAddr)) //校验 { Result = 1; } } } } } } } IB_CON1 = 0; IB_CON2 = 0; IB_CON3 = 0; IB_CON4 = 0; IB_CON5 = 0; McuFlashDis(); XPAGE = 0x00; IrqEn(); return Result; } /************************************************************************************************* * 函数名: McuFlashProcess * 参 数: 无 * 返回值: 无 * 描 述: 写MCU Flash,同时更新备份1区和2区 *************************************************************************************************/ void McuFlashProcess(void) { BOOL McuFlashBk1WrFailFlg = 0, McuFlashBk2WrFailFlg = 0; U16 VoltageMin; if(bMcuFlashWrFlg) { bMcuFlashWrFlg = 0; ucMcuFlashWrValid = 0x55; //防误写检验标志 if(ucCellNum > 5) //6~10串应用,需要总电压超过10V { VoltageMin = 10000; } else //3~5串应用,需要总电压超过5V { VoltageMin = 5000; } if((Info.ulVoltage>=VoltageMin) && (E2uiCheckFlag==0x5AA5)) { if(!McuFlashWrite(MCUFLASH_BK1_ADDR, XRAM_MAP_ADDR)) //连续写两次,如果都错误则置位错误标志 { if(!McuFlashWrite(MCUFLASH_BK1_ADDR, XRAM_MAP_ADDR)) { McuFlashBk1WrFailFlg = 1; E2uiCheckFlag = 0xFFFF; McuFlashWrOneByte(MCUFLASH_BK1_ADDR+510,0xFF); McuFlashWrOneByte(MCUFLASH_BK1_ADDR+511,0xFF); } } if(!McuFlashWrite(MCUFLASH_BK2_ADDR, XRAM_MAP_ADDR)) { if(!McuFlashWrite(MCUFLASH_BK2_ADDR, XRAM_MAP_ADDR)) { McuFlashBk2WrFailFlg = 1; E2uiCheckFlag = 0xFFFF; McuFlashWrOneByte(MCUFLASH_BK2_ADDR+510,0xFF); McuFlashWrOneByte(MCUFLASH_BK2_ADDR+511,0xFF); } } } else { McuFlashBk1WrFailFlg = 1; McuFlashBk2WrFailFlg = 1; } ucMcuFlashWrValid = 0x00; if(McuFlashBk1WrFailFlg && McuFlashBk2WrFailFlg) //如果Flash两个区都操作错误,则置位Flash错误标志 { bMcuFlashErr = 1; } } } /************************************************************************************************* * 函数名: McuFlashRead * 参 数: SourceAddr:源地址;TargetAddr:目标地址;Length:数据长度 * 返回值: 0:数据正确;1:数据错误 * 描 述: 判断MCU Flash参数区的最后一个字节是否为0x5AA5,检查数据区是否被破坏 *************************************************************************************************/ BOOL McuFlashRead(U16 SourceAddr, U8 xdata *TargetAddr, U16 Length) { U16 i; BOOL Result = 1; U8 xdata *data TargetAddr1 = TargetAddr; //*后面的data关键字的作用,是把指针TargetAddr1定义在data区中 IrqDis(); McuFlashEn(); McuWDTClear(); for(i=0; i= MCU_FLASH_WATI_DELAY) { bMcuFlashWrWaitFlg = 0; bMcuFlashWrWaitCnt = 0; bMcuFlashWrFlg = 1; } } } /************************************************************************************************* * 函数名: McuFlashCheckFlg * 参 数: McuFlashAddr:MCU Flash区的地址 * 返回值: 0:数据正确;1:数据错误 * 描 述: 判断MCU Flash参数区的最后一个字节是否为0x5AA5,检查数据区是否被破坏 *************************************************************************************************/ BOOL McuFlashCheckFlg(U16 McuFlashAddr) { BOOL Result = 0; McuFlashEn(); if(CWORD[McuFlashAddr/2] == 0x5AA5) { Result = 1; } McuFlashDis(); return Result; }