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

📄 nandfmd.c

📁 nand flash 测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            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(u32 blockID)
{
    u16 Status;
    u32 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;
}

static void FMD_WriteMain(u16_ptr pBuffer,/* u8_ptr pMain,*/ u16 pSize)
{
	u16 i;
	u16_ptr pMain ;
	pMain = (u16 *)(0xD8000000);
	for(i = 0; i < pSize; i++)
	{
		*pMain = *pBuffer ;
		pBuffer++ ; 
		pMain++ ;	
	}
	return;
}
//-----------------------------------------------------------------------------
//
//  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(u32 startSectorAddr, u16_ptr pSectorBuff, 
    PSectorInfo pSectorInfoBuff, u32 dwNumSectors)
{
    u16 Status;
    u32 SectorAddr = startSectorAddr;
    u32 ColumnAddr, RowAddr;
    BOOL rc = FALSE;

    NFCSetClock(TRUE);
    
    if (!pSectorBuff && !pSectorInfoBuff)
    {
        goto cleanUp;
    }

    while (dwNumSectors--)
    {
        RowAddr = (u32)SectorAddr/NAND_SECTORS_PERPAGE;
        ColumnAddr = ((u32)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);

			FMD_WriteMain(pSectorBuff,256);
#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
			pSectorBuff += NAND_SECTOR_SIZE/2;  // 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)
        {
            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(u32 dwIoControlCode, u8_ptr pInBuf, u32 nInBufSize, 
    u8_ptr pOutBuf, u32 nOutBufSize, u32_ptr pBytesReturned)
{
    BOOL rc = FALSE;

    return(rc);
}



//-----------------------------------------------------------------------------
//
//  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.
//
//-----------------------------------------------------------------------------
u32 FMD_GetBlockStatus(u32 blockID)
{
    u32 Sector = (blockID * NAND_SECTOR_CNT);
    SectorInfo SI[2];
    u32 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))
    {
        dwResult = BLOCK_STATUS_UNKNOWN;
        goto cleanUp;
    }

    if ((SI[0].bBadBlock != 0xFF) || (SI[1].bBadBlock != 0xFF))
    {
        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(u32 blockID, u32 dwStatus)
{
    u32 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 + -