用CFlashAmd对些DBAU1200开发板的BOOT FLASH

//========================================================================
//TITLE:
// DBAU1200开发板的BOOT FLASH读写
//AUTHOR:
// norains
//DATE:
// Saturday 31-May-2008
//Environment:
// VS2005 + DBAU1200 BOARD + MIPSII SDK
//========================================================================

WinCE的一个好处就是,能够在应用程序中访问物理内存。也正是在这个基础之上,才使我们在应用程序中能够更新boot flash。

为了使用上方便,已经将flash的读写操作封装为Class,在此先看代码:

//////////////////////////////////////////////////////////////////////
// Flash.h
//
//////////////////////////////////////////////////////////////////////
namespace Flash
{
//Flash information
struct FlashInfo
{
int Bank;
int Width;
unsigned long Size; //The size of the flash
unsigned long SectorSize; //The sector size, in bytes.
unsigned long BootSectorCount;
unsigned long BootSectorSize;
unsigned long WriteBufferSize;
};

//The information of the specified flash
const FlashInfo FLASH_INFO_AM29LV256M = {2,16,0x04000000,0x10000,0,0,(16 * (16 / 8))};
};

//////////////////////////////////////////////////////////////////////
// FlashAmd.h: interface for the CFlashAmd class.
//
//Version:
// 1.1.0
//
//Date:
// 2008.05.29
//
//Description:
//
//
//////////////////////////////////////////////////////////////////////


#pragma once

#include "Flash.h"


class CFlashAmd
{

public:
//Interface

//-------------------------------------------------------------------------------------------------------
//Description:
// Erase the flash
//
//Parameters:
// ulAddressOffset : [in] The offset address to erase
// ulSize : [in] The number of byte
// bCompletion : If true, the function would return after finish erasing,or it would return immediately.
//
//-------------------------------------------------------------------------------------------------------
virtual bool EraseFlash(unsigned long ulAddressOffset,unsigned long ulSize,bool bCompletion );


//-------------------------------------------------------------------------------------------------------
//Description:
// Lock the flash
//
//Parameters:
// ulAddressOffset : [in] The offset address to lock
// ulSize : [in] The number of byte to lock
//-------------------------------------------------------------------------------------------------------
virtual void LockFlash(unsigned long ulAddressOffset,unsigned long ulSize);

//-------------------------------------------------------------------------------------------------------
//Description:
// Unlock the flash
//
//Parameters:
// ulAddressOffset : [in] The offset address to unlock
// ulSize : [in] The number of byte to unlock
//-------------------------------------------------------------------------------------------------------
virtual void UnlockFlash(unsigned long ulAddressOffset,unsigned long ulSize);

//-------------------------------------------------------------------------------------------------------
//Description:
// Read the flash
//
//Parameters:
// ulAddressOffset : [in] The offset address to read
// pDataStore : [out] The buffer for storing the data.
// ulSize : [in] The size of the buffer
//-------------------------------------------------------------------------------------------------------
virtual bool ReadFlash(unsigned long ulAddressOffset,void *pDataStore,unsigned long ulSize);

//-------------------------------------------------------------------------------------------------------
//Description:
// Wait for finishing erasing
//
//Parameters:
// ulAddressOffset : [in] The offset address to wait
//-------------------------------------------------------------------------------------------------------
virtual bool WaitForEraseComplete(unsigned long ulAddressOffset);

//-------------------------------------------------------------------------------------------------------
//Description:
// Write the data to the flash
//
//Parameters:
// ulAddressOffset : [in] The offset address to write.
// pDataWrite : [in] The data buffer to write
// ulSize : [in] The source buffer length in bytes,must be multiple of 4
// bErase : [in] If true, it would erase the block before writing.
//-------------------------------------------------------------------------------------------------------
virtual bool WriteFlash(unsigned long ulAddressOffset,const void * pDataWrite,unsigned long ulSize,bool bErase);


//-------------------------------------------------------------------------------------------------------
//Description:
// Set the flash base address
//
//Parameters:
// dwAddress : [in] The base address to set
//-------------------------------------------------------------------------------------------------------
bool SetFlashAddressBase(unsigned long ulAddress);

//-------------------------------------------------------------------------------------------------------
//Description:
// Set the flash base address
//-------------------------------------------------------------------------------------------------------
unsigned long GetFlashAddressBase(void);

//-------------------------------------------------------------------------------------------------------
//Description:
// Set the flash information
//-------------------------------------------------------------------------------------------------------
bool SetFlashInfo(const Flash::FlashInfo & flashInfo);

//-------------------------------------------------------------------------------------------------------
//Description:
// Get the flash information
//-------------------------------------------------------------------------------------------------------
const Flash::FlashInfo& GetFlashInfo();


public:
CFlashAmd(void);
~CFlashAmd(void);


private:

//-------------------------------------------------------------------------------------------------------
//Description:
// Return the base address of a FLASH bank
//
//Parameters:
// iBank : [in] Bank number (zero based)
//
//Return Values:
// Base address of the FLASH bank
//
//-------------------------------------------------------------------------------------------------------
unsigned long GetBankBaseAddress(int iBank);

//-------------------------------------------------------------------------------------------------------
//Description:
// Returns the index of the FLASH bank containing the specified address
//
//Parameters:
// ulAddr : [in] FLASH Address
//
//Return Values:
// Index of the FLASH bank containing Address
//
//-------------------------------------------------------------------------------------------------------
int GetBankIndex(unsigned long ulAddr);


//-------------------------------------------------------------------------------------------------------
//Description:
// IssueFlashCommand RESET/UNLOCK/ERASE/.....
//
//Parameters:
// ulCommand : [in] command id
// ulParam1, ulParam2 : [in] Command Dependent:
// CMDRESET: ulParam1 - FLASH Bank
// ulParam2 - Ignore
// CMDUNLOCK: ulParam1 - FLASH Bank
// ulParam2 - Ignore
// CMDERASESET: ulParam1 - FLASH Bank
// ulParam2 - Ignore
// CMDERASESECTOR: ulParam1 - FLASH Bank
// ulParam2 - Sector
// CMDPROGRAM: ulParam1 - FLASH Bank
// ulParam2 - Ignore
// CMDWRITEBUFFER: ulParam1 - Program Location
// ulParam2 - Word Count - 1. Present twice in 32bit word
// CMDCOMMITBUFFER: ulParam1 - Program Location
// ulParam2 - Ignore
//
//Return Values:
// NONE
//
//-------------------------------------------------------------------------------------------------------
void IssueFlashCommand(unsigned long ulCommand, unsigned long ulParam1, unsigned long ulParam2);

//-------------------------------------------------------------------------------------------------------
//Description:
// Get the address of the specified sector
//
//Parameters:
// iBank : [in] Bank number (zero based)
// ulSector : [in] Sector number
//
//Return Values:
// Address of the sector
//
//-------------------------------------------------------------------------------------------------------
unsigned long GetSectorAddress(int iBank, unsigned long ulSector);

//-------------------------------------------------------------------------------------------------------
//Description:
// Return the size of sector, uses GetFlashInfo().Width to handle the case of two 16bit FLASH parts in parallel to form up a 32bit word.
//
//Parameters:
// ulSector - Sector number
//
//Return Values:
// Size in bytes of the sector including both parts
//
//-------------------------------------------------------------------------------------------------------
unsigned long GetSectorSize(unsigned long ulSector);

//-------------------------------------------------------------------------------------------------------
//Description:
// Returns the index of the FLASH bank and sector containing the specified address
//
//Parameters:
// ulAddress : [in] FLASH Address
// iBank : [out] The variable to receive the Bank containing Address
// ulSector : [out] The variable to receive the Sector containing Address
//
//Return Values:
// NONE
//
//-------------------------------------------------------------------------------------------------------
void GetBankAndSectorIndex(unsigned long ulAddress, int & iBank, unsigned long & ulSector);

//-------------------------------------------------------------------------------------------------------
//Description:
// Erases the specified sector and waits until sector is completely erased.
// Typical sector erase time varies from 0.7 seconds to 15 seconds.. See data sheet
//
//Parameters:
// BYTE bSector. Sector number to be erased .. 0 denotes SA0 and 70 denotes SA70
//
//Return Values:
// True to indicate that sector has been successfully erased and flash is ready for other operation
//
//-------------------------------------------------------------------------------------------------------
bool EraseSectorWithCompletion(int iBank, unsigned long ulSector, bool bCompletion);

//-------------------------------------------------------------------------------------------------------
//Description:
// Erases the specified sector
//
//Parameters:
// iBank : [in] Bank being worked on
// ulSector : [in] Sector number to be erased

//
//Return Values:
// True to indicate that erase command has been successfully erased
//
//-------------------------------------------------------------------------------------------------------
bool EraseSector(int iBank, unsigned long ulSector);

//-------------------------------------------------------------------------------------------------------
//Description:
// Get the status of operations(write/erase) on the flash
//
//Parameters:
// ulAddress : [in] Address of the flash to check status
//
//Return Values:
// STATUSREADY flash has completed an operation and is ready for new operation0
// STATUSERASESUSPEND .. flash erase has been suspended
// STATUSTIMEOUT Time out
// STATUSBUSY Busy
// STATUSERROR Error
//
//-------------------------------------------------------------------------------------------------------
unsigned long GetFlashStatus(unsigned long ulAddress);


//-------------------------------------------------------------------------------------------------------
//Description:
// Program an entire write buffers worth of data
//
//Parameters:
//
//
//Return Values:
//
//
//-------------------------------------------------------------------------------------------------------
bool WriteFlashBuffer(unsigned long ulAddress,const void * pSrcData, unsigned long ulByteCount);

//-------------------------------------------------------------------------------------------------------
//Description:
// Write the data to the flash address base on the flash width.
//-------------------------------------------------------------------------------------------------------
bool WriteFlash(unsigned long ulAddr, unsigned long ulValue);

//-------------------------------------------------------------------------------------------------------
//Description:
// Read the flash data from the address base on the flash width.
//-------------------------------------------------------------------------------------------------------
unsigned long ReadFlash(unsigned long ulAddr);


//-------------------------------------------------------------------------------------------------------
//Description:
// Write the flash which the width is 32bit
//-------------------------------------------------------------------------------------------------------
bool WriteFlash32(unsigned long ulAddr, unsigned long ulValue);

//-------------------------------------------------------------------------------------------------------
//Description:
// Read the flash which the width is 32bit
//-------------------------------------------------------------------------------------------------------
unsigned long ReadFlash32(unsigned long ulAddr);

//-------------------------------------------------------------------------------------------------------
//Description:
// Write the flash which the width is 16bit
//-------------------------------------------------------------------------------------------------------
bool WriteFlash16(unsigned long ulAddr, unsigned long ulValue);

//-------------------------------------------------------------------------------------------------------
//Description:
// Read the flash which the width is 16bit
//-------------------------------------------------------------------------------------------------------
unsigned short ReadFlash16(unsigned long ulAddr);

private:
unsigned long m_ulAddressBase;
Flash::FlashInfo m_FlashInfo;
};


