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

📄 flash.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
*/
// ----------------------------------------------------------------
// File:     flash.c,v
// Revision: 1.0
// ----------------------------------------------------------------
// $
//

#include <windows.h>
#include <halether.h>
#include <platform.h>
#include <flash_lib.h>
#include <sizes.h>
#include <cdefs.h>
//#include <apcharlcd.h>

#include "eboot.h"

//
// Physical address of the NK image in RAM (when not in flash)
//  NOTE: This must match the config.bib settings
//
#define NK_RAM_BASE        0x00070000

//
// Download file cache used when flashing an image - use RAM image space. 
//  NOTE: Must match eboot.bib setting.
//
#define FCACHE             NK_RAM_BASE

//
// Intel 28F256L30 flash commands and status definitions.
//
#define PROGRAM_COMMAND    0x1010
#define PROGRAM_VERIFY     0xD0D0
#define READ_STATUS        0x7070
#define CLEAR_STATUS       0x5050
#define READ_ARRAY         0xFFFF
#define BLOCK_ERASE        0x2020
#define BLOCK_WRITE_MODE   0xE8E8
#define BLOCK_LOCK_SETUP   0x6060
#define BLOCK_LOCK         0x0101
#define BLOCK_UNLOCK       0xD0D0
#define CFI_QUERY_COMMAND  0x9898

#define STATUS_READY       0x0080
#define STATUS_LOCKED      0x0001
#define STATUS_LOCK_ERROR  0x0010
#define STATUS_ERASE_ERROR 0x0020

// Maximum flash write buffer in words
#define MAX_WRITE_BUFF     0x20

#define BLOCK_ERASE_STEP   3

//
// Helper macros.
//
#define TOTAL_FLASH_BLOCKS (ARMVPB_FLASH_SIZE / ARMVPB_FLASH_BLOCK_SIZE)
#define BLOCK_ADDR(i)      (PHYS_FLASH_BASE + (i * ARMVPB_FLASH_BLOCK_SIZE))
#define BLOCK_NUM(i)       ((i - PHYS_FLASH_BASE) / ARMVPB_FLASH_BLOCK_SIZE)

//
// Flash block variables used for block erasure.
//
ULONG gnStartBlock;
ULONG gnEndBlock;
ULONG gnBlocks;
ULONG gnBlockCount;

// Boot loader settings
extern BLDR_SETTINGS g_BldrSettings;

//
// Function prototypes.
//
void OEMWriteDebugByte(UCHAR ch);
int32 CFI_Lock_Bit_Set(unsigned16 *address);
int32 CFI_Lock_Bit_Clear(unsigned16 *address);
int32 CFI_Check_Status( volatile unsigned16 *vflash );


///////////////////////////////////////////////////////////////////
// Intel 28F256L30 Flash Routines
//

static int32 CFI_Check_Status( volatile unsigned16 *vflash )
{
    volatile unsigned16 s_reg;
    
    /* Check Status Register bit 7 for correct write */
    do
    {
        *vflash = READ_STATUS;
        s_reg = *vflash;
    } while ((s_reg  & STATUS_READY) != STATUS_READY);
 
    s_reg &= ~STATUS_READY;
    
    if( s_reg!=0 )
    {
        *vflash = CLEAR_STATUS;
    }
    *vflash=READ_ARRAY;
    
    if(s_reg!=0)
     return -1;
    else
     return 0;
}
    

static int32 CFI_Lock_Bit_Set( unsigned16 *address )
{
    int32 iRet = PASS;
    volatile unsigned16 *vflash = (volatile unsigned16*)address;

    /* Set block lock bit at block address */  
    *vflash = BLOCK_LOCK_SETUP;

    // Confirm Block lock bit at block address
    *vflash = BLOCK_LOCK;
   
    if (CFI_Check_Status(vflash)==-1) iRet = FAIL;

    /* Reset for Read operation */
    *vflash = READ_ARRAY; 
    
    return (iRet);
}

