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

📄 nandfmd.c

📁 nand flash 测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-2007, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
#include "basetype.h"
#include "inc.h"
#include "mx27_nandfc.h"
#include "nandfmd.h"
#include <string.h>

//-----------------------------------------------------------------------------
// External Functions

extern BOOL NFCAlloc(void);
extern void NFCWait(BOOL bPoll);
extern BOOL NFCSetClock(BOOL bEnabled);
extern BOOL NFCSetPagesize(BOOL bLargePage);

#define __JIA__
//-----------------------------------------------------------------------------
// External Variables


//-----------------------------------------------------------------------------
// Defines


//-----------------------------------------------------------------------------
// Types




//-----------------------------------------------------------------------------
// Local Variables
static u16 g_NandDeviceID;


//-----------------------------------------------------------------------------
// Local Functions



//-----------------------------------------------------------------------------
//
//  Function: NFCReadSpare
//
//  This function reads the NAND flash controller spare area and provides this
//  information to the upper FMD layers.
//
//  Parameters:
//      pSectorInfoBuff 
//          [out] Buffer containing sector information read.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void NFCReadSpare(PSectorInfo pSectorInfoBuff)
{
    pSectorInfoBuff->dwReserved1 = INREG32((u32 *) &g_pNFC->SPARE[0][0]);
    *((u16 *) (&pSectorInfoBuff->bOEMReserved)) = INREG16(&g_pNFC->SPARE[0][2]);
    pSectorInfoBuff->wReserved2 = INREG16(&g_pNFC->SPARE[0][7]);
}
//-----------------------------------------------------------------------------
//
//  Function: NFCWriteSpare
//
//  This function writes the spare data provided by the upper FMD layers
//  to the NAND flash controller spare area.
//
//  Parameters:
//      pSectorInfoBuff 
//          [in] Buffer containing sector information to be written.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void NFCWriteSpare(PSectorInfo pSectorInfoBuff)
{
    OUTREG32((u32 *) &g_pNFC->SPARE[0][0], pSectorInfoBuff->dwReserved1);
    OUTREG16(&g_pNFC->SPARE[0][2], *((u16 *) (&pSectorInfoBuff->bOEMReserved)));
    OUTREG16(&g_pNFC->SPARE[0][3], 0xFFFF);
    OUTREG32((u32 *) &g_pNFC->SPARE[0][4], 0xFFFFFFFF);
    OUTREG16(&g_pNFC->SPARE[0][6], 0xFFFF);
    OUTREG16(&g_pNFC->SPARE[0][7], pSectorInfoBuff->wReserved2);
}

//-----------------------------------------------------------------------------
//
//  Function: NFCClearSpare
//
//  This function clears the NAND flash controller spare area (all
//  ones written to the spare area will prevent the spare area of
//  the NAND memory device from being updated since only zeros are
//  written during a NAND program cycle).
//
//  Parameters:
//      None.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void NFCClearSpare(void)
{
    u32 *dest = (u32 *) &g_pNFC->SPARE[0];

    OUTREG32(&dest[0], 0xFFFFFFFF);
    OUTREG32(&dest[1], 0xFFFFFFFF);
    OUTREG32(&dest[2], 0xFFFFFFFF);
    OUTREG32(&dest[3], 0xFFFFFFFF);
}

BOOL NFCAlloc(void)
{
    // Map peripheral physical address to virtual address
//    g_pNFC = (PCSP_NANDFC_REGS) OALPAtoUA(CSP_BASE_REG_PA_NANDFC);
	g_pNFC = (volatile PCSP_NANDFC_REGS)(CSP_BASE_REG_PA_NANDFC);


    return TRUE;   
}
//-----------------------------------------------------------------------------
//
//  Function: FMD_Init
//
//  This function initializes the flash memory of a device.
//
//  Parameters:
//      lpActiveReg
//          [in] Pointer to the active registry string used to find device 
//          information from the registry. Set to NULL if not needed. 
//
//      pRegIn
//          [in] Pointer to a PCI_REG_INFO structure. Used to find flash 
//          hardware on PCI hardware. Set to NULL if not needed.
//
//      pRegOut
//          [in/out] Pointer to a PCI_REG_INFO structure. Used to return 
//          flash information. Set to NULL if not needed.
//
//  Returns:
//      A handle that can be used in a call to FMD_Deinit. It is the 
//      responsibility of the specific flash media driver (FMD) implementation 
//      to determine what this value represents. A value of zero (0) 
//      represents failure.
//
//-----------------------------------------------------------------------------
volatile int fmd_inited=0;
BOOL FMD_Init(void)//LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{

	if(fmd_inited)
		return TRUE;

	fmd_inited=1;
    
    NFCSetClock(TRUE);
    
    // Perform NFC allocations, mappings, and initializations
    /*if (!NFCAlloc())
    {
        ERRORMSG(TRUE, (_T("FMD_Init: failed memory allocation/mapping\r\n")));
        goto cleanUp;
    }*/
    NFCAlloc();

    
    // Unlock buffer pages
	OUTREG16(&g_pNFC->NFC_CONFIGURATION,0x02);

    // Use NFC buffer #0 for all operations
    OUTREG16(&g_pNFC->RAM_BUFF_ADDRESS, 0);
    
    // Configure the NFC
    //  - Enable hardware ECC
    //  - Mask NFC interrupt
    //  - Little endian mode
    //  - Reset NFC state machine
    //  - CE signal operates normally
	//	- 0x0018
    OUTREG16(&g_pNFC->NAND_FLASH_CONFIG1, 
        CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_ECC_EN, NANDFC_NAND_FLASH_CONFIG1_ECC_EN_ENABLE) |
        CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_INT_MSK, NANDFC_NAND_FLASH_CONFIG1_INT_MSK_MASK) |
        CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_NF_BIG, NANDFC_NAND_FLASH_CONFIG1_NF_BIG_LITTLE) |
        CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_NF_CE, NANDFC_NAND_FLASH_CONFIG1_NF_CE_UNFORCE));    

    NF_CMD(CMD_RESET);     // Send flash reset command

    // Get manufacturer and device codes.
    NF_CMD(CMD_READID);     // Read ID command
    NF_ADDR(0);             // Required address cycle
    NF_RD_ID();             // Read ID into NFC buffer

    g_NandDeviceID = INREG16(&g_pNFC->MAIN[0]);
    
    if (g_NandDeviceID != NAND_ID_CODE)
    {
        //ERRORMSG(TRUE, (_T("FMD_Init: invalid device ID (%x)\r\n"), g_NandDeviceID));
        return FALSE;
    }

    // Unlock all blocks
    OUTREG16(&g_pNFC->UNLOCK_START_BLK_ADD, 0);
    OUTREG16(&g_pNFC->UNLOCK_END_BLK_ADD, NAND_BLOCK_CNT-1);
    OUTREG16(&g_pNFC->NF_WR_PROT, NANDFC_NF_WR_PROT_WPC_UNLOCK);

cleanUp:
    NFCSetClock(FALSE);
    return TRUE;//rc;
}


//-----------------------------------------------------------------------------
//
//  Function: FMD_Deinit
//
//  This function de-initializes the flash chip.
//
//  Parameters:
//      hFMD 
//          [in] The handle returned from FMD_Init. 
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_Deinit(void)//Pvoid hFMD)
{
    return(TRUE);
}

//-----------------------------------------------------------------------------
//
//  Function: NFCReadMain
//
//  This function reads the NAND flash controller main area and provides this
//  sector data to the upper FMD layers.
//
//  Parameters:
//      pSectorBuff 
//          [out] Buffer containing sector data read.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void NFCReadMain(u8_ptr pSectorBuff)
{        

/*    if((u32)pSectorBuff & 0x1)        
    {
        // Byte-aligned on BYTE[3]
        if((u32)pSectorBuff & 0x2)        
        {
            RdPage512Align3(pSectorBuff);
        }

        // Byte-aligned on BYTE[1]
        else
        {
            RdPage512Align1(pSectorBuff);
        }
    }
    else if ((u32)pSectorBuff & 0x2)
    {
        // Half-word aligned on BYTE[2]
        RdPage512Align2(pSectorBuff);
    } 
    else
    {
        // Word-aligned
        RdPage512Align4(pSectorBuff);
    }*/
}

static void FMD_ReadMain(u16_ptr pBuffer,/* u8_ptr pMain,*/ u16 pSize)
{
	u16 i;
	 u16_ptr pMain ;
	pMain = (u16 *)(0xD8000000);
	for(i = 0; i < pSize; i++)
	{
		*pBuffer = *pMain ;
		pBuffer++ ; 
		pMain++ ;	
	}
	return;
}
//-----------------------------------------------------------------------------
//
//  Function: FMD_ReadSector
//
//  This function reads the requested sector data and metadata from the 
//  flash media.
//
//  Parameters:
//      startSectorAddr 
//          [in] The starting physical sector address to read.
//
//      pSectorBuff 
//          [out] Pointer to the buffer that contains the sector data read 
//          from flash memory. Set to NULL if this data is not needed.
//
//      pSectorInfoBuff 
//          [out] Buffer for an array of sector information structures. There 
//          is one sector information entry for every sector that is to be read. 
//          Set to NULL if this data is not needed. 
//
//      dwNumSectors 
//          [in] Number of sectors to read.
//
//  Returns:  
//      Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------

BOOL FMD_ReadSector(u32 startSectorAddr, u16_ptr pSectorBuff, 
    PSectorInfo pSectorInfoBuff, u32 dwNumSectors)
{
    u32 SectorAddr = startSectorAddr;
    u32 ColumnAddr, RowAddr;
    BOOL bSeqRead = FALSE;
    BOOL rc = FALSE;
    u16 Status;

    NFCSetClock(TRUE);
    
    while (dwNumSectors--)
    {
        RowAddr = (u32)SectorAddr/NAND_SECTORS_PERPAGE;
        ColumnAddr = ((u32)SectorAddr%NAND_SECTORS_PERPAGE) * (NAND_SECTOR_SIZE + NAND_SPARE_SIZE); 
    
    
        if (pSectorBuff != NULL)
        {
            // If read access requires command and address to be sent
            if (!bSeqRead)
            {
                NF_CMD(CMD_READ);             // Send page read command.
                NF_ADDR_COL(ColumnAddr);      // Send column address
                NF_ADDR_PAGE(RowAddr);        // Send page address
                
#ifdef NAND_LARGE_PAGE
                NF_CMD(CMD_READ_2CYCLE);      // Send 2nd cycle read command
#endif
            }
            
            // Read page data into NFC buffer
            NF_RD_PAGE();
            
            // Move page data from NFC buffer sector buffer
            //NFCReadMain(pSectorBuff);
			//data = sizeof(pSectorBuff);
			//FMD_ReadMain(pSectorBuff,&g_pNFC->MAIN,512);
			FMD_ReadMain(pSectorBuff, 256);
			//memcpy(pSectorBuff,&g_pNFC->MAIN,data);

            if (pSectorInfoBuff != NULL)
            {
                NFCReadSpare(pSectorInfoBuff);

                pSectorInfoBuff++;
            }

            pSectorBuff += NAND_SECTOR_SIZE;

            // Check for uncorrectable ECC errors in main and spare areas
			Status = INREG16(&g_pNFC->ECC_STATUS_RESULT);
            if (Status & 0xa)
            {
                goto cleanUp;
            }
          
        }

        else if (pSectorInfoBuff != NULL)
        {
#ifndef NAND_LARGE_PAGE
            NF_CMD(CMD_READ2);                        // Send spare read command.

⌨️ 快捷键说明

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