//////////////////////////////////////////////////////////////////////
// FlashAmd.cpp
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FlashAmd.h"

//------------------------------------------------------------------------------------------------------
//Macro define


// AMD Specifics
#define LATCH_OFFSET1 (0x555 * (GetFlashInfo().Width / 8))
#define LATCH_OFFSET2 (0x2AA * (GetFlashInfo().Width / 8))
#define LATCH_UNLOCKBYPASS (0xBA * (GetFlashInfo().Width / 8))
#define AMD_UNLOCK1 0x00AA00AA
#define AMD_UNLOCK2 0x00550055

#define AMD_AUTOSELECT32 0x00900090
#define AMD_RESET32 0x00F000F0
#define AMD_ERASESET 0x00800080
#define AMD_ERASESECTOR 0x00300030
#define AMD_SUSPENDERASE 0x00B000B0
#define AMD_RESUMEERASE 0x00300030
#define AMD_PROGRAM 0x00A000A0
#define AMD_PROGRAMBUFFER 0x00250025
#define AMD_UNLOCKBYPASS 0x00200020
#define AMD_UNLOCKBYPASSPROGRAM 0x00A000A0
#define AMD_UNLOCKBYPASSRESET1 0x00900090
#define AMD_UNLOCKBYPASSRESET2 0x00000000
#define AMD_CHIPERASE 0x00100010
#define AMD_COMMITBUFFER 0x00290029


