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

📄 nandfmd.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            }
            
        }

        else if (pSectorInfoBuff != NULL)
        {
#ifndef NAND_LARGE_PAGE
            NF_CMD(CMD_READ2);                        // Send spare read command.
            NF_ADDR_COL(ColumnAddr);                  // Send column address
            NF_ADDR_PAGE(RowAddr);                    // Send page address
#else
            NF_CMD(CMD_READ);                         // Send read command
            NF_ADDR_COL(ColumnAddr + NAND_SECTOR_SIZE); // Send column address
            NF_ADDR_PAGE(RowAddr);                    // Send page address
            NF_CMD(CMD_READ_2CYCLE);                  // Send 2nd cycle read command
#endif

            // Read page data into NFC buffer
            NF_RD_SPARE();
            NFCReadSpare(pSectorInfoBuff);

            pSectorInfoBuff++;
        }

        ++SectorAddr;

        bSeqRead = NF_READ_SEQ(SectorAddr);
            
    }

    rc = TRUE;

cleanUp:
    NFCSetClock(FALSE);
    return rc;
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_EraseBlock
//
//  This function erases the specified flash block.
//
//  Parameters:
//      blockID 
//          [in] The block number to erase.
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
    UINT16 Status;
    UINT32 RowAddr = blockID * (NAND_SECTOR_CNT / NAND_SECTORS_PERPAGE);

    // RETAILMSG(TRUE, (_T("FMD_EraseBlock(block = %d, addr = 0x%x)\r\n"), blockID, addr));

    NFCSetClock(TRUE);

#ifndef NAND_LARGE_PAGE   
    NF_CMD(CMD_READ);           // Set address pointer to main area
#endif

    NF_CMD(CMD_ERASE);          // Send block erase setup command
    NF_ADDR_PAGE(RowAddr);      // Send page address
    NF_CMD(CMD_ERASE2);         // Send block erase command

    NF_CMD(CMD_STATUS)          // Send status command
    NF_RD_STATUS();             // Read status into NFC buffer
    Status = INREG16(&g_pNFC->MAIN[0][0]);     // Read status from NFC buffer
    
    NFCSetClock(FALSE);
        
    if (Status & NAND_STATUS_MASK_ERROR)
    {
        ERRORMSG(TRUE, (_T("NAND erase failed (blockID = 0x%x)\r\n"), blockID)); 
        return FALSE;
    }

    return TRUE;
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_WriteSector
//
//  This function writes the requested sector data and metadata to the 
//  flash media.
//
//  Parameters:
//      startSectorAddr 
//          [in] The starting physical sector address to write to.
//
//      pSectorBuff 
//          [in] Pointer to the buffer that contains the sector data to write. 
//          Set to NULL if no data is to be written.
//
//      pSectorInfoBuff 
//          [in] Buffer for an array of sector information structures. There 
//          must be one sector information entry for each sector that is to be 
//          written. Set to NULL if this data is not written.
//
//      dwNumSectors 
//          [in] Number of sectors to write.
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, 
    PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    UINT16 Status;
    SECTOR_ADDR SectorAddr = startSectorAddr;
    UINT32 ColumnAddr, RowAddr;
    BOOL rc = FALSE;

    NFCSetClock(TRUE);
    
    if (!pSectorBuff && !pSectorInfoBuff)
    {
        ERRORMSG(TRUE, (_T("Sector/Info buffers are NULL\r\n")));
        goto cleanUp;
    }

    while (dwNumSectors--)
    {
        RowAddr = (UINT32)SectorAddr/NAND_SECTORS_PERPAGE;
        ColumnAddr = ((UINT32)SectorAddr%NAND_SECTORS_PERPAGE)
                         * (NAND_SECTOR_SIZE + NAND_SPARE_SIZE);
    
        if (pSectorBuff)
        {
            if (pSectorInfoBuff)
            {
                // Update spare area with sector information provided
                NFCWriteSpare(pSectorInfoBuff);

                pSectorInfoBuff++;
            }
            else
            {
                // Clear out the spare area
                NFCClearSpare();
            }

            // Move page data from sector buffer to NFC buffer
            NFCWriteMain(pSectorBuff);

#ifndef NAND_LARGE_PAGE
            NF_CMD(CMD_READ);           // Set address pointer to main area
#endif
            NF_CMD(CMD_WRITE);          // Send sequential data input command
            NF_ADDR_COL(ColumnAddr);    // Send column address
            NF_ADDR_PAGE(RowAddr);      // Send page address

            NF_WR_PAGE();               // Write out the page data

            pSectorBuff += NAND_SECTOR_SIZE;  // Next sector
        }

        else
        {
            // Update spare area with sector information provided
            NFCWriteSpare(pSectorInfoBuff);

#ifndef NAND_LARGE_PAGE            
            NF_CMD(CMD_READ2);          // Set address pointer to spare area
            NF_CMD(CMD_WRITE);          // Send sequential data input command
            NF_ADDR_COL(ColumnAddr);    // Send column address
            NF_ADDR_PAGE(RowAddr);      // Send page address
#else
            NF_CMD(CMD_WRITE);          // Send sequential data input command
            NF_ADDR_COL(ColumnAddr + NAND_SECTOR_SIZE); // Send column address
            NF_ADDR_PAGE(RowAddr);      // Send page address
#endif

            NF_WR_SPARE();          // Write out the spare data

            pSectorInfoBuff++;
        }
            
        NF_CMD(CMD_WRITE2)          // Send program command
        
        NF_CMD(CMD_STATUS)          // Send status command
        NF_RD_STATUS();             // Read status into NFC buffer
        Status = INREG16(&g_pNFC->MAIN[0][0]);     // Read status from NFC buffer
        
        if (Status & NAND_STATUS_MASK_ERROR)
        {
            ERRORMSG(TRUE, (_T("NAND program failed (Sectoraddr = 0x%x)\r\n"), SectorAddr)); 
            goto cleanUp;
        }

        ++SectorAddr;
    }


    rc = TRUE;

cleanUp:
    NFCSetClock(FALSE);
    return  rc;
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_PowerUp
//
//  This function restores power to the flash memory device, if applicable.
//
//  Parameters:
//      None
//
//  Returns:  
//      None
//
//-----------------------------------------------------------------------------
VOID FMD_PowerUp(VOID)
{
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_PowerDown
//
//  This function suspends power to the flash memory device, if applicable.
//
//  Parameters:
//      None
//
//  Returns:  
//      None
//
//-----------------------------------------------------------------------------
VOID FMD_PowerDown(VOID)
{
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_OEMIoControl
//
//  This function implements user-defined commands for the flash memory device. 
//
//  Parameters:
//      dwIoControlCode 
//          [in] The control code specifying the command to execute.
//
//      pInBuf
//          [in] Long pointer to a buffer that contains the data required to 
//          perform the operation. Set to NULL if the dwIoControlCode parameter 
//          specifies an operation that does not require input data.
//                        
//      nInBufSize
//          [in] Size, in bytes, of the buffer pointed to by pInBuf. 
//
//      pOutBuf
//          [out] Long pointer to a buffer that receives the output data for 
//          the operation. Set to NULL if the dwIoControlCode parameter 
//          specifies an operation that does not produce output data.
//
//      nOutBufSize
//          [in] Size, in bytes, of the buffer pointed to by pOutBuf.
//
//      pBytesReturned
//          [out] Long pointer to a variable that receives the size, in bytes, 
//          of the data stored into the buffer pointed to by pOutBuf. Even 
//          when an operation produces no output data and pOutBuf is set to 
//          NULL, the DeviceIoControl function uses the variable pointed to 
//          by pBytesReturned. After such an operation, the value of the 
//          variable has no meaning. 
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, 
    PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
    BOOL rc = FALSE;

    return(rc);
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_GetInfo
//
//  This function determines the size characteristics for the flash memory 
//  device.
//
//  Parameters:
//      pFlashInfo 
//          [out] A pointer to a structure that contains the size 
//          characteristics for the flash memory device.
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{

    if (!pFlashInfo)
        return(FALSE);

    pFlashInfo->flashType           = NAND;
    pFlashInfo->wDataBytesPerSector = NAND_SECTOR_SIZE;
    pFlashInfo->dwNumBlocks         = NAND_BLOCK_CNT;
    pFlashInfo->wSectorsPerBlock    = NAND_SECTOR_CNT;
    pFlashInfo->dwBytesPerBlock     = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);

    return(TRUE);
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_GetBlockStatus
//
//  This function returns the status of a block.
//
//  Parameters:
//      blockID 
//          [in] The block number used to check status.
//
//  Returns:  
//      Flags to describe the status of the block.
//
//-----------------------------------------------------------------------------
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
    SECTOR_ADDR Sector = (blockID * NAND_SECTOR_CNT);
    SectorInfo SI[2];
    DWORD dwResult = 0;
    
    // Samsung makes sure that either the 1st or 2nd page of every initial 
    // invalid block has non-FFh data at the column address of 517.  Read
    // first two page spare areas and to determine block status.
    if (!FMD_ReadSector(Sector, NULL, SI, 2))
    {
        ERRORMSG(TRUE, (_T("NAND block %d status is unknown.\r\n"), blockID));
        dwResult = BLOCK_STATUS_UNKNOWN;
        goto cleanUp;
    }

    if ((SI[0].bBadBlock != 0xFF) || (SI[1].bBadBlock != 0xFF))
    {
        DEBUGMSG(TRUE, (_T("NAND block %d is bad.\r\n"), blockID));
        dwResult = BLOCK_STATUS_BAD;
        goto cleanUp;
    }

    if (!(SI[0].bOEMReserved & OEM_BLOCK_READONLY))  
        dwResult |= BLOCK_STATUS_READONLY;

    if (!(SI[0].bOEMReserved & OEM_BLOCK_RESERVED))  
        dwResult |= BLOCK_STATUS_RESERVED;

cleanUp:

    return(dwResult);
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_SetBlockStatus
//
//  This function sets the status of a block.
//
//  Parameters:
//      blockID 
//          [in] The block number used to set status. 
//
//      dwStatus
//          [in] The status value to set.
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    SECTOR_ADDR Sector = (blockID * NAND_SECTOR_CNT);
    SectorInfo SI;
    
    if (dwStatus & (BLOCK_STATUS_BAD | BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {        
        if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
            return FALSE;
        }

        if (dwStatus & BLOCK_STATUS_BAD)
        {
            SI.bBadBlock = 0x00;
        }
            
        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);
}

⌨️ 快捷键说明

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