rt-thread-official/bsp/wch/arm/ch579m/libraries/StdPeriphDriver/CH57x_flash.c

284 lines
9.2 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.

/********************************** (C) COPYRIGHT *******************************
* File Name : CH57x_flash.c
* Author : WCH
* Version : V1.1
* Date : 2020/03/20
* Description :
*******************************************************************************/
/******************************************************************************/
/* 头文件包含 */
#include "CH57x_common.h"
/* 操作Flash的保护状态标志 */
#define CODEFLASH_SAFE_FLAG1 0x57
#define CODEFLASH_SAFE_FLAG2 0xA8
/* 操作Flash的保护状态变量 */
unsigned char codeflash_access_flag1 = 0x0;
unsigned char codeflash_access_flag2 = 0x0;
/*******************************************************************************
* Function Name : GetUniqueID
* Description : 获取芯片唯一ID小端模式6B-ID 2B-CKS
* Input : buf: 存储8字节前6字节小端ID后2字节小端校验和
* Return : None
*******************************************************************************/
void GetUniqueID(PUINT8 buf)
{
PUINT8 pID;
UINT8 i;
pID = (PUINT8)ROM_UUID_ADDR;
for(i=0; i<8; i++) *buf++ = *pID++;
}
/*******************************************************************************
* Function Name : GetMACAddress
* Description : 获取网络MAC小端模式6B-MAC
* Input : buf: 存储6字节6字节小端物理 MAC
* Return : None
*******************************************************************************/
void GetMACAddress(PUINT8 buf)
{
PUINT8 pMAC;
UINT8 i;
pMAC = (PUINT8)ROM_MAC_ADDR;
for(i=0; i<6; i++) *buf++ = *pMAC++;
}
/*******************************************************************************
* Function Name : FlashBlockErase
* Description : Flash 块擦除一次擦除512B
* Input : addr: 32位地址需要512对齐
* codeflash: startAddr - 0x00000000 size - 0x3E800
* dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
* Return : 0 - 成功,其他 - 错误
*******************************************************************************/
UINT8 FlashBlockErase(UINT32 addr)
{
UINT8 status = 0;
volatile UINT8 op_step;
if( addr & (0x200-1) ) return 1; //地址不对齐
op_step = 0x11;
codeflash_access_flag1 = 0;
codeflash_access_flag2 = 0;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
//开启电压监控中断
op_step += 0x11;
if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
op_step += 0x11;
if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低Flash不允许操作
op_step += 0x11;
if(((R8_BAT_STATUS & 0x03) == 0x00)
&&(op_step == 0x44))
{
codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
}
op_step += 0x11;
if(((R8_BAT_STATUS & 0x03) == 0x00)
&&(op_step == 0x55)
&&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
{
codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
}
op_step += 0x11;
if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x66))
{
R32_FLASH_ADDR = addr;
if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
}
op_step += 0x11;
/* 判断操作Flash的保护状态标志 */
if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x77))
{
R8_FLASH_COMMAND = ROM_CMD_ERASE;
status = (unsigned char)(R16_FLASH_STATUS & 0xff);
}
op_step = 0x00;
codeflash_access_flag1 = 0x00;
codeflash_access_flag2 = 0x00;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10; // LOCK
if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
return 0;
}
/*******************************************************************************
* Function Name : FlashWriteDW
* Description : Flash 双字写地址需4字节对齐
* Input : addr: 32位地址需要4对齐
* codeflash: startAddr - 0x00000000 size - 0x3E800
* dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
dat: 32位写入数据
* Return : FAILED - 错误
SUCCESS - 成功
*******************************************************************************/
UINT8 FlashWriteDW(UINT32 addr, UINT32 dat)
{
UINT32 add = addr;
UINT32 val = dat;
UINT8 status = 0;
volatile UINT8 op_step;
if( addr & (4-1) ) return 1; //地址不对齐
op_step = 0x11;
codeflash_access_flag1 = 0;
codeflash_access_flag2 = 0;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
//开启电压监控中断
op_step += 0x11;
if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
op_step += 0x11;
if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低Flash不允许操作
op_step += 0x11;
if(((R8_BAT_STATUS & 0x01) == 0x00)
&&(op_step == 0x44))
{
codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
}
op_step += 0x11;
if(((R8_BAT_STATUS & 0x01) == 0x00)
&&(op_step == 0x55)
&&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
{
codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
}
op_step += 0x11;
if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x66))
{
if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
}
op_step += 0x11;
/* 判断OTA操作Flash的保护状态标志 */
if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x77))
{
R32_FLASH_ADDR = add;
R32_FLASH_DATA = val;
R8_FLASH_COMMAND = ROM_CMD_PROG;
status = (unsigned char)(R16_FLASH_STATUS & 0xff);
}
op_step = 0x00;
codeflash_access_flag1 = 0x00;
codeflash_access_flag2 = 0x00;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
return 0;
}
/*******************************************************************************
* Function Name : FlashWriteBuf
* Description : Flash 连续多个双字写入
* Input : addr: 32位地址需要4对齐
* codeflash: startAddr - 0x00000000 size - 0x3E800
* dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
* pdat: 待写入数据缓存区首地址
* len: 待写入数据字节长度
* Return : 0 - 成功,其他 - 错误
*******************************************************************************/
UINT8 FlashWriteBuf(UINT32 addr, PUINT32 pdat, UINT16 len)
{
UINT32 add = addr;
PUINT32 p32 = pdat;
UINT8 status = 0;
UINT16 i;
volatile UINT8 op_step;
if( addr & (4-1) ) return 1; //地址不对齐
op_step = 0x11;
codeflash_access_flag1 = 0;
codeflash_access_flag2 = 0;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
//开启电压监控中断
op_step += 0x11;
if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
op_step += 0x11;
if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低Flash不允许操作
op_step += 0x11;
if(((R8_BAT_STATUS & 0x01) == 0x00)
&&(op_step == 0x44))
{
codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
}
op_step += 0x11;
if(((R8_BAT_STATUS & 0x01) == 0x00)
&&(op_step == 0x55)
&&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
{
codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
}
op_step += 0x11;
if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x66))
{
if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
}
op_step += 0x11;
/* 判断OTA操作Flash的保护状态标志 */
if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
&&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
&&(op_step == 0x77))
{
for(i=0; i<len; i+=4)
{
R32_FLASH_ADDR = add;
R32_FLASH_DATA = *p32++;
R8_FLASH_COMMAND = ROM_CMD_PROG;
add += 4;
//status = R8_FLASH_STATUS;
status = (unsigned char)(R16_FLASH_STATUS & 0xff);
if( status != RB_ROM_ADDR_OK ) break;
}
}
op_step = 0x00;
codeflash_access_flag1 = 0x00;
codeflash_access_flag2 = 0x00;
R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
return 0;
}