// defines for GetFlashStatus() function
#define STATUS_READY 0x00000000
#define STATUS_ERASESUSPEND 0x00040004 // DQ2
#define STATUS_TIMEOUTVALUE 0x00200020 // DQ5
#define STATUS_TOGGLEVALUE 0x00400040 // DQ6 - toggle bit one


//Flash status
enum FlashStatus
{
STATUSREADY = 100,
STATUSERASESUSPEND = 101,
STATUSTIMEOUT = 102,
STATUSBUSY = 103,
STATUSERROR = 104
};

// Flash Commands
enum FlashCommand
{
CMDRESET = 0x1000,
CMDUNLOCK = 0x1001,
CMDAUTOSELECT = 0x1002,
CMDERASESET = 0x1003,
CMDERASESECTOR = 0x1004,
CMDSUSPENDERASE = 0x1005,
CMDRESUMEERASE = 0x1006,
CMDPROGRAM = 0x1007,
CMDUNLOCKBYPASSSET = 0x1008,
CMDUNLOCKBYPASSRESET = 0x1009,
CMDCHIPERASE = 0x1010,
CMDREADIDCODES = 0x1011,
CMDCLEARSTATUS = 0x1012,
CMDREADSTATUS = 0x1013,
CMDWRITEWORD = 0x1014,
CMDWRITEBUFFER = 0x1015,
CMDCOMMITBUFFER = 0x1016
};
//------------------------------------------------------------------------------------------------------

CFlashAmd::CFlashAmd(void):
m_ulAddressBase(0)
{
}

CFlashAmd::~CFlashAmd(void)
{
}

bool CFlashAmd::EraseFlash(unsigned long ulAddressOffset,unsigned long ulSize,bool bCompletion )
{
unsigned long ulBeginAddr = GetFlashAddressBase() + ulAddressOffset;
if(ulBeginAddr + ulSize - 1 > GetFlashAddressBase() + GetFlashInfo().Size)
{
return false;
}

unsigned long ulEndAddr = ulBeginAddr + ulSize - 1;
unsigned long ulCurAddr = ulBeginAddr;

//
// erase the sectors in this range
//

for (int i = 0; i < GetFlashInfo().Bank; i ++)
{
IssueFlashCommand(CMDRESET, i, 0);
}


int iBank = 0;
unsigned long ulSector = 0;
do{
GetBankAndSectorIndex(ulCurAddr, iBank, ulSector);

EraseSectorWithCompletion(iBank, ulSector, bCompletion);

ulCurAddr += GetSectorSize(ulSector);

}
while (ulCurAddr < ulEndAddr);



// Verify Erase
for (unsigned i = 0;i < ulSize; i += 4)
{
unsigned long ulTemp = ReadFlash32(ulBeginAddr + i);
if (0xFFFFFFFF != ulTemp)
{
return false;
}
}


return true;

}

void CFlashAmd::LockFlash(unsigned long ulAddressOffset,unsigned long ulSize)
{
return ;
}

void CFlashAmd::UnlockFlash(unsigned long ulAddressOffset,unsigned long ulSize)
{
return ;
}

bool CFlashAmd::ReadFlash(unsigned long ulAddressOffset,void *pDataStore,unsigned long ulSize)
{
unsigned long ulAddrRead = ulAddressOffset + GetFlashAddressBase();;

int iBank = GetBankIndex(ulAddrRead);
IssueFlashCommand(CMDRESET, iBank, 0);

while (ulSize --)
{
(reinterpret_cast<unsigned char *> (pDataStore))[ulSize] = *(reinterpret_cast<unsigned char *>(ulAddrRead + ulSize));
}

return true;
}

bool CFlashAmd::WaitForEraseComplete(unsigned long ulAddressOffset)
{
unsigned long ulAddr = GetFlashAddressBase() + ulAddressOffset;

return (GetFlashStatus(ulAddr) != 0 );
}


bool CFlashAmd::WriteFlash(unsigned long ulAddressOffset,const void * pDataWrite,unsigned long ulSize,bool bErase)
{
unsigned long ulAddr = ulAddressOffset + GetFlashAddressBase();

bool bResult = true;

// Check parameters...
if (ulAddressOffset + ulSize - 1 > GetFlashInfo().Size)
{
return false;
}


// Round up to whole word
if (ulSize & 0x3)
{
ulSize += ulSize % 4;
}

int iBank = GetBankIndex(ulAddr);
IssueFlashCommand(CMDRESET, iBank, 0);


// Firstly check that is is erased
if (!bErase)
{
for (unsigned long i = 0; i < ulSize; i ++)
{
if (0xff != *(reinterpret_cast<unsigned char *>(ulAddr + i)))
{
bResult = FALSE;

goto EXIT;
}
}
}

if (bErase)
{
// Erase the area before write

EraseFlash(ulAddressOffset,ulSize,true);
}




// Get to next buffer boundary
const unsigned long * pulData = reinterpret_cast<const unsigned long *>(pDataWrite);
while (ulSize && (ulAddr & (GetFlashInfo().WriteBufferSize - 1)) && bResult)
{

bResult = WriteFlash32(ulAddr, *pulData);

ulSize -= 4;
ulAddr += 4;
pulData ++;
}

IssueFlashCommand(CMDRESET, iBank, 0);

// Round Size up to multiple of 4 bytes
ulSize = (ulSize+3) & ~0x3;

while (ulSize && bResult)
{
unsigned long ulCopySize;


// GetFlashInfo().WriteBufferSize specifies the number of bytes of write buffer
ulCopySize = min(ulSize, GetFlashInfo().WriteBufferSize);

bResult = WriteFlashBuffer(ulAddr, pulData, ulCopySize);

//Sleep(5);//norains.Maybe don't finish writing.

ulSize -= ulCopySize;
ulAddr += ulCopySize;
pulData = &pulData[ulCopySize / 4];
}


EXIT:

return bResult;
}

unsigned long CFlashAmd::GetBankBaseAddress(int iBank)
{
return GetFlashAddressBase() + ( ( GetFlashInfo().Size / GetFlashInfo().Bank) * iBank);

}



int CFlashAmd::GetBankIndex(unsigned long ulAddr)
{
int iBank;

for(iBank = GetFlashInfo().Bank - 1; iBank >= 0; iBank--)
{
if(ulAddr >= GetBankBaseAddress(iBank))
{
break;
}
}

return iBank;
}


void CFlashAmd::IssueFlashCommand(unsigned long ulCommand, unsigned long ulParam1, unsigned long ulParam2)
{
unsigned long ulAddr; // will hold address of the flash


switch (ulCommand)
{
case CMDRESET:
ulAddr = GetBankBaseAddress(ulParam1);
WriteFlash(ulAddr, AMD_RESET32); // Set the Device to Read Mode
break;

case CMDUNLOCK:
ulAddr = GetBankBaseAddress(ulParam1);
WriteFlash(ulAddr + LATCH_OFFSET1, AMD_UNLOCK1);
WriteFlash(ulAddr + LATCH_OFFSET2, AMD_UNLOCK2);
break;

case CMDERASESET:
ulAddr = GetBankBaseAddress(ulParam1);
WriteFlash(ulAddr + LATCH_OFFSET1, AMD_ERASESET);
break;

case CMDERASESECTOR:
ulAddr = GetSectorAddress(ulParam1,ulParam2);
WriteFlash(ulAddr, AMD_ERASESECTOR); // issue erase sector command
break;

case CMDPROGRAM:
ulAddr = GetBankBaseAddress(ulParam1);
WriteFlash(ulAddr + LATCH_OFFSET1, AMD_PROGRAM);
break;

case CMDWRITEBUFFER:
WriteFlash(ulParam1, AMD_PROGRAMBUFFER);
WriteFlash(ulParam1, ulParam2); // word count - 1
break;

case CMDCOMMITBUFFER:
WriteFlash(ulParam1, AMD_COMMITBUFFER);
break;

default:
break;
}
}



unsigned long CFlashAmd::GetSectorAddress(int iBank, unsigned long ulSector)
{
unsigned long ulSectorAddr;

ulSectorAddr = GetBankBaseAddress(iBank);

for (unsigned long i=0; i < ulSector; i ++)
{
ulSectorAddr += GetSectorSize(ulSector);
}

return ulSectorAddr;
}



unsigned long CFlashAmd::GetSectorSize(unsigned long ulSector)
{
unsigned long ulSectorSize;

if (ulSector < GetFlashInfo().BootSectorCount)
{
ulSectorSize = GetFlashInfo().BootSectorSize;
}
else
{
ulSectorSize = GetFlashInfo().SectorSize;
}

return ulSectorSize * (GetFlashInfo().Width / 16);
}



void CFlashAmd::GetBankAndSectorIndex(unsigned long ulAddress, int & iBank, unsigned long & ulSector)
{
//Reset
iBank = 0;
ulSector = 0;

// Find the Bank number first
for (iBank = GetFlashInfo().Bank - 1; iBank >= 0; iBank --)
{
if (ulAddress >= GetBankBaseAddress(iBank))
{
break;
}
}

// Now work out the sector number
while (ulAddress >= GetSectorAddress(iBank,ulSector))
{
ulSector ++;
}
ulSector --;


}



bool CFlashAmd::EraseSectorWithCompletion(int iBank, unsigned long ulSector, bool bCompletion)
{
unsigned long ulAddr = GetSectorAddress(iBank, ulSector);
EraseSector(iBank, ulSector);

unsigned long ulStatus;

if (bCompletion)
{

// wait until flash state machine is ready for other operation
ulStatus = GetFlashStatus(ulAddr);
}
else
{
ulStatus = STATUSREADY;
}

return (ulStatus == STATUSREADY);
}



bool CFlashAmd::EraseSector(int iBank, unsigned long ulSector)
{
IssueFlashCommand(CMDUNLOCK, iBank, 0); // issue unlock command // no data to write
IssueFlashCommand(CMDERASESET, iBank, 0); // // erase setup command
IssueFlashCommand(CMDUNLOCK, iBank, 0);
IssueFlashCommand(CMDERASESECTOR, iBank, ulSector); // issue erase sector command

return true;
}

unsigned long CFlashAmd::GetFlashStatus(unsigned long ulAddress)
{
unsigned long ulStatus;

int iBank = GetBankIndex(ulAddress);

// Two consecutive reads to check if bits are toggling
unsigned long ulOldRead = ReadFlash(ulAddress);
unsigned long ulNewRead = ReadFlash(ulAddress);

//The timeout value
unsigned long ulStatusTimeoutValue = STATUS_TIMEOUTVALUE;
if(GetFlashInfo().Width == 16)
{
ulStatusTimeoutValue &= 0xFFFF;
}

do {
// XOR to see if bits toggled

ulStatus = ulOldRead ^ ulNewRead;
if (0 == (ulStatus & STATUS_TOGGLEVALUE))
{
ulStatus = STATUSREADY;
break;
}


if ((ulNewRead & ulStatusTimeoutValue) == ulStatusTimeoutValue)
{

ulNewRead = ReadFlash(ulAddress);
ulOldRead = ReadFlash(ulAddress);

ulStatus = ulOldRead ^ ulNewRead;

if (0 == (ulStatus & STATUS_TOGGLEVALUE))
{
ulStatus = STATUSREADY;
break;
}


ulStatus = STATUSTIMEOUT;

IssueFlashCommand(CMDRESET,iBank,0);

break;
}

ulOldRead = ulNewRead;
ulNewRead = ReadFlash(ulAddress);


} while(true);

return ulStatus;
}



bool CFlashAmd::WriteFlashBuffer(unsigned long ulAddress,const void * pSrcData, unsigned long ulByteCount)
{
if ((ulByteCount & 3) || (0 == ulByteCount))
{
//Flash Write buffer requires a whole multiple of words
return false;
}

//
// issue Program Command
// The Write buffer is GetFlashInfo().width entries deep
// With 2 chips it is 32 bits wide
unsigned long ulSize = (ulByteCount / (GetFlashInfo().Width / 8));

int iBank = GetBankIndex(ulAddress);
IssueFlashCommand(CMDUNLOCK, iBank, 0);
IssueFlashCommand(CMDWRITEBUFFER, ulAddress, ulSize - 1 |((ulSize - 1) << 16));

while (ulSize--)
{
if(GetFlashInfo().Width == 16)
{
WriteFlash(ulAddress, *(reinterpret_cast<const unsigned short *>(pSrcData)));
}
else if(GetFlashInfo().Width == 32)
{
WriteFlash(ulAddress, *(reinterpret_cast<const unsigned long *>(pSrcData)));
}

ulAddress = ulAddress + (GetFlashInfo().Width / 8);

if(GetFlashInfo().Width == 16)
{
pSrcData = reinterpret_cast<const void *>(reinterpret_cast<const unsigned short *>(pSrcData) + 1);
}
else if(GetFlashInfo().Width == 32)
{
pSrcData = reinterpret_cast<const void *>(reinterpret_cast<const unsigned long *>(pSrcData) + 1 );
}

}

ulAddress = ulAddress - (GetFlashInfo().Width / 8);

IssueFlashCommand(CMDCOMMITBUFFER, ulAddress, 0);


// wait until flash is ready to accept new command
unsigned long ulStatus = GetFlashStatus(ulAddress);


return (ulStatus != STATUSTIMEOUT);
}



bool CFlashAmd::SetFlashAddressBase(unsigned long ulAddress)
{
m_ulAddressBase = ulAddress;
return true;
}

unsigned long CFlashAmd::GetFlashAddressBase(void)
{
return m_ulAddressBase;
}

bool CFlashAmd::SetFlashInfo(const Flash::FlashInfo & flashInfo)
{
m_FlashInfo = flashInfo;

return true;
}

const Flash::FlashInfo & CFlashAmd::GetFlashInfo(void)
{
return m_FlashInfo;
}




bool CFlashAmd::WriteFlash32(unsigned long ulAddr, unsigned long ulValue)
{

*(volatile unsigned long * const)(ulAddr) = (ulValue);
__asm("sync");

return (*(volatile unsigned long * const)(ulAddr) == (ulValue));
}


unsigned long CFlashAmd::ReadFlash32(unsigned long ulAddr)
{
return *(volatile unsigned long * const)(ulAddr);
}



bool CFlashAmd::WriteFlash16(unsigned long ulAddr, unsigned long ulValue)
{

*(volatile unsigned short * const)(ulAddr) = static_cast<unsigned short>( (ulValue) & 0xFFFF);
__asm("sync");

return (*(volatile unsigned short * const)(ulAddr) == static_cast<unsigned short>( (ulValue) & 0xFFFF));
}


unsigned short CFlashAmd::ReadFlash16(unsigned long ulAddr)
{
return *(volatile unsigned short * const)(ulAddr);
}


bool CFlashAmd::WriteFlash(unsigned long ulAddr, unsigned long ulValue)
{
switch(m_FlashInfo.Width)
{
case 16:
WriteFlash16(ulAddr,ulValue);
break;
case 32:
WriteFlash32(ulAddr,ulValue);
break;
default:
return false;
}

return true;
}

unsigned long CFlashAmd::ReadFlash(unsigned long ulAddr)
{
switch(m_FlashInfo.Width)
{
case 16:
return ReadFlash16(ulAddr);
break;
case 32:
return ReadFlash32(ulAddr); ;
default:
return 0;
}

}


CFlashAmd主要限制于DBAU1200的开发板,并且该板子上的FLASH型号为AM29LV256M。

如果条件具备,那么让我们看看如何烧写flash吧。

CFlashAmd flashAmd;
//设置flash型号
flashAmd.SetFlashInfo(Flash::FLASH_INFO_AM29LV256M);
//设置flash的起始地址。在开发板中,FLASH的起始地址为0xBC000000。
flashAmd.SetFlashAddressBase(0xBC000000);

...

//烧写FLASH。在这里注意的是,地址为偏移地址。该偏移地址是相对于之前通过SetFlashAddressBase所设置的地址。
flashAmd.WriteFlash(dwOffsetAddr,&vtStore[0],vtStore.size(),true);
阅读更多

没有更多推荐了,返回首页