211 lines
5.7 KiB
C
211 lines
5.7 KiB
C
/********************************************************************************
|
||
Copyright (C), Sinowealth Electronic. Ltd.
|
||
Author: Sino
|
||
Version: V0.0
|
||
Date: 2020/04/26
|
||
History:
|
||
V2.0 2020/04/26 Preliminary
|
||
********************************************************************************/
|
||
#include "MCURegister.h"
|
||
#include "C51_TYPE.H"
|
||
#include "Flash.h"
|
||
#include <intrins.h>
|
||
#include <ABSACC.H>
|
||
|
||
U8 ucMcuFlashWrValid;
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashEraseSector
|
||
* 参 数: McuFlashAddr:起始地址;McuType:擦除CODE区或者EEPROM
|
||
* 返回值: 无
|
||
* 描 述: 擦除Sector
|
||
*************************************************************************************************/
|
||
void McuFlashEraseSector(U32 xdata McuFlashAddr, U8 xdata McuType)
|
||
{
|
||
FLASHCON = McuType;
|
||
XPAGE = McuFlashAddr>>8;
|
||
|
||
IB_CON1 = 0xE6;
|
||
if(!EA) //防止误写
|
||
{
|
||
IB_CON2 = 0x05;
|
||
if(FLASHCON == McuType) //防止误写
|
||
{
|
||
IB_CON3 = 0x0A;
|
||
if(ucMcuFlashWrValid == 0x55) //防止误写
|
||
{
|
||
IB_CON4 = 0x09;
|
||
if(XPAGE == (McuFlashAddr>>8)) //防止误写
|
||
{
|
||
IB_CON5 = 0x06;
|
||
_nop_();
|
||
_nop_();
|
||
_nop_();
|
||
_nop_();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
FLASHCON = MCU_TYPE_CODE;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashBlankCheck
|
||
* 参 数: McuFlashAddr:起始地址
|
||
* 返回值: 0:非全0,Erase失败;1:全0,Erase成功
|
||
* 描 述: 当Erase完1个Sector,需检查是否全为0
|
||
*************************************************************************************************/
|
||
BOOL McuFlashBlankCheck(U32 xdata McuFlashAddr, U8 xdata McuType)
|
||
{
|
||
BOOL Result = 1;
|
||
U16 i;
|
||
|
||
FLASHCON = McuType;
|
||
for(i=0; i<MCU_CODE_SECTOR_SIZE; i++)
|
||
{
|
||
if(CBYTE[McuFlashAddr+i] != 0x00)
|
||
{
|
||
Result = 0;
|
||
break;
|
||
}
|
||
}
|
||
FLASHCON = MCU_TYPE_CODE;
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashWrOneByte
|
||
* 参 数: McuFlashAddr:起始地址;WrData:写入的注释
|
||
* 返回值: 无
|
||
* 描 述: 写1个字节
|
||
*************************************************************************************************/
|
||
void McuFlashWrOneByte(U32 xdata McuFlashAddr, U8 xdata WrData, U8 xdata McuType)
|
||
{
|
||
FLASHCON = McuType;
|
||
XPAGE = McuFlashAddr>>8;
|
||
IB_OFFSET = McuFlashAddr % 256;
|
||
|
||
IB_DATA = WrData;
|
||
IB_CON1 = 0x6E;
|
||
if(!EA) //防止误写
|
||
{
|
||
IB_CON2 = 0x05;
|
||
if(FLASHCON == McuType) //防止误写
|
||
{
|
||
IB_CON3 = 0x0A;
|
||
if(ucMcuFlashWrValid == 0x55) //防止误写
|
||
{
|
||
IB_CON4 = 0x09;
|
||
if(XPAGE == (McuFlashAddr>>8)) //防止误写
|
||
{
|
||
IB_CON5 = 0x06;
|
||
_nop_();
|
||
_nop_();
|
||
_nop_();
|
||
_nop_();
|
||
_nop_();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
FLASHCON = MCU_TYPE_CODE;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: McuFlashRdOneByte
|
||
* 参 数: McuFlashAddr:读取CODE区的地址
|
||
* 返回值: 返回当前Code字节
|
||
* 描 述: 读1个字节
|
||
*************************************************************************************************/
|
||
U8 McuFlashRdOneByte(U32 xdata McuFlashAddr, U8 xdata McuType)
|
||
{
|
||
U8 GetData = 0;
|
||
|
||
FLASHCON = McuType;
|
||
GetData = CBYTE[McuFlashAddr];
|
||
FLASHCON = MCU_TYPE_CODE;
|
||
return GetData;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: BootProgram
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: Boot区进行升级代码操作:Erase->Program->Verify
|
||
每擦除1个Sector,即刻写入数据,校验数据
|
||
*************************************************************************************************/
|
||
U8 BootProgram(void)
|
||
{
|
||
U8 i, McuCode, McuFlashType;
|
||
U16 j;
|
||
U32 McuFlashAddr;
|
||
|
||
for(i=0; i<IAP_BK_CODE_SIZE/MCU_CODE_SECTOR_SIZE; i++) //擦除应用程序区,以Sector为单位
|
||
{
|
||
BootMcuWdtClear();
|
||
if(i < IAP_CODE_SIZE/MCU_CODE_SECTOR_SIZE) //当前更新CODE区29K
|
||
{
|
||
McuFlashType = MCU_TYPE_CODE; //IAP更新CODE区
|
||
McuFlashAddr = IAP_CODE_START_ADDR + (U16)i*MCU_CODE_SECTOR_SIZE; //从第5K开始
|
||
}
|
||
else
|
||
{
|
||
McuFlashType = MCU_TYPE_E2P; //IAP更新EEPROM区
|
||
McuFlashAddr = (U16)i*MCU_CODE_SECTOR_SIZE - IAP_CODE_SIZE;
|
||
}
|
||
ucMcuFlashWrValid = 0x55;
|
||
McuFlashEraseSector(McuFlashAddr, McuFlashType); //以字节为单位
|
||
if(McuFlashBlankCheck(McuFlashAddr, McuFlashType)) //擦除结束后,需要查空
|
||
{
|
||
for(j=0; j<MCU_CODE_SECTOR_SIZE; j++) //将数据搬入APP对应地址
|
||
{
|
||
McuCode = McuFlashRdOneByte(IAP_BK_CODE_START_ADDR+j+(U16)i*MCU_CODE_SECTOR_SIZE, MCU_TYPE_CODE); //yangweilei 此处固化为从flash取数据,从APP备份区读取CODE(1字节)
|
||
McuFlashWrOneByte(McuFlashAddr+j, McuCode, McuFlashType); //将CODE写入APP执行区
|
||
if(McuCode != McuFlashRdOneByte(McuFlashAddr+j, McuFlashType)) //校验写入的代码
|
||
{
|
||
return (BOOT_PGR_WR_ERR);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return (BOOT_PGR_ERASE_ERR);
|
||
}
|
||
}
|
||
|
||
return (BOOT_PGR_OK);
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: BootUpgradeCode
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: Boot区进行升级代码操作:Erase->Program->Verify
|
||
*************************************************************************************************/
|
||
BOOL BootUpgradeCode(void)
|
||
{
|
||
BOOL Result = 1;
|
||
|
||
if(BootProgram() == BOOT_PGR_OK)
|
||
{
|
||
McuFlashEraseSector(BOOT_FLG_START_ADDR, MCU_TYPE_CODE); //写入成功,擦除远程升级标志位
|
||
Result = McuFlashBlankCheck(BOOT_FLG_START_ADDR, MCU_TYPE_CODE); //擦除结束后,需要查空
|
||
}
|
||
else
|
||
{
|
||
Result = 0;
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|