369 lines
8.5 KiB
C
369 lines
8.5 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 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<MCUFLASH_SECTOR_SIZE; i++)
|
||
{
|
||
if(CBYTE[McuFlashAddr+i] != 0x00)
|
||
{
|
||
Result = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashDataCheck
|
||
* 参 数: McuFlashAddr:起始地址
|
||
* 返回值: 0:校验错误;1:校验正确
|
||
* 描 述: 校验被写的Sector数据是否和XRAM区一致
|
||
*************************************************************************************************/
|
||
BOOL McuFlashDataCheck(U16 McuFlashAddr, U16 XramAddr)
|
||
{
|
||
BOOL Result = 1;
|
||
U8 xdata *ptr = (U8 xdata *)XramAddr; //强制将变量的值作为地址赋值给指针变量
|
||
U16 i;
|
||
|
||
for(i=0; i<MCUFLASH_SECTOR_SIZE; i++)
|
||
{
|
||
if(CBYTE[McuFlashAddr+i] != *(ptr+i))
|
||
{
|
||
Result = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashWrSector
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 写1个Sector的数据
|
||
*************************************************************************************************/
|
||
BOOL McuFlashWrSector(U16 McuFlashAddr, U16 XramAddr)
|
||
{
|
||
BOOL Result = 0;
|
||
U16 i;
|
||
U8 xdata *ptr = (U8 xdata *)XramAddr; //强制将变量的值作为地址赋值给指针变量
|
||
|
||
for(i=0; i<MCUFLASH_SECTOR_SIZE; i++)
|
||
{
|
||
IB_OFFSET = McuFlashAddr+i;
|
||
XPAGE = (McuFlashAddr+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<Length; i++)
|
||
{
|
||
*TargetAddr1 = CBYTE[SourceAddr+i];
|
||
TargetAddr1++;
|
||
}
|
||
McuFlashDis();
|
||
IrqEn();
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashWrWaitCheck
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 当需要写MCU Flash参数时,部分模块需要延时2S执行写操作(上位机修改参数),部分模块立即写
|
||
*************************************************************************************************/
|
||
void McuFlashWrWaitCheck(void)
|
||
{
|
||
if(bMcuFlashWrWaitFlg)
|
||
{
|
||
if(++bMcuFlashWrWaitCnt >= 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;
|
||
}
|
||
|