fmd.cpp

来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,511 行 · 第 1/4 页

CPP
1,511
字号
            addr1 = (UCHAR) ((startSectorAddr) & 0xff);
            addr2 = (UCHAR) ((startSectorAddr>> 8) & 0xff);
            addr3 = (UCHAR) ((startSectorAddr>> 16) & 0xff);
            //  Issue Read command 
	     	*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE;
            *((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;
      
			//Sleep(1);

	     	//  Read only data portion of the sector.
            for(i=0; i<0x800; i++)
            {            
                *((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR) pSectorBuff[i];
            }
			
			
            if(pSectorInfoBuff)
            {
            	//RETAILMSG(1, (TEXT("FMD_WriteSector4!\r\n")));
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)(pSectorInfoBuff->bBadBlock);                         // Bad block byte		
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->dwReserved1 & 0x000000FF)); 		// Reserved field 1 
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->dwReserved1 & 0x0000FF00) >> 8); 
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->dwReserved1 & 0x00FF0000) >> 16);
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->dwReserved1 & 0xFF000000) >> 24); 
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)(pSectorInfoBuff->bOEMReserved);                      // OEM byte
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->wReserved2 & 0x000000FF));
				*((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)((pSectorInfoBuff->wReserved2 & 0x0000FF00) >> 8);    // Reserved field 2
 
				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++)
                {
                  *((volatile ULONG *)(NAND_DATA_PORT ))=(UCHAR)(0xff);
                }
            }

			// Compute the ECC for this data (only 6 of the available 8 bytes are used)
            if(!ECC_ComputeECC(pSectorBuff, 2048, ECC, 24))
            {
                RETAILMSG(1, (TEXT("FMD: Unable to compute ECC(sector 0x%x) !!!\r\n"),startSectorAddr));
            }

            // Write the sector info and ECC into the spare area
            for(i=0; i<8; i++) {
               *((volatile ULONG *)(NAND_DATA_PORT ))= ECC[i];
            }
		 	*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE2;
		 	status = GetStatus((DWORD) -1);
            if(status & STATUS_ERROR) {
				RETAILMSG(1, (TEXT("######## Error Programing page %d!\n"), startSectorAddr));
                //FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
                return FALSE;
            }
			pSectorBuff += 2048;
	   	}

       startSectorAddr ++;
    }

	SetKMode(bLastMode);

    return (TRUE);
}


 //
//  IsBlockBad
//
//  Check to see if the given block is bad. A block is bad if the 517th byte on
//  the first or second page is not 0xff. 
//
//  blockID:    The block address. We need to convert this to page address
//
//


BOOL IsBlockBad(BLOCK_ID blockID)
{
    UCHAR  addr1, addr2, addr3, wData;
    DWORD  dwPageID = blockID*64;   //  Get the first page of the blcok
    BOOL bLastMode = SetKMode(TRUE);

//	RETAILMSG(1, (TEXT("IsBlockBad:blockID=0x%x \r\n"),blockID));
    addr1 = (UCHAR) ((dwPageID) & 0xff);
    addr2 = (UCHAR) ((dwPageID >> 8) & 0xff);
    addr3 = (UCHAR) ((dwPageID >> 16) & 0xff);

    //  For our NAND flash, we don't have to issue two read command. We just need
    //  to issue one read command and do contiquous read

    
    //  Check the first page.
    *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READ;
	//Sleep(1);
    *((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;
//    usWait(20);//wzw
	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 20);
//	Sleep(1);
//	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);

    //Sleep(1);
	//Sleep(1);    // check ready
    wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
	//RETAILMSG(1, (TEXT("wData:wData=0x%x \r\n"),wData));
    if(0xff != wData) {
        SetKMode (bLastMode);
		//RETAILMSG(1, (TEXT("IsBlockBad111:blockID=0x%x \r\n"),blockID));
        return TRUE;
    }

    //  Check the second page
 
   /* Sleep(1);    // check ready
    *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READ;
	Sleep(1);
    *((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=0x08;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=(addr1+0x7f);
	*((volatile ULONG *)(NAND_ADDR_PORT ))=addr2;
if(NEED_EXT_ADDR) {
                *((volatile ULONG *)(NAND_ADDR_PORT ))=addr3&0x07;
            }
*((volatile ULONG *)(NAND_CMD_PORT ))=0x30;
    Sleep(1);    // check ready

    wData =(UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
    if(0xff != wData) {
        SetKMode (bLastMode);
		//RETAILMSG(1, (TEXT("IsBlockBad222:blockID=0x%x \r\n"),blockID));
        return TRUE;
    }*/
//RETAILMSG(1, (TEXT("IsBlockBad333:blockID=0x%x \r\n"),blockID));
   
    SetKMode (bLastMode);
    return FALSE;
}

/* 
 *  MarkBlockBad
 *
 *  Mark the block as a bad block. We need to write a 00 to the 517th byte 
 */

BOOL MarkBlockBad(BLOCK_ID blockID)
{
    UCHAR  addr1, addr2, addr3, status;
    DWORD   dwStartPage = blockID*64;

	RETAILMSG(1, (TEXT("MarkBlockBad:blockID=0x%x \r\n"),blockID));
    //  We will try to write 00 to the 517th byte of the first page
    addr1 = (UCHAR) ( (dwStartPage) & 0xff );
    addr2 = (UCHAR) ( (dwStartPage >> 8) & 0xff );
    addr3 = (UCHAR) ( (dwStartPage >> 16) & 0xff );
   
    
    
      //First we set the pointer to point to the spare area
   // *((volatile UCHAR *)(NAND_CMD_PORT ))=CMD_READ2;

    //Sleep(1);    // check ready
      //Start writing to the first page of the block
    *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE;
    
   // Sleep(1);
    *((volatile ULONG *)(NAND_ADDR_PORT ))=0x00;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=0x08;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=addr1;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=addr2;
//if(NEED_EXT_ADDR) {
                *((volatile ULONG *)(NAND_ADDR_PORT ))=addr3;
           // }
   // Sleep(1);

     // Put a zero in the block valid address. 
    *((volatile ULONG *)(NAND_DATA_PORT ))=0x00;
    //  Close out the write.
   *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_WRITE2;

    //  Check the status
   status = GetStatus((DWORD) -1);
    if(status & STATUS_ERROR) {
        RETAILMSG(1, (TEXT("######## Failed to mark the block bad!\n")));
               return FALSE;
    }
 

        return TRUE;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_GetBlockStatus()

Description:    Returns the status of a block.  For read-only blocks, checks the sector 
        info data for the first sector of the block.  Block is always good, so no need to check.

Returns:        Block status.
------------------------------------------------------------------------------*/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
    
//RETAILMSG(1, (TEXT("FMD_GetBlockStatus:blockID=0x%x \r\n"),blockID));
     SECTOR_ADDR Sector = blockID * 64;
    SectorInfo SI;
    DWORD dwResult = 0;
    
    if (IsBlockBad (blockID))
    	{
    	//RETAILMSG(1, (TEXT("FMD_GetBlockStatus111:blockID=0x%x \r\n"),blockID));
        return BLOCK_STATUS_BAD;
		
    	}
    if (!FMD_ReadSector(Sector, NULL, &SI, 1)) 
    	{
    	//RETAILMSG(1, (TEXT("FMD_GetBlockStatus222:blockID=0x%x \r\n"),blockID));
	return BLOCK_STATUS_UNKNOWN;
	
    	}
    if (!(SI.bOEMReserved & OEM_BLOCK_READONLY))  
    	{
    	//RETAILMSG(1, (TEXT("FMD_GetBlockStatus333:blockID=0x%x \r\n"),blockID));
	dwResult |= BLOCK_STATUS_READONLY;
    	}
    if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))  
    	{
    	//RETAILMSG(1, (TEXT("FMD_GetBlockStatus444:blockID=0x%x \r\n"),blockID));
	dwResult |= BLOCK_STATUS_RESERVED;
    	}
      //RETAILMSG(1, (TEXT("FMD_GetBlockStatus555:blockID=0x%x  dwResult =%x\r\n"),blockID,dwResult));
    return dwResult;

}   

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_SetBlockStatus()

Description:    Sets the status of a block.  

Returns:        TRUE if no errors in setting.
------------------------------------------------------------------------------*/

BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
     RETAILMSG(1, (TEXT("FMD_SetBlockStatus:blockID=0x%x \r\n"),blockID));

       if (dwStatus & BLOCK_STATUS_BAD) {
        if (!MarkBlockBad (blockID))
            return FALSE;
       	}
    if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
        
        SECTOR_ADDR Sector = blockID *64;
        SectorInfo SI;

        if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
            return FALSE;
        }

        if (dwStatus & BLOCK_STATUS_READONLY) {
            SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
        }
        
        if (dwStatus & BLOCK_STATUS_RESERVED) {
            SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
        }

        if (!FMD_WriteSector (Sector, NULL, &SI, 1)) {
            return FALSE;
        }

    }    
    
    return TRUE;


	
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_EraseBlock()

Description:    Erases the specified Flash block.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_EraseBlock(BLOCK_ID blockID)
{
    ULONG blockPage = (blockID * 64);    // Convert block address to page address.
    ULONG ulStatus = 0;
   UCHAR  addr1, addr2, addr3, status;
    BOOL bLastMode = SetKMode(TRUE);

//    RETAILMSG(1, (TEXT("FMD_EraseBlock: blockID=0x%x \r\n"),blockID));
        
    addr1 = (UCHAR) ((blockPage) & 0xff);
    addr2 = (UCHAR) ((blockPage >> 8) & 0xff);
    addr3 = (UCHAR) ((blockPage >> 16) & 0xff);

    *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_ERASE;
    *((volatile ULONG *)(NAND_ADDR_PORT ))=addr1;
    *((volatile ULONG *)(NAND_ADDR_PORT ))=addr2;
	*((volatile ULONG *)(NAND_ADDR_PORT ))=addr3;
           
    //Sleep(1);    // check ready
     *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_ERASE2;
	 //Sleep(10);    // check ready
     status = GetStatus((DWORD) -1);

    if(status & STATUS_ERROR) {
        RETAILMSG(1, (TEXT("######## Error Erasing block %d!\n"), blockID));
        //FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
        return FALSE;
    }

  
    SetKMode(bLastMode);
    return(TRUE);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_PowerUp()

Description:    Restores power to the Flash memory device (if applicable).

Returns:        None.
------------------------------------------------------------------------------*/
VOID  FMD_PowerUp(VOID)  
{  
    return; 
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_PowerDown()

Description:    Suspends power to the Flash memory device (if applicable).

Returns:        None.
------------------------------------------------------------------------------*/
VOID  FMD_PowerDown(VOID)
{  
    return; 
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_OEMIoControl()

Description:    Implements user-defined (a.k.a. application specific) commands 
                for the Flash memory device

Returns:        None.
------------------------------------------------------------------------------*/
BOOL  FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, 
                       PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
    

    return(TRUE);
}



⌨️ 快捷键说明

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