rt-thread/bsp/essemi/es8p508x/libraries/Library/Source/lib_flashiap.c

356 lines
8.9 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.

/***************************************************************
*Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd
*文件名: lib_flashiap.c
*作 者: Liut
*版 本: V1.00
*日 期: 2017/07/14
*描 述: flash读写库函数
*备 注: 适用于 ES8P508x芯片
本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。
***************************************************************/
#include "lib_flashiap.h"
/***************************************************************
函数名FlashIap_Close_WPROT
描 述IAP关闭写保护
输入值Page:0-63,每page对应2K字节,64 为INFO区
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_Close_WPROT(uint8_t Page)
{
if(Page > 64)
return ERROR;
if(Page == 64)
{
IAP->WPROT2.Word = 0x00000000;
return SUCCESS;
}
if(Page < 32)
{
IAP->WPROT0.Word &=~ ((uint32_t)0x1 << Page);
}
else
{
Page -= 32;
IAP->WPROT1.Word &=~ ((uint32_t)0x1 << Page);
}
return SUCCESS;
}
/***************************************************************
函数名FlashIap_Open_WPROT
描 述IAP开启写保护
输入值Page:0-63,每page对应2K字节,,64 为INFO区
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_Open_WPROT(uint8_t Page)
{
if(Page > 64)
return ERROR;
if(Page == 64)
{
IAP->WPROT2.Word = 0x00000001;
return SUCCESS;
}
if(Page < 32)
{
IAP->WPROT0.Word &=~ ((uint32_t)0x1 << Page);
IAP->WPROT0.Word |= ((uint32_t)0x1 << Page);
}
else
{
Page -= 32;
IAP->WPROT1.Word &=~ ((uint32_t)0x1 << Page);
IAP->WPROT1.Word |= ((uint32_t)0x1 << Page);
}
return SUCCESS;
}
/***************************************************************
函数名FlashIap_CloseAll_WPROT
描 述IAP关闭所有写保护
输入值Page:0-63,每page对应2K字节
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_CloseAll_WPROT(void)
{
IAP->WPROT0.Word = 0x00000000;
IAP->WPROT1.Word = 0x00000000;
IAP->WPROT2.Word = 0x00000000;
return SUCCESS;
}
/***************************************************************
函数名FlashIap_OpenAll_WPROT
描 述IAP打开所有写保护
输入值:
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_OpenAll_WPROT(void)
{
IAP->WPROT0.Word = 0xFFFFFFFF;
IAP->WPROT1.Word = 0xFFFFFFFF;
IAP->WPROT2.Word = 0xFFFFFFFF;
return SUCCESS;
}
/***************************************************************
函数名FlashIap_Unlock
描 述IAP解锁与访问请求
输入值:无
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_Unlock(void)
{
uint16_t Temp16;
FlashIAP_RegUnLock(); //解锁 IAP
FlashIAP_Enable(); //使能IAP
FlashIAP_REQ(); //访问请求
for(Temp16 = 0; Temp16 < 0xFFFF; Temp16++) //等待FLASH应答信号
{
if(IAP->CON.FLASH_ACK != 0)
break;
}
if(Temp16 == 0xFFFF)
return ERROR;
else
return SUCCESS;
}
/***************************************************************
函数名FlashIap_WriteEnd
描 述IAP写结束
输入值:无
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_WriteEnd(void)
{
uint32_t Temp32;
FlashIAP_RegUnLock(); //IAP解锁
IAP->CON.Word &= 0xFFFFFFEE; //IAP访问FLASH请求(结束)
for(Temp32 = 0; Temp32 < 0xFFFF; Temp32++) //等待FLASH应答信号(结束)
{
if(IAP->CON.FLASH_ACK == 0)
break;
}
if(Temp32 == 0xFFFF)
return ERROR;
else
return SUCCESS;
}
/***************************************************************
函数名FlashIap_ErasePage
描 述IAP页擦除
输入值Page_Addr页地址
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_ErasePage(uint8_t Page_Addr)
{
uint16_t Temp16;
uint32_t temp;
temp = __get_PRIMASK(); //获取PRIMASK寄存器当前状态
__disable_irq(); //屏蔽所有中断
if(FlashIap_Unlock() == ERROR)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_CloseAll_WPROT() == ERROR)
{
__set_PRIMASK(temp);
return ERROR;
}
IAP->ADDR.IAPPA = Page_Addr; //输入页地址
IAP->TRIG.TRIG = 0x00005EA1; //输入编程命令
for(Temp16 = 0; Temp16 < 0xFFFF; Temp16++)
{ //判断IAP工作状态
if((IAP->STA.Word & (uint32_t)0x01) == (uint32_t)0x00)
break;
}
if(Temp16 == 0xFFFF)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
for(Temp16 = 0; Temp16 < 0xFFFF; Temp16++)
{
if((IAP->STA.Word & (uint32_t)0x02) == (uint32_t)0x02) //判断IAP页擦除标志
break;
}
if(Temp16 == 0xFFFF)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_WriteEnd() == ERROR)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_OpenAll_WPROT() == ERROR)
{
__set_PRIMASK(temp);
return ERROR;
}
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return SUCCESS;
}
/***************************************************************
函数名FlashIap_WriteCont
描 述IAP连续写
输入值Unit_addr单元地址 、 Page_addr页地址 、 Data32数据
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_WriteCont(uint8_t Unit_addr, uint8_t Page_addr, uint32_t Data32)
{
uint16_t temp16;
IAP->ADDR.IAPPA = Page_addr; //输入地址
IAP->ADDR.IAPCA = Unit_addr;
IAP->DATA.DATA = Data32; //输入数据
IAP->TRIG.TRIG = 0x00005DA2; //输入编程命令
for(temp16 = 0; temp16 < 0xFFFF; temp16++)
{
if((IAP->STA.Word & (uint32_t)0x01) == (uint32_t)0x00) //判断IAP工作状态
break;
}
if(temp16 == 0xFFFF)
return ERROR;
for(temp16 = 0; temp16 < 0xFFFF; temp16++)
{
if((IAP->STA.Word & 0x04)==0x04) //判断IAP编程结束标志
break;
}
if(temp16 == 0xFFFF)
return ERROR;
return SUCCESS;
}
/***************************************************************
函数名FlashIap_WriteWord
描 述IAP写一个字
输入值Unit_addr单元地址 、 Page_addr页地址 、 Data32数据
输出值:无
返回值:成功、失败
***************************************************************/
ErrorStatus FlashIap_WriteWord(uint8_t Unit_addr, uint8_t Page_addr, uint32_t Data32)
{
uint32_t temp;
temp = __get_PRIMASK(); //获取PRIMASK寄存器当前状态
__disable_irq(); //屏蔽所有中断
if(FlashIap_Unlock() == ERROR)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_CloseAll_WPROT() == ERROR)
{
__set_PRIMASK(temp); //关闭所有写保护状态
return ERROR;
}
if(FlashIap_WriteCont(Unit_addr, Page_addr, Data32) == ERROR)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_WriteEnd() == ERROR)
{
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return ERROR;
}
if(FlashIap_OpenAll_WPROT() == ERROR)
{
__set_PRIMASK(temp); //打开所有写保护状态
return ERROR;
}
__set_PRIMASK(temp); //恢复PRIMASK寄存器状态
return SUCCESS;
}
/***************************************************************
函数名Flash_Read
描 述Flash读数据
输入值Ram_Addr读出数据的存放地址 、 Flash_AddrFlash地址0x00000000 ~ 0x0001FFFF、 Len读取的字长度
输出值:读出的数据
返回值:成功、失败
***************************************************************/
ErrorStatus Flash_Read(uint32_t * Ram_Addr, uint32_t Flash_Addr, uint8_t Len)
{
uint8_t i;
uint32_t *ram_addr32;
const uint32_t *flash_addr32;
ram_addr32 = (uint32_t *)Ram_Addr;
flash_addr32 = (const uint32_t *)Flash_Addr;
if((Len == 0) & (Len>(0x20000 - Flash_Addr) / 4)) //判断读取长度是否合法
{
return ERROR;
}
for(i=0; i<Len; i++)
{
*ram_addr32 = *flash_addr32;
ram_addr32++;
flash_addr32++;
}
return SUCCESS;
}
/*************************END OF FILE**********************/