⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 用于WSN的PDA搜救器
💻 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 + -