fmd.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,511 行 · 第 1/4 页
CPP
1,511 行
pBaseAddress = (ULONG)NAND_DATA_PORT;
FlashLength = 0x2000000;
// Run in kernel mode.
bLastMode = SetKMode(TRUE);
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_RESET;
// Sleep(1); // check ready
///// mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
// Sleep(1);
mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
// Identify the flash part and collect device information.
//
SetKMode(bLastMode);
return ((PVOID)(pBaseAddress));
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_Deinit()
Description: De-initializes the Flash memory device.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_Deinit(PVOID pBaseAddress)
{
return(TRUE);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_GetInfo()
Description: Determines the size characteristics for the Flash memory device.
Notes: Notice that although each byte of a NOR Flash block is individually
addressable, the media is still logically broken up into sectors.
To compute the number of sectors per block, you have to divide the
total Flash block size by the number of bytes per sector and the number
bytes for the sector metadata.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
pFlashInfo->flashType = NAND;
//wzw test
pFlashInfo->dwNumBlocks = 8192;// 2048; //512; // 8192;//wzw size
// pFlashInfo->dwNumBlocks = 200;
pFlashInfo->dwBytesPerBlock = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);
pFlashInfo->wDataBytesPerSector = 2048 ;
pFlashInfo->wSectorsPerBlock = 64 ;
return(TRUE);
}
/*
* NAND_ReadSectorInfo
*
* Read SectorInfo out of the spare area. The current implementation only handles
* one sector at a time.
*/
void NAND_ReadSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
UCHAR addr1, addr2, addr3, wData,TEMP;
addr1 = (UCHAR) ((sectorAddr) & 0xff);
addr2 = (UCHAR) ((sectorAddr>> 8) & 0xff);
addr3 = (UCHAR) ((sectorAddr>> 16) & 0xff);
// Issue Read command, reading from the spare bits
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READ;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x08;
*((volatile ULONG *)(NAND_ADDR_PORT ))=(addr1);
*((volatile ULONG *)(NAND_ADDR_PORT ))=(addr2);
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr3;
*((volatile ULONG *)(NAND_CMD_PORT ))=0x30;
//*((volatile ULONG *)(NAND_ADDR_PORT ))=(addr3)&0xff;
// usWait(20);//wzw
mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 20);
// Sleep(1);
// mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
//Sleep(1); // check ready
// Read the SectorInfo data (we only need to read first 8 bytes)
// NOTE: The bytes are swapped because of Little Endian.
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // Bad block byte
pInfo->bBadBlock = (wData);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // First reserved field (DWORD)
pInfo->dwReserved1 = (wData);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pInfo->dwReserved1 |= (wData << 8);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pInfo->dwReserved1 |= (wData << 16);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pInfo->dwReserved1 |= (wData<<24);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // OEM byte
pInfo->bOEMReserved = (wData);
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // Second reserved field (WORD)
pInfo->wReserved2 = (wData );
wData = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pInfo->wReserved2 |= (wData << 8);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_ReadSector()
Description: Reads the requested sector data and/or sector metadata from the
Flash media.
Notes: Notice that although each byte of a NOR Flash block is individually
addressable, the media is still logically broken up into sectors.
Thus, for each sector request, we must determine where this data
resides in the respective Flash block (see note above).
By default, the NOR Flash is configured in READ ARRAY MODE so there
is no need to set any control lines to access the media. The data
can just be read directly from the media (like RAM).
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
UCHAR addr1, addr2, addr3, wData;
DWORD i,count;
BOOL bLastMode;
// ULONG startSectorAddr;//++
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_RESET;
//----- 1. Check the input parameters -----
// NOTE: The FAL insures that the starting sector address is in the allowable range.
/*if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
{
return(FALSE);
}*/
if (!pSectorBuff && !pSectorInfoBuff || dwNumSectors > 1) {
//RETAILMSG(1, (TEXT("Invalid parameters!\n")));
return FALSE;
}
//----- 2. Process the read request(s)... -----
bLastMode = SetKMode(TRUE);
// SetWriteProtect(FALSE);
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READ;
//Sleep(1);
for(i = 0; i < dwNumSectors; i++)
{
// Sleep(1); // check ready
if(!pSectorBuff) {
// We are reading spare only
// RETAILMSG(1, (TEXT("FMD_ReadSector1!\r\n")));
NAND_ReadSectorInfo(startSectorAddr, pSectorInfoBuff);
pSectorInfoBuff ++;
}
else{
// Reading data from the flash
addr1 = (UCHAR) ((startSectorAddr) & 0xff);
addr2 = (UCHAR) ((startSectorAddr>> 8) & 0xff);
addr3 = (UCHAR) ((startSectorAddr>> 16) & 0xff);
// Issue Read command
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READ;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr1;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr2;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr3;
*((volatile ULONG *)(NAND_CMD_PORT ))=0x30;
// usWait(20);//wzw
mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 20);
// Sleep(1);
// mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
//Sleep(1); // check ready
// Read only data portion of the sector.
for(i=0; i<0x800; i++)
{
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
// Copy the bytes directly into pSectorBuff
pSectorBuff[i] = wData;
}
// Read the SectorInfo data (we only need to read first 8 bytes)
// Read the SectorInfo data
if(pSectorInfoBuff)
{
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // Bad block byte
pSectorInfoBuff->bBadBlock = (wData);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // First reserved field (DWORD)
pSectorInfoBuff->dwReserved1 = (wData);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pSectorInfoBuff->dwReserved1 |= (wData << 8);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pSectorInfoBuff->dwReserved1 |= (wData << 16);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pSectorInfoBuff->dwReserved1 |= (wData << 24);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // OEM byte
pSectorInfoBuff->bOEMReserved = (wData);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); // Second reserved field (WORD)
pSectorInfoBuff->wReserved2 = (wData);
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
pSectorInfoBuff->wReserved2 |= (wData << 8);
pSectorInfoBuff ++;
}else
{
// Make sure we advance the Flash's read pointer (even though we don't need the SectorInfo data).
for(i=0; i<sizeof(SectorInfo); i++)
{
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
}
}
// Read the ECC info
for(i=0; i<8; i++)
{
wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
// Read out the ECC bits saved
ECC[i] = wData;
}
// Test the data integrity; if the data is invalid, attempt to fix it using ECC
if(!ECC_IsDataValid(pSectorBuff, 2048, ECC, 24))
{
RETAILMSG(1, (TEXT("FMD: Sector data (sector 0x%x) is invalid. Attempting ECC to fix it.\n"), startSectorAddr));
if(!ECC_CorrectData(pSectorBuff, 2048, ECC, 24))
{
// NOTE: this is specifically a debug message because sometimes it's valid to try to read from a sector in a good
// block which might contain bogus data (ECC fails) - example: loader code that needs to save/restore non-block-aligned
// data and we don't want a bunch of warnings in a retail build.
RETAILMSG(1, (TEXT("FMD: ERROR - Sector data (sector 0x%x) Unable to correct invalid data!\r\n"),startSectorAddr));
// return FALSE;
}else{
RETAILMSG(1, (TEXT("FMD: Invalid data was corrected using ECC!\r\n")));
}
}
pSectorBuff +=2048;
}
startSectorAddr ++;
}
SetKMode(bLastMode);
return(TRUE);
}
/*
* NAND_WriteSectorInfo
*
* Write SectorInfo out to the spare area. The current implementation only handles
* one sector at a time.
*/
BOOL NAND_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
UCHAR addr1, addr2, addr3, wData,status;
addr1 = (UCHAR) ((sectorAddr) & 0xff);
addr2 = (UCHAR) ((sectorAddr>> 8) & 0xff);
addr3 = (UCHAR) ((sectorAddr>> 16) & 0xff);
// *((volatile UCHAR *)(NAND_CMD_PORT ))=CMD_READ2;
//Sleep(1); // check ready
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
*((volatile ULONG *)(NAND_ADDR_PORT ))=0x08;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr1;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr2;
*((volatile ULONG *)(NAND_ADDR_PORT ))=addr3;
//Sleep(1); // check ready
// Since there is not any ECC information, we only need to write the SectorInfo data
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)(pInfo->bBadBlock); // Bad block byte
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->dwReserved1 & 0x000000FF)); // Reserved field 1
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->dwReserved1 & 0x0000FF00) >> 8);
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->dwReserved1 & 0x00FF0000) >> 16);
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->dwReserved1 & 0xFF000000) >> 24);
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)(pInfo->bOEMReserved); // OEM byte
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->wReserved2 & 0x00FF)); // Reserved field 2
*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pInfo->wReserved2 & 0xFF00) >> 8);
// Instruct the Flash to commit the data to the media
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE2;
// Check the status
status = GetStatus((DWORD) -1);
if(status & STATUS_ERROR) {
RETAILMSG(1, (TEXT("######## Error Programing page %d!\n"), sectorAddr));
//FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1); // disable chip
return FALSE;
}
//RETAILMSG(1, (TEXT("NAND_WriteSectorInfo dwReserved1 is %x bOEMReserved is %x bBadBlock is %x wReserved2 is %x\r\n"),pInfo->dwReserved1,pInfo->bOEMReserved,pInfo->bBadBlock,pInfo->wReserved2));
return TRUE;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_WriteSector()
Description: Writes the requested sector data and/or sector metadata to the
Flash media.
Notes: Notice that although each byte of a NOR Flash block is individually
addressable, the media is still logically broken up into sectors.
Thus, for each sector request, we must determine where to put the
data in each respective Flash block (see note above).
By default, the NOR Flash is configured in READ ARRAY MODE we need
to set some control lines to prepare for the WRITE operation.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
DWORD i,count;
UCHAR addr1, addr2, addr3, wData,status;
BOOL bLastMode = SetKMode(TRUE);
//----- 1. Check the input parameters -----
// NOTE: The FAL insures that the starting sector address is in the allowable range.
if((!pSectorBuff && !pSectorInfoBuff) || dwNumSectors == 0) {
RETAILMSG(1, (TEXT("Invalid parameters!\n")));
return FALSE;
}
//----- 2. Process the write request(s)... -----
bLastMode = SetKMode(TRUE);
//*((volatile UCHAR *)(NAND_CMD_PORT ))=CMD_READ;
for(i = 0; i < dwNumSectors; i++)
{
//Sleep(1); // check ready
if(!pSectorBuff) {
// If we are asked just to write the SectorInfo, we will do that separately
if(!NAND_WriteSectorInfo(startSectorAddr, pSectorInfoBuff)) {
return FALSE;
}
pSectorInfoBuff ++;
}
else{
// Reading data from the flash
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?