static int32 CFI_Lock_Bit_Clear( unsigned16 *address )
{
    int32 iRet = PASS;
    volatile unsigned16 *vflash = (volatile unsigned16*)address;

    /* Clear lock bits */
    *vflash = BLOCK_LOCK_SETUP;

    /* Confirm action */
    *vflash = BLOCK_UNLOCK;

    if (CFI_Check_Status(vflash)==-1) iRet = FAIL;

    /* Reset for Read operation */
    *vflash = READ_ARRAY; 
    
    return (iRet);
}


int32 CFI_Write_Word (unsigned16 *address, unsigned16 data)
{
    int32 iRet = PASS;
    volatile unsigned16 *vflash = (volatile unsigned16*)address;
   
    CFI_Lock_Bit_Clear( address );

    /* CFI routine for Intel is firstly issue program command 0x10 (word)
     * and address of data
     */
    *vflash = PROGRAM_COMMAND;
    
    /* Write required word to required address */
    *vflash = data;
    
    if (CFI_Check_Status(vflash)==-1) iRet = FAIL;
   
    CFI_Lock_Bit_Set( address );
     
    return(iRet);
}

int32 CFI_Write_Block(unsigned16 *address, unsigned16 *data, 
                      unsigned32 size)
{
    int32 iRet = PASS;
    volatile unsigned16 *vflash = (volatile unsigned16*)address;
    volatile unsigned16 s_reg;
    int n, nWords = 0;
    unsigned32 bytesWritten = 0, bytesLeft = size;
    
    if (0 != ((unsigned16)address & 0x1)) 
    {
        EdbgOutputDebugString("ERROR: CFI_Write_Block - address must fall on a block-aligned boundary (0x%x).\r\n", 
                (unsigned32)address);
        return(FAIL);
    }

    CFI_Lock_Bit_Clear( address );

    while ( bytesLeft > 0 && iRet == PASS) 
    {
        /* buffer available? */
        do
        {
            /* Start write to buffer */
            *vflash = BLOCK_WRITE_MODE;
            /* Read status */
            s_reg = *vflash;
            
        } while((s_reg & STATUS_READY) != STATUS_READY);

        /* Generate the number of words to write */
        /* Remember that size is in bytes so divide by 4 for word accesses */
        if ((bytesLeft / 2) < MAX_WRITE_BUFF)
        {
            nWords = (bytesLeft / 2);
        }
        else
        {
            nWords = MAX_WRITE_BUFF;
        }

        /* Write word count minus one (flash starts at word 0) */
        *vflash = ((nWords-1));

        /* Write data */
        for( n = nWords; n > 0; n-- )
        {
            *vflash++ = *data++;
        }

        // Show something to indicate progress...
        if (!(bytesWritten % 8192))
        {
            EdbgOutputDebugString("."); 
            OEMWriteDebugByte(0x20);    // Space
            OEMWriteDebugByte(0x8);     // Backspace
        }

        /* Confirm write  - using the address of the last word written
         *  This makes sure we confirm the write to the same block as we 
         *  wrote the data to.
         */
        *(vflash - 1) = PROGRAM_VERIFY;        

        s_reg = CFI_Check_Status(vflash);
        if( s_reg ==-1 ) 
        {
            EdbgOutputDebugString("FLASH ERROR: Block write failed (%08x). %d bytes written\r\n", s_reg, bytesWritten);
            iRet = FAIL;
        }
        
        /* Advance pointers - in bytes */
        bytesLeft -= (nWords * 2);
        bytesWritten += (nWords * 2);
        
        // Check for wrap round error
        if( bytesLeft > size )
        {
            EdbgOutputDebugString("FLASH ERROR: Too many bytes written. Size = %d, Written = %d\r\n", size, bytesWritten);
            iRet = FAIL;
        }
    }
    
//    EdbgOutputDebugString("Size: %d, Written: %d, left: %d\r\n", size, bytesWritten, bytesLeft); 
    EdbgOutputDebugString("\r\n"); 


    /* reset to read mode */
    *vflash = READ_ARRAY;            

    CFI_Lock_Bit_Set( address );

    return(iRet); 
}

int32 CFI_Read_Word  (unsigned16 *address, unsigned16 *value)  
{
    /* just read the address */
  
    *value = *address;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -