📄 flash.c
字号:
/* Description : flash functions.
*
* $Author: 王琢玉
* $Date: 2007/02/23
* $Name: flash.c
*/
#define FLASH_GLOBALS
#include "include.h"
/*******************************************************************************
MC13213拥有64k的flash资源,分为两部分,第一部分只有一页,468个字节,第二部分 115页,
每页大小为 512,由于MC13213的 code 在 flash 中,所以在使用flash时一定要慎重。0x8000后的
flash是可以用的。
flash 的擦写都是以页为单位的,所以要定义一个大小为 512 的buffer,为了节约资源,可以
和SCIBUFFER,RXBUFFER,TXBUFFER 公用一个空间,另外,由于MC13213的代码是在flash中的,而对
flash 进行擦写操作时,是无法读取代码的,所以需要将 flash 的擦写程序先拷贝到 RAM 中去。
因此还需要定义一个大小为 120 左右的 buffer 用来存放 flash 的擦写代码。也可以考虑和其他
buffer 合用。
同样,使用flash时,首先要初始化,这通过函数 void FlashInit(void) 实现。
*******************************************************************************/
//******************************************************************************
// Compilation options
//******************************************************************************
typedef void (*pFlashPageErase)(BYTE *);
typedef void (*pFlashPageWrite)(BYTE *,BYTE *);
// Uncomment VERIFY_WRITE if you would like a verification performed on program
// memory writes. Note that this option will also perform the CHECK_BEFORE_WRITE
// function. Be aware that if there is a problem with the device where it is
// unable to successfully perform the program memory write, and infinite loop will
// occur.
//#define VERIFY_WRITE
//******************************************************************************
// RAM and ROM Variables
//******************************************************************************
// Since we are using non-volatile memory for storage with no hardcoded
// memory address, it is possible that these memory regions may be
// placed inbetween executable code. In that case when we update this
// memory, we would erase part of executable code.
// To avoid that there are two ERASE_BLOCK_SIZE filler block around the storage.
// This will make sure that we are well away from executable code.
//******************************************************************************
// Macros
//******************************************************************************
void FlashInit(void)
{
FSTAT = 0x30;
FCDIV = 0x27;
}
void FlashCopyToRam(BYTE *dest, BYTE *src, UINT16 count)
{
while(count --)
{
*dest++ = *src++;
}
}
void FlashPageErase(BYTE *Addr)
{
SaveStatusReg();
FSTAT=0x00; /* Init. flash engine */
if(FSTAT & BM_FLASH_ERR_MASK) /* Protection violation or access error */
{
FSTAT = BM_FLASH_ERR_MASK; /* Clear FPVIOL & FACERR flag */
}
*Addr = 0x00;
FCMD = FCMD_PAGE_ERASE; /* 页擦除*/
FSTAT = 0x80; /* Launch the command */
if(!(FSTAT & BM_FLASH_ERR_MASK)) /* Protection violation or access error detected ? */
{
while(!FSTAT_FCCF); /* Wait to command complete */
}
RestoreStatusReg();
}
void FlashPageWrite(BYTE *dest, BYTE *src)
{
UINT16 i;
dest = (BYTE*)((UINT16)dest & (UINT16)(~(ERASE_BLOCK_SIZE-1)));
FSTAT=0x00; /* Init. flash engine */
if(FSTAT & BM_FLASH_ERR_MASK) /* Protection violation or access error */
{
FSTAT = BM_FLASH_ERR_MASK; /* Clear FPVIOL & FACERR flag */
}
SaveStatusReg();
for(i = ERASE_BLOCK_SIZE; i > 0; i--)
{
*dest++ = *src++;
FCMD = FCMD_BURST_PROGRAM; /* Initiate burst write command */
FSTAT = 0x80; /* Launch the command */
if(FSTAT & BM_FLASH_ERR_MASK) /* Error detected? */
{
return; /* Yes, return */
}
while(!FSTAT_FCCF);
}
RestoreStatusReg();
}
/*********************************************************************
* Function: void NVMWrite(NVM_ADDR *dest, BYTE *src, BYTE count)
*
* PreCondition: None
*
* Input: *dest - pointer to the location in ROM where the first
* source byte is to be stored
* *src - pointer to the location in RAM of the first
* byte to be written to ROM
* count - the number of bytes to be written
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine writes the specified number of bytes
* into program memory.
*
* Note: Some devices have a limited number of write cycles.
* When using these devices, ensure that the number
* of write cycles over the lifetime of the application
* will not exceed the specification. It is also
* recommended that the CHECK_BEFORE_WRITE option is
* enabled to further reduce the number of write cycles.
********************************************************************/
void FlashWriteNbyte(BYTE *dest, BYTE *src, UINT16 count)
{
// BYTE *memBlock; // 在ram中分配一个block
BYTE *pMemPage;
BYTE *pErasePage; // 块的起始地址
// BYTE TempPage[ERASE_BLOCK_SIZE];
UINT16 writeStart;
// if((RamFunc = MemoryAlloc( CodeSize )) == NULL) return;
pErasePage = (BYTE*)((UINT16)dest & (UINT16)(~(ERASE_BLOCK_SIZE-1)));
writeStart = (UINT16)((UINT16)dest & (UINT16)(ERASE_BLOCK_SIZE-1));
while( count )
{
CLRWDT();
FlashCopyToRam(TempPage, pErasePage, ERASE_BLOCK_SIZE);
FlashCopyToRam(RamFunc, FlashPageErase, CodeSize);
((pFlashPageErase)&RamFunc)(pErasePage);
pMemPage = &TempPage[writeStart];
while((writeStart < ERASE_BLOCK_SIZE) && count )
{
*pMemPage++ = *src++;
count--;
writeStart++;
}
CLRWDT();
// After first block write, next start would start from 0.
writeStart = 0;
pMemPage = TempPage;
FlashCopyToRam(RamFunc, FlashPageWrite, CodeSize);
((pFlashPageWrite)&RamFunc)(pErasePage,pMemPage);
CLRWDT();
pErasePage += ERASE_BLOCK_SIZE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -