mirror of
https://github.com/armfly/H7-TOOL_STM32H7_App.git
synced 2024-08-09 10:05:34 +08:00
933 lines
27 KiB
C
933 lines
27 KiB
C
/*
|
||
*********************************************************************************************************
|
||
*
|
||
* 模块名称 : stm8系列flash访问程序
|
||
* 文件名称 : stm8_flash.c
|
||
* 版 本 : V1.0
|
||
* 说 明 : STM8 flash编程函数。根据STM8各个系列的固件库汇总而成。
|
||
* 修改记录 :
|
||
* 版本号 日期 作者 说明
|
||
* V1.0 2020-02-08 armfly 原创。
|
||
*
|
||
* Copyright (C), 2018-2030, 安富莱电子 www.armfly.com
|
||
*
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#include "bsp.h"
|
||
#include "DAP_config.h"
|
||
#include "stm8_swim.h"
|
||
#include "stm8_flash.h"
|
||
#include "stm8.h"
|
||
|
||
///* STM8S 寄存器定义 */
|
||
//#define STM8_FLASH_OPT 0x00004800
|
||
//#define STM8_FLASH_PUKR 0x00005062
|
||
//#define STM8_FLASH_DUKR 0x00005064
|
||
//#define STM8_FLASH_CR2 0x0000505B
|
||
//#define STM8_FLASH_IAPSR 0x0000505f
|
||
//#define STM8_FLASH_FPR 0x0000505D
|
||
//#define CLK_SWIMCCR 0x000050CD
|
||
//#define SWIM_CSR 0x00007F80
|
||
//#define DM_CSR2 0x00007F99
|
||
|
||
//#define STM8_FLASH_EOF 0x04
|
||
//#define STM8_FLASH_WR_PG_DIS 0x01
|
||
//#define STM8_FLASH_HVOFF 0x40
|
||
|
||
//#define PAGE_BLOCK_SIZE_64 64
|
||
//#define PAGE_BLOCK_SIZE_128 128
|
||
|
||
//static const uint8_t OPT_UNL[16] = {0x00,0x00,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0x55};
|
||
//static const uint8_t OPT_LCK[16] = {0xAA,0x00,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0x55};
|
||
|
||
|
||
|
||
uint16_t s_STM8_SerialType = 0; /* 0 = STM8S, 1 = STM8L */
|
||
uint16_t s_STM8_BlockSize = 64; /* 块大小,64或者128字节 */
|
||
uint16_t s_STM8_HVOFF = 0; /* 等待完成的标志选择 */
|
||
|
||
uint32_t s_STM8_FlashSize = 32 * 1024; /* FLASH 容量 */
|
||
uint32_t s_STM8_EEPromSize = 32 * 1024; /* EEPROM 容量 */
|
||
|
||
//#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) ||
|
||
// defined(STM8S005) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined(STM8AF626x)
|
||
// FLASH_FLAG_HVOFF = (uint8_t)0x40, /*!< End of high voltage flag */
|
||
//#endif /* STM8S208, STM8S207, STM8S105, STM8AF62Ax, STM8AF52Ax, STM8AF626x */
|
||
|
||
#define STM8_ERASE_BLOCK_TIMEOUT 100 /* 100ms */
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_WaitForLastOperation
|
||
* 功能说明: 等待内部写操作完成. STM8_FLASH_WaitForLastOperation(FLASH_MEMTYPE_PROG);
|
||
* 形 参: _uiTimeout : 超时时间,ms
|
||
* 返 回 值:
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_WaitForLastOperation(uint8_t FLASH_MemType, uint32_t _uiTimeout)
|
||
{
|
||
uint32_t re = 0;
|
||
int32_t s_time;
|
||
|
||
s_time = bsp_GetRunTime();
|
||
|
||
if (FLASH_MemType == FLASH_MEMTYPE_PROG)
|
||
{
|
||
while (1)
|
||
{
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
re = SWIM_ReadByte(STM8S_FLASH_IAPSR);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
re = SWIM_ReadByte(STM8L_FLASH_IAPSR);
|
||
}
|
||
|
||
if (re & (STM8_FLASH_IAPSR_EOP | STM8_FLASH_IAPSR_WR_PG_DIS))
|
||
{
|
||
re = 1;
|
||
break;
|
||
}
|
||
|
||
if (bsp_CheckRunTime(s_time) >= _uiTimeout)
|
||
{
|
||
re = 0;
|
||
break;
|
||
}
|
||
}
|
||
return re;
|
||
}
|
||
else if (FLASH_MemType == FLASH_MEMTYPE_DATA) /* EEPROM 的判断条件复杂些 */
|
||
{
|
||
while (1)
|
||
{
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
re = SWIM_ReadByte(STM8S_FLASH_IAPSR);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
re = SWIM_ReadByte(STM8L_FLASH_IAPSR);
|
||
}
|
||
|
||
if (s_STM8_HVOFF == 1)
|
||
{
|
||
if (re & (STM8_FLASH_IAPSR_HVOFF | STM8_FLASH_IAPSR_WR_PG_DIS))
|
||
{
|
||
re = 1;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (re & (STM8_FLASH_IAPSR_EOP | STM8_FLASH_IAPSR_WR_PG_DIS))
|
||
{
|
||
re = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (bsp_CheckRunTime(s_time) >= _uiTimeout)
|
||
{
|
||
re = 0;
|
||
break;
|
||
}
|
||
}
|
||
return re;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_WaitIAPSR_Flag
|
||
* 功能说明: 等待内部操作完成. 读STM8S_FLASH_IAPSR
|
||
* 形 参: _Flag : 判断标志位
|
||
* _BitValue : 0或1,表示返回的条件
|
||
* _uiTimeout : 超时时间,ms
|
||
* 返 回 值: 0 超时,1 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_WaitIAPSR_Flag(uint8_t _Flag, uint8_t _BitValue, uint32_t _uiTimeout)
|
||
{
|
||
uint8_t re = 0;
|
||
int32_t s_time;
|
||
|
||
s_time = bsp_GetRunTime();
|
||
|
||
while (1)
|
||
{
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
re = SWIM_ReadByte(STM8S_FLASH_IAPSR);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
re = SWIM_ReadByte(STM8L_FLASH_IAPSR);
|
||
}
|
||
|
||
if (_BitValue == 0)
|
||
{
|
||
if ((re & _Flag) == 0)
|
||
{
|
||
re = 1;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ((re & _Flag) == _Flag)
|
||
{
|
||
re = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
if (bsp_CheckRunTime(s_time) >= _uiTimeout)
|
||
{
|
||
re = 0;
|
||
break;
|
||
}
|
||
}
|
||
return re;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_Unlock
|
||
* 功能说明: 解锁允许写flash和eeprom。 STM8S、STM8L个系列均相同
|
||
* 形 参: FlashAddr : 地址
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void STM8_FLASH_Unlock(void)
|
||
{
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
/* Unlock program memory */
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, STM8_FLASH_RASS_KEY1);
|
||
// bsp_DelayUS(50);
|
||
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, STM8_FLASH_RASS_KEY2);
|
||
// bsp_DelayUS(50);
|
||
|
||
/* Unlock data memory */
|
||
/* Warning: keys are reversed on data memory !!! */
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, STM8_FLASH_RASS_KEY2);
|
||
// bsp_DelayUS(50);
|
||
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, STM8_FLASH_RASS_KEY1);
|
||
// bsp_DelayUS(50);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
/* Unlock program memory */
|
||
SWIM_WriteByte(STM8L_FLASH_PUKR, STM8_FLASH_RASS_KEY1);
|
||
// bsp_DelayUS(50);
|
||
|
||
SWIM_WriteByte(STM8L_FLASH_PUKR, STM8_FLASH_RASS_KEY2);
|
||
// bsp_DelayUS(50);
|
||
|
||
/* Unlock data memory */
|
||
/* Warning: keys are reversed on data memory !!! */
|
||
SWIM_WriteByte(STM8L_FLASH_DUKR, STM8_FLASH_RASS_KEY2);
|
||
// bsp_DelayUS(50);
|
||
|
||
SWIM_WriteByte(STM8L_FLASH_DUKR, STM8_FLASH_RASS_KEY1);
|
||
// bsp_DelayUS(50);
|
||
}
|
||
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_DUL | STM8_FLASH_IAPSR_PUL, 1, 20);
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_Lock
|
||
* 功能说明: Locks the program or data EEPROM memory
|
||
* 形 参: _FLASH_MemType : FLASH_MEMTYPE_PROG、FLASH_MEMTYPE_DATA
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void STM8_FLASH_Lock(uint32_t FlashAddr)
|
||
{
|
||
FLASH_MemType_TypeDef FLASH_MemType;
|
||
|
||
if (FlashAddr < 0x8000)
|
||
{
|
||
FLASH_MemType = FLASH_MEMTYPE_DATA;
|
||
}
|
||
else
|
||
{
|
||
FLASH_MemType = FLASH_MEMTYPE_PROG;
|
||
}
|
||
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
uint8_t iapsr;
|
||
|
||
iapsr = SWIM_ReadByte(STM8S_FLASH_IAPSR);
|
||
iapsr &= (uint8_t)FLASH_MemType;
|
||
|
||
/* Lock memory */
|
||
SWIM_WriteByte(STM8S_FLASH_IAPSR, iapsr);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
uint8_t iapsr;
|
||
|
||
iapsr = SWIM_ReadByte(STM8L_FLASH_IAPSR);
|
||
iapsr &= (uint8_t)FLASH_MemType;
|
||
|
||
/* Lock memory */
|
||
SWIM_WriteByte(STM8L_FLASH_IAPSR, iapsr);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_WriteReg_CR2
|
||
* 功能说明: 写CR2寄存器. 比如 STM8_WriteReg_CR2(STM8_FLASH_CR2_OPT)
|
||
* 形 参: _value : 0禁止, 1是使能
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void STM8_WriteReg_CR1(uint8_t _value)
|
||
{
|
||
uint8_t buf[1];
|
||
|
||
buf[0] = _value;
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
SWIM_WriteBuf(STM8S_FLASH_CR1, buf, 1);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
SWIM_WriteBuf(STM8L_FLASH_CR1, buf, 1);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_WriteReg_CR2
|
||
* 功能说明: 写CR2寄存器. 比如 STM8_WriteReg_CR2(STM8_FLASH_CR2_OPT)
|
||
* 形 参: _value : 0禁止, 1是使能
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void STM8_WriteReg_CR2(uint8_t _value)
|
||
{
|
||
uint8_t buf[2];
|
||
|
||
buf[0] = _value;
|
||
buf[1] = ~buf[0];
|
||
if (s_STM8_SerialType == STM8S)
|
||
{
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2);
|
||
}
|
||
else if (s_STM8_SerialType == STM8L)
|
||
{
|
||
SWIM_WriteBuf(STM8L_FLASH_CR2, buf, 1);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_EraseBlock
|
||
* 功能说明: Erases a block in the program or data memory.
|
||
* 形 参: FlashAddr : 绝对地址。 必须是block首地址
|
||
* FLASH_MemType : FLASH_MEMTYPE_PROG、FLASH_MEMTYPE_DATA
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void STM8_FLASH_EraseBlock(uint32_t FlashAddr)
|
||
{
|
||
uint32_t BlockAddr = 0;
|
||
const uint8_t zefo[4] = {0,0,0,0};
|
||
|
||
BlockAddr = (FlashAddr / s_STM8_BlockSize) * s_STM8_BlockSize;
|
||
|
||
/* Enable erase block mode */
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_ERASE);
|
||
|
||
SWIM_WriteBuf(BlockAddr, (uint8_t *)zefo, 4);
|
||
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 10);
|
||
|
||
// if (BlockAddr < 0x8000)
|
||
// {
|
||
// STM8_FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA, 100);
|
||
// }
|
||
// else
|
||
// {
|
||
// STM8_FLASH_WaitForLastOperation(FLASH_MEMTYPE_PROG, 100);
|
||
// }
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_ProgramBlock
|
||
* 功能说明: Programs a memory block
|
||
* 形 参: FlashAddr : 绝对地址。 必须是block首地址
|
||
* Buffer : Pointer to buffer containing source data.
|
||
* 返 回 值: 0:失败 1:成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_ProgramBlock(uint32_t FlashAddr, uint8_t *Buffer)
|
||
{
|
||
FLASH_MemType_TypeDef FLASH_MemType;
|
||
uint32_t BlockAddr = 0;
|
||
uint8_t re;
|
||
|
||
BlockAddr = (FlashAddr / s_STM8_BlockSize) * s_STM8_BlockSize;
|
||
if (BlockAddr < 0x8000)
|
||
{
|
||
FLASH_MemType = FLASH_MEMTYPE_DATA;
|
||
}
|
||
else
|
||
{
|
||
FLASH_MemType = FLASH_MEMTYPE_PROG;
|
||
}
|
||
|
||
if (s_STM8_SerialType == STM8L)
|
||
{
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_PRG);
|
||
}
|
||
else
|
||
{
|
||
STM8_WriteReg_CR1(STM8_FLASH_PROGRAMTIME_TPROG); /* 设置快速编程模式 */
|
||
bsp_DelayUS(100);
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_FPRG);
|
||
}
|
||
|
||
re = SWIM_WriteBuf(BlockAddr, Buffer, s_STM8_BlockSize);
|
||
if (re == 0) goto err_quit;
|
||
bsp_DelayUS(100);
|
||
|
||
#if 1
|
||
re = STM8_FLASH_WaitForLastOperation(FLASH_MemType, STM8_ERASE_BLOCK_TIMEOUT);
|
||
#else
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 20);
|
||
#endif
|
||
if (re == 0) goto err_quit;
|
||
|
||
return 1;
|
||
|
||
err_quit:
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_ProgramBuf
|
||
* 功能说明: Programs a memory block
|
||
* 形 参: _FlashAddr : 绝对地址。
|
||
* _Buff : Pointer to buffer containing source data.
|
||
* _Size : 数据大小,可以大于1个block
|
||
* 返 回 值: 0 : 出错; 1 : 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_ProgramBuf(uint32_t _FlashAddr, uint8_t *_Buff, uint32_t _Size)
|
||
{
|
||
uint32_t i;
|
||
uint32_t BlockAddr = 0;
|
||
uint8_t buf0[128]; /* 一般就是64或者128 */
|
||
uint8_t *pSrc;
|
||
uint32_t size;
|
||
uint8_t re = 0;
|
||
|
||
pSrc = _Buff;
|
||
|
||
/* 计算block首地址 */
|
||
BlockAddr = (_FlashAddr / s_STM8_BlockSize) * s_STM8_BlockSize;
|
||
|
||
/* 烧录第一个block */
|
||
if (BlockAddr != _FlashAddr)
|
||
{
|
||
uint16_t offset;
|
||
uint16_t len;
|
||
|
||
re = SWIM_ReadBuf(BlockAddr, buf0, s_STM8_BlockSize);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
if (CheckBlankBuf((char *)buf0, s_STM8_BlockSize, 0) == 0)
|
||
{
|
||
STM8_FLASH_EraseBlock(BlockAddr);
|
||
}
|
||
|
||
offset = _FlashAddr - BlockAddr;
|
||
|
||
if (offset + _Size < s_STM8_BlockSize)
|
||
{
|
||
len = _Size;
|
||
}
|
||
else
|
||
{
|
||
len = s_STM8_BlockSize - offset;
|
||
}
|
||
for (i = 0; i < len; i++)
|
||
{
|
||
buf0[i + offset] = *pSrc++;
|
||
|
||
_Size--;
|
||
|
||
_FlashAddr++;
|
||
}
|
||
|
||
re = STM8_FLASH_ProgramBlock(BlockAddr, buf0);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
}
|
||
|
||
/* 烧录中间block */
|
||
size = _Size;
|
||
for (i = 0; i < size / s_STM8_BlockSize; i++)
|
||
{
|
||
// re = SWIM_ReadBuf(BlockAddr, buf0, s_STM8_BlockSize);
|
||
// if (re == 0)
|
||
// {
|
||
// goto err_quit;
|
||
// }
|
||
//
|
||
// if (CheckBlankBuf((char *)buf0, s_STM8_BlockSize, 0) == 0)
|
||
// {
|
||
// STM8_FLASH_EraseBlock(BlockAddr);
|
||
// }
|
||
|
||
re = STM8_FLASH_ProgramBlock(_FlashAddr, pSrc);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
pSrc += s_STM8_BlockSize;
|
||
_Size -= s_STM8_BlockSize;
|
||
_FlashAddr += s_STM8_BlockSize;
|
||
}
|
||
|
||
/* 烧录最后一个block */
|
||
if (_Size > 0)
|
||
{
|
||
re = SWIM_ReadBuf(BlockAddr, buf0, s_STM8_BlockSize);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
if (CheckBlankBuf((char *)buf0, s_STM8_BlockSize, 0) == 0)
|
||
{
|
||
STM8_FLASH_EraseBlock(BlockAddr);
|
||
}
|
||
|
||
for (i = 0; i < _Size; i++)
|
||
{
|
||
buf0[i] = *pSrc++;
|
||
}
|
||
re = STM8_FLASH_ProgramBlock(_FlashAddr, buf0);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
}
|
||
|
||
return 1;
|
||
|
||
err_quit:
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_ProgramOptionBytes
|
||
* 功能说明: Programs option byte
|
||
* 形 参: _AddrBuf : 地址数组,大端模式排列.
|
||
* _AddrLen : _AddrLen
|
||
* _DataBuf : 输入数据
|
||
* _DataLen : 数据大小,可以大于1个block
|
||
* 返 回 值: 0 : 出错; 1 : 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_ProgramOptionBytes(uint8_t *_AddrBuf, uint16_t _AddrLen, uint8_t *_DataBuf, uint16_t _DataLen)
|
||
{
|
||
uint8_t re;
|
||
uint16_t Address;
|
||
uint16_t LastAddress;
|
||
uint8_t LastData;
|
||
|
||
if (_DataLen == 0 || _AddrLen == 0 || (_AddrLen % 2) != 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
while (_AddrLen)
|
||
{
|
||
STM8_FLASH_Unlock(); /* 允许写Flash和EEProm */
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_OPT); /* 编程OPT */
|
||
|
||
Address = BEBufToUint16(_AddrBuf);
|
||
_AddrBuf += 2;
|
||
|
||
bsp_DelayUS(200);
|
||
|
||
if (Address == 0xFFFF) /* 上一个字节取反写入 */
|
||
{
|
||
re = SWIM_WriteByte(LastAddress + 1, ~LastData);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
LastAddress = Address;
|
||
LastData = *_DataBuf;
|
||
|
||
re = SWIM_WriteByte(LastAddress, LastData);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
_DataBuf++;
|
||
}
|
||
|
||
_AddrLen -= 2;
|
||
|
||
/* STM8L151 实测寄存器变化 2A 2A 2A -> 4E 判断结束 */
|
||
bsp_DelayUS(500);
|
||
if (Address == 0x4800)
|
||
{
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 1000); /* 1000ms超时 */
|
||
}
|
||
else
|
||
{
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 50); /* 50ms超时 */
|
||
}
|
||
bsp_DelayUS(50);
|
||
STM8_WriteReg_CR2(0); /* 不确定是否需要这句话 解除编程操作*/
|
||
bsp_DelayUS(50);
|
||
}
|
||
|
||
return 1; /* 成功 */
|
||
err_quit:
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_EraseChip
|
||
* 功能说明: 擦除全片,FLASH (PROG). 事先需要unlock
|
||
* 形 参: FlashAddr : 绝对地址。 0x08000 或者 0x04000
|
||
* FLASH_MemType : FLASH_MEMTYPE_PROG、FLASH_MEMTYPE_DATA
|
||
* 返 回 值: 0 失败 1 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_EraseChip(uint32_t _FlashAddr)
|
||
{
|
||
#if 0
|
||
uint8_t value;
|
||
|
||
value = 0xAA;
|
||
STM8_ProgramOptionBytes(0x4800, &value, 1);
|
||
|
||
bsp_DelayUS(100);
|
||
|
||
SWIM_EntrySequence();
|
||
|
||
STM8_ProgramOptionBytes(0x4800, &value, 1);
|
||
|
||
bsp_DelayUS(100);
|
||
#else
|
||
uint32_t i;
|
||
const uint8_t zefo[4] = {0,0,0,0};
|
||
uint8_t re;
|
||
uint32_t FlashSize;
|
||
|
||
STM8_FLASH_Unlock();
|
||
if (_FlashAddr == 0x08000)
|
||
{
|
||
FlashSize = s_STM8_FlashSize;
|
||
}
|
||
else if (_FlashAddr == 0x04000)
|
||
{
|
||
FlashSize = s_STM8_EEPromSize;
|
||
}
|
||
else
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
for (i = 0; i < FlashSize / s_STM8_BlockSize; i++)
|
||
{
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_ERASE);
|
||
|
||
re = SWIM_WriteBuf(_FlashAddr, (uint8_t *)zefo, 4);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
re = STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 10);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
_FlashAddr += s_STM8_BlockSize;
|
||
}
|
||
|
||
return 1;
|
||
|
||
err_quit:
|
||
return 0;
|
||
#endif
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_EraseSector
|
||
* 功能说明: 擦除扇区
|
||
* 形 参: FlashAddr : 绝对地址。 0x08000 或者 0x04000
|
||
* FLASH_MemType : FLASH_MEMTYPE_PROG、FLASH_MEMTYPE_DATA
|
||
* 返 回 值: 0 失败 1 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_EraseSector(uint32_t _FlashAddr)
|
||
{
|
||
const uint8_t zefo[4] = {0,0,0,0};
|
||
uint8_t re;
|
||
|
||
STM8_FLASH_Unlock();
|
||
|
||
STM8_WriteReg_CR2(STM8_FLASH_CR2_ERASE);
|
||
|
||
re = SWIM_WriteBuf(_FlashAddr, (uint8_t *)zefo, 4);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
re = STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_EOP, 1, 10);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
return 1;
|
||
|
||
err_quit:
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_FLASH_ReadBuf
|
||
* 功能说明: 读flash
|
||
* 形 参: _FlashAddr : 绝对地址。
|
||
* _Buff : Pointer to buffer containing source data.
|
||
* _Size : 数据大小,可以大于1个block
|
||
* 返 回 值: 0 : 出错; 1 : 成功
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_FLASH_ReadBuf(uint32_t _FlashAddr, uint8_t *_Buff, uint32_t _Size)
|
||
{
|
||
uint32_t i;
|
||
uint8_t *pSrc;
|
||
uint32_t size;
|
||
uint8_t re = 0;
|
||
|
||
pSrc = _Buff;
|
||
|
||
size = _Size;
|
||
for (i = 0; i < size / s_STM8_BlockSize; i++)
|
||
{
|
||
re = SWIM_ReadBuf(_FlashAddr, pSrc, s_STM8_BlockSize);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
|
||
pSrc += s_STM8_BlockSize;
|
||
_Size -= s_STM8_BlockSize;
|
||
_FlashAddr += s_STM8_BlockSize;
|
||
}
|
||
|
||
if (_Size > 0)
|
||
{
|
||
re = SWIM_ReadBuf(_FlashAddr, pSrc, _Size);
|
||
if (re == 0)
|
||
{
|
||
goto err_quit;
|
||
}
|
||
}
|
||
|
||
return 1;
|
||
|
||
err_quit:
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: STM8_UnlockReadProtect
|
||
* 功能说明: 解除读保护. 逻辑分析仪跟踪ST-LINK解锁过程获得的数据。
|
||
* 形 参: 无
|
||
* 返 回 值: 1表示OK, 0表示出错
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t STM8_UnlockReadProtect(void)
|
||
{
|
||
uint8_t buf[8];
|
||
uint8_t re;
|
||
|
||
// SWIM_WriteByte(0x7F80, 0xB0); /* 切换到速模式 */
|
||
//
|
||
// g_HighSpeed = 1;
|
||
//
|
||
// bsp_DelayUS(400); /* 延迟400us */
|
||
//
|
||
// SWIM_WriteByte(0x7F80, 0xB4); /* */
|
||
//
|
||
// bsp_DelayUS(200); /* 延迟200us */
|
||
|
||
// SWIM_WriteByte(STM8_CLK_CKDIVR, 0x00); /* STM8_CLK_CKDIVR = 0x50C6 */
|
||
//
|
||
// SWIM_ReadBuf(0x4FFC, buf, 4); /* 返回 0x67 0x67 0x10 0x03 */
|
||
//
|
||
// bsp_DelayMS(5); /* 延迟5ms */
|
||
//
|
||
// SWIM_ReadByte(0x505F); /* 返回 0x80 */
|
||
|
||
|
||
re = SWIM_ReadByte(0x4800); /* 返回 0x71*/
|
||
if (re == 0)
|
||
|
||
bsp_DelayUS(500); /* 延迟500us */
|
||
|
||
// 42681
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, 0x56); /* STM8S_FLASH_PUKR = 0x5062 */
|
||
|
||
bsp_DelayUS(260); /* 延迟260us */
|
||
|
||
// 43058
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, 0xAE); /* STM8S_FLASH_PUKR = 0x5062 */
|
||
|
||
bsp_DelayUS(260); /* 延迟260us */
|
||
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, 0xAE); /* STM8S_FLASH_DUKR = 0x5064 */
|
||
bsp_DelayUS(260);
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, 0x56);
|
||
bsp_DelayUS(260);
|
||
|
||
|
||
//#define STM8_FLASH_IAPSR_HVOFF ((uint8_t)0x40) /*!< End of high voltage flag mask */
|
||
//#define STM8_FLASH_IAPSR_DUL ((uint8_t)0x08) /*!< Data EEPROM unlocked flag mask */
|
||
//#define STM8_FLASH_IAPSR_EOP ((uint8_t)0x04) /*!< End of operation flag mask */
|
||
//#define STM8_FLASH_IAPSR_PUL ((uint8_t)0x02) /*!< Flash Program memory unlocked flag mask */
|
||
//#define STM8_FLASH_IAPSR_WR_PG_DIS ((uint8_t)0x01) /*!< Write attempted to protected page mask */
|
||
SWIM_ReadByte(0x505F); /* 返回 0xCA 1100 1010 */
|
||
|
||
bsp_DelayUS(500);
|
||
|
||
buf[0] = STM8_FLASH_CR2_OPT; /* STM8_FLASH_CR2_OPT = 0x80 */
|
||
buf[1] = ~buf[0];
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2); /* STM8S_FLASH_CR2 = 0x505B */
|
||
|
||
SWIM_WriteByte(0x4800, 0);
|
||
|
||
// SWIM_ReadByte(0x505F); /* 返回 AB 1010 1011 STM8S_FLASH_IAPSR = 0x505F */
|
||
// SWIM_ReadByte(0x505F); /* 返回 AB 1010 1011 */
|
||
//
|
||
// SWIM_ReadByte(0x505F); /* 返回 AA 1010 1010 */
|
||
// SWIM_ReadByte(0x505F); /* 返回 AA 1010 1010 */
|
||
//
|
||
// // 48063
|
||
// SWIM_ReadByte(0x505F); /* 返回 4E 0100 1110 */
|
||
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_WR_PG_DIS | STM8_FLASH_IAPSR_EOP, 1, 50);
|
||
|
||
bsp_DelayUS(500);
|
||
buf[0] = 0x00;
|
||
buf[1] = 0xFF;
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2); /* STM8S_FLASH_CR2 = 0x505B */
|
||
|
||
// 50261
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, 0x56); /* STM8S_FLASH_PUKR = 0x5062 */
|
||
bsp_DelayUS(1500);
|
||
// 50661
|
||
SWIM_WriteByte(STM8S_FLASH_PUKR, 0xAE);
|
||
bsp_DelayUS(300);
|
||
//51072
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, 0xAE); /* STM8S_FLASH_DUKR = 0x5064 */
|
||
|
||
// 51432.US
|
||
SWIM_WriteByte(STM8S_FLASH_DUKR, 0x56);
|
||
|
||
bsp_DelayUS(200);
|
||
SWIM_ReadByte(0x505F); /* 返回 */
|
||
|
||
bsp_DelayUS(500);
|
||
buf[0] = STM8_FLASH_CR2_OPT; /* STM8_FLASH_CR2_OPT = 0x80 */
|
||
buf[1] = ~buf[0]; /* 7F */
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2); /* STM8S_FLASH_CR2 = 0x505B */
|
||
|
||
bsp_DelayUS(200);
|
||
SWIM_WriteByte(0x4801, 0x00);
|
||
// SWIM_ReadByte(0x505F); /* 返回 2A 0010 1010 */
|
||
// SWIM_ReadByte(0x505F); /* 返回 2A 0010 1010 */
|
||
// SWIM_ReadByte(0x505F); /* 返回 6A 0110 1010 */
|
||
// SWIM_ReadByte(0x505F); /* 返回 4E 0100 1110 */
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_WR_PG_DIS | STM8_FLASH_IAPSR_EOP, 1, 50);
|
||
|
||
// 56544
|
||
SWIM_WriteByte(0x4802, 0xFF);
|
||
// SWIM_ReadByte(0x505F); /* 返回 4E */
|
||
// SWIM_ReadByte(0x505F);
|
||
// SWIM_ReadByte(0x505F);
|
||
// SWIM_ReadByte(0x505F);
|
||
// SWIM_ReadByte(0x505F);
|
||
STM8_WaitIAPSR_Flag(STM8_FLASH_IAPSR_WR_PG_DIS | STM8_FLASH_IAPSR_EOP, 1, 50);
|
||
|
||
// 60.01877
|
||
buf[0] = 0x00;
|
||
buf[1] = ~buf[0];
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2); /* STM8S_FLASH_CR2 = 0x505B */
|
||
|
||
|
||
bsp_DelayUS(900);
|
||
|
||
|
||
//61129
|
||
SWIM_WriteByte(0x5062, 0x56);
|
||
bsp_DelayUS(200);
|
||
// 61526
|
||
SWIM_WriteByte(0x5062, 0xAE);
|
||
bsp_DelayUS(200);
|
||
// 61915
|
||
SWIM_WriteByte(0x5064, 0xAE);
|
||
bsp_DelayUS(200);
|
||
// 62217
|
||
SWIM_WriteByte(0x5064, 0x56);
|
||
bsp_DelayUS(200);
|
||
|
||
// 62527
|
||
SWIM_ReadByte(0x505F); /* 返回 4A 0100 1010 */
|
||
|
||
// 62992
|
||
bsp_DelayUS(500);
|
||
buf[0] = STM8_FLASH_CR2_OPT; /* STM8_FLASH_CR2_OPT = 0x80 */
|
||
buf[1] = ~buf[0]; /* 7F */
|
||
SWIM_WriteBuf(STM8S_FLASH_CR2, buf, 2); /* STM8S_FLASH_CR2 = 0x505B */
|
||
|
||
return 1;
|
||
}
|
||
|
||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|