fmd.cpp

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

CPP
1,511
字号
//
// 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.
//

#include "fmd.h"

#include <ceddk.h>
#ifdef READ_FROM_REGISTRY
#include <ddkreg.h>
#endif 

//wzw>> -
//#include <hwdefs.h>

#include "strata.h"

#define _SDNAND_


//=========================================================================================================
#include "xllp_ost.h"

#define NAND_BUSY_PORT			(IoAddr+8)
#define NAND_CS_PORT			(IoAddr+0xc)

typedef struct
{
    volatile unsigned long    osmr0;         	//OS timer match register 0
    volatile unsigned long    osmr1;         	//OS timer match register 1
    volatile unsigned long    osmr2;         	//OS timer match register 2
    volatile unsigned long    osmr3;          	//OS timer match register 3
    volatile unsigned long    oscr0;            //OS timer counter register 0(compatible)
    volatile unsigned long    ossr;             //OS timer status register
    volatile unsigned long    ower;          	//OS timer watchdog enable register
    volatile unsigned long    oier;           	//OS timer interrupt enable register
    volatile unsigned long    osnr;           	//OS timer snapshot register
    volatile unsigned long    reserved1[7];
    volatile unsigned long    oscr4;		//OS timer counter register 4
    volatile unsigned long    oscr5;		//OS timer counter register  5
    volatile unsigned long    oscr6;		//OS timer counter register  6
    volatile unsigned long    oscr7;		//OS timer counter register  7
    volatile unsigned long    oscr8;		//OS timer counter register  8
    volatile unsigned long    oscr9;		//OS timer counter register  9
    volatile unsigned long    oscr10;		//OS timer counter register  10
    volatile unsigned long    oscr11;		//OS timer counter register  11
    volatile unsigned long    reserved2[8];
    volatile unsigned long    osmr4;		//OS timer match register 4
    volatile unsigned long    osmr5;		//OS timer match register 5
    volatile unsigned long    osmr6;		//OS timer match register 6
    volatile unsigned long    osmr7;		//OS timer match register 7
    volatile unsigned long    osmr8;		//OS timer match register 8
    volatile unsigned long    osmr9;		//OS timer match register 9
    volatile unsigned long    osmr10;		//OS timer match register 10
    volatile unsigned long    osmr11;		//OS timer match register 11
    volatile unsigned long    reserved3[8];
    volatile unsigned long    omcr4;		//OS timer match control register 4
    volatile unsigned long    omcr5;		//OS timer match control register 5
    volatile unsigned long    omcr6;		//OS timer match control register 6
    volatile unsigned long    omcr7;		//OS timer match control register 7
    volatile unsigned long    omcr8;		//OS timer match control register 8
    volatile unsigned long    omcr9;		//OS timer match control register 9
    volatile unsigned long    omcr10;		//OS timer match control register 10
    volatile unsigned long    omcr11;		//OS timer match control register 11
} m_OST_T, *P_m_OST_T;
//=========================================================================================================
volatile ULONG NAND_CMD_PORT ;           
volatile ULONG NAND_ADDR_PORT ;          
volatile ULONG NAND_DATA_PORT ;         

extern "C" PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);


void *mg_pOSTRegs;
void *v_pNANDFlash;

//==============================================================================================

//1. adrress
//2. 8bit--->32bit
//3. delay
//==============================================================================================

//-------------------------------------------------------------
static void mmXllpOstDelayTicks(P_m_OST_T pOstRegs, unsigned long ticks)
{    
    unsigned long  expireTime, time;

    time = pOstRegs->oscr0;
	expireTime = time + ticks;

	if (expireTime < time)     {
		while (time < pOstRegs->oscr0);
	}
	while (pOstRegs->oscr0 <= expireTime);
    return;
}

void mmXllpOstDelayMicroSeconds(P_m_OST_T pOstRegs, unsigned long microseconds)
{
    unsigned long  ticks;

    ticks = microseconds * 3;	///XLLP_OST_TICKS_US;  // approx. 3 ticks per microsecond. 
    mmXllpOstDelayTicks (pOstRegs, ticks);
}
//-------------------------------------------------------------



#if 0
BOOL FMD_MapVirtualAddress()
{
//    RETAILMSG(1, (TEXT("wzw:FMD_MapVirtualAddress\r\n")));
//	v_pNANDFlash=(ULONG *)VirtualAllocCopy(0x100,"nflash_addr",((PVOID)FPGA_REGS_BASE_U_VIRTUAL+0x400));
	v_pNANDFlash=VirtualAllocCopy(0x100,"mapping nand",(LPVOID)(FPGA_REGS_BASE_U_VIRTUAL+0x400));

	if (!v_pNANDFlash)	{
		if (v_pNANDFlash) {
			VirtualFree((PVOID)v_pNANDFlash,0,FPGA_REGS_BASE_U_VIRTUAL);
			v_pNANDFlash = NULL;
		}
		return FALSE;
	}

//	NAND_CMD_PORT  = *v_pNANDFlash + 4;
//	NAND_ADDR_PORT = *v_pNANDFlash + 8;
//	NAND_DATA_PORT = *v_pNANDFlash + 0;
/*
	nandAdrr =	v_pNANDFlash + 4;	//2;	//1;	//4 ;
	nandCMD	 =	v_pNANDFlash + 8;	//1;	//2;	//8 ;
	nandDATA =	v_pNANDFlash + 0 ;
*/


//wzw>>
	NAND_CMD_PORT  = ((ULONG)v_pNANDFlash + 0x08);	//0x408);
	NAND_ADDR_PORT = ((ULONG)v_pNANDFlash + 0x04);	//0x404);
	NAND_DATA_PORT = ((ULONG)v_pNANDFlash + 0x0);	//0x400);

	return TRUE;
}
#endif

//==============================================================================================

BOOL FMD_MapVirtualAddress()
{
    PHYSICAL_ADDRESS PA;
    PHYSICAL_ADDRESS RegPA;
	
//	v_pNANDFlash=VirtualAllocCopy(0x100,"mapping nand",(LPVOID)(FPGA_REGS_BASE_U_VIRTUAL+0x400));
	
    PA.QuadPart = 0x08000000+0x400;		///MAINSTONEII_BASE_REG_PA_FPGA;
    v_pNANDFlash = (void *) MmMapIoSpace(PA, 0x100, FALSE);

    if (mg_pOSTRegs == NULL)    {
        RegPA.QuadPart = 0x40A00000;	///BULVERDE_BASE_REG_PA_OST;
        mg_pOSTRegs = (void *) MmMapIoSpace(RegPA, 0x400, FALSE);
    }


    if (!v_pNANDFlash  || !mg_pOSTRegs )    {
        DEBUGMSG(1, (TEXT("ERROR: Failed to allocate touch panel resources (Error=%u).\r\n"), GetLastError()));
		if (mg_pOSTRegs)	{
        	VirtualFree((void *)mg_pOSTRegs, 0, MEM_RELEASE);
	        mg_pOSTRegs = NULL;
    	}
	    if (!v_pNANDFlash)   {
        	VirtualFree((void *)v_pNANDFlash, 0, MEM_RELEASE);
	        v_pNANDFlash = NULL;
	    }
        return(FALSE);
    }

	NAND_CMD_PORT  = ((ULONG)v_pNANDFlash + 0x08);	//0x408);
	NAND_ADDR_PORT = ((ULONG)v_pNANDFlash + 0x04);	//0x404);
	NAND_DATA_PORT = ((ULONG)v_pNANDFlash + 0x0);	//0x400);
	
	return TRUE;
}
//==============================================================================================
//  Flash Chip Capability

#define NUM_BLOCKS                  4096
#define SECTOR_SIZE                 2048
#define SPARE_SIZE                  64

//  NAND Flash Command. This appears to be generic across all NAND flash chips
#define CMD_READ                    0x00        //  Read
#define CMD_READ1                   0x01        //  Read1
#define CMD_READ2                   0x50        //  Read2
#define CMD_READID                  0x90        //  ReadID
#define CMD_READID2                 0x91        //  Read extended ID
#define CMD_WRITE                   0x80        //  Write phase 1
#define CMD_WRITE2                  0x10        //  Write phase 2
#define CMD_ERASE                   0x60        //  Erase phase 1
#define CMD_ERASE2                  0xd0        //  Erase phase 2
#define CMD_STATUS                  0x70        //  Status read
#define CMD_RESET                   0xff        //  Reset

//  Status bit pattern
#define STATUS_READY                0x40        //  Ready
#define STATUS_ERROR                0x01        //  Error
static BYTE ECC[8];                  // Used to retrieve/store ECC information
#ifndef _ECC_H_
#define _ECC_H_ 

#include <windows.h>
//#include <windows.h>
#include <nkintr.h>

#define DATA_BLOCK_LEN          256
#define ECC_BUFF_LEN            6                   // 3 bytes per 256 bytes of data

#define UNCORRECTABLE_ERROR     1
#define CORRECTABLE_ERROR       11

#ifdef __cplusplus
extern "C" {
#endif 

//---------------------------- Structure Definitions -----------------------------



//------------------------------- Public Interface ------------------------------

BOOL ECC_ComputeECC(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pECC, DWORD dwECCBuffLen); 
BOOL ECC_IsDataValid(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pExistingECC, DWORD dwECCBuffLen); 
BOOL ECC_CorrectData(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pExistingECC, DWORD dwECCBuffLen);


//------------------------------ Helper Functions ------------------------------ 
UCHAR CountNumberOfOnes(UCHAR num);

#ifdef __cplusplus
}
#endif

#endif _ECC_H_

static BOOL g_bPairedFlash = TRUE;        // Indicates whether or not two flash parts are paired to create a 32-bit data interface.

#define MIN(a, b) (a < b ? a : b) 
BOOL NEED_EXT_ADDR = TRUE;
static BOOL g_bXIPMode = FALSE;
static FMD_FLASH_INFO g_FMDInfo;
ULONG oldval;


// Function required by StrataFlash FMD - stub implementation.
DWORD SetKMode(DWORD fMode)
{
    return(fMode);
}

//  CheckStatus()
//
//  Retrieve the status of the Chip. This function accept a loop number, which
//  is used to do the loop if chip is not ready.
//
//  dwLoops: 
//
//  0:          no loop
//  0xffffffff: loop forever
//
UCHAR CheckStatus(DWORD dwLoops)
{
    BOOL    bStop = (dwLoops != (DWORD) -1);
    UCHAR   usStatus,temp;

    // Twb=200ns wait. generate 20 * 30ns wait
    for (volatile int i=0;i<5;i++)
   	{
        temp=*((volatile UCHAR *)(0x92000080));
   	}
    
    return usStatus;
}
//  GetStatus()
//
//  Retrieve the status of the Chip. This function accept a loop number, which
//  is used to do the loop if chip is not ready.
//
//  dwLoops: 
//
//  0:          no loop
//  0xffffffff: loop forever
//
UCHAR GetStatus(DWORD dwLoops)
{
    BOOL    bStop = (dwLoops != (DWORD) -1);
    UCHAR   usStatus;

//wzw@@
//	usWait(2);	//
	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 2);
//	Sleep(1);
//	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
	
    //  Issue read status command
	*((volatile ULONG *)(NAND_CMD_PORT))=CMD_STATUS;
    while(1) {
        usStatus = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
        if( usStatus & STATUS_READY )                   //  Non-infinite loop and //  we already pay our due
        {
            break;
        }
        dwLoops--;
    }

    //  We need to reset the port back to read mode. Issuing a read (0x00) 
    //  command
    //FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ);

    return usStatus;
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_Init()

Description:    Initializes the Flash memory device.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
static DWORD ReadFlashID(void)
{
    BYTE Mfg, Dev;

    *((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READID;       // Send flash ID read command.
    *((volatile ULONG *)(NAND_CMD_PORT ))=0;                //
//  Sleep(1);     //wzw wait      // Wait for flash to complete command.
//	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
//	Sleep(1);
	mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);

    Mfg    = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));    // 
    Dev    = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));    // 

    return ((DWORD)Mfg*0x100+Dev);
}


BOOL ECC_ComputeECC(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pECC, DWORD dwECCBuffLen)
{
	static UINT    i, j, k;
	static UCHAR   evenParity[16] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0};		// Look-up table (LUT)
	static UCHAR   dataXOR = 0;
	static UCHAR   bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7;

	// Column parity terms.  NOTE: p subscript denotes "prime" (i.e. P1p = P1')
	static UCHAR   P1, P2, P4,  P1p, P2p, P4p;			

	// Row parity terms.  NOTE: p subscript denotes "prime" (i.e. P8p = P8')
	UCHAR   P8, P8p, P16, P16p, P32, P32p, P64, P64p, P128, P128p, 
		    P256, P256p, P512, P512p, P1024, P1024p;

//    RETAILMSG(1, (TEXT("INFO:ECC_ComputeECC\r\n")));//+

	//----- 1. Check to make sure the input buffers are legitimate... -----
	if((pData == NULL) || (pECC == NULL) || (dwDataBuffLen < DATA_BLOCK_LEN) || (dwECCBuffLen < ECC_BUFF_LEN) )
	{
		DEBUGMSG(1, (TEXT("FMD:ECC_ComputeECC() - Input buffers are not legitimate!\r\n")));
		return FALSE;
	}

	//----- 2. Segregrate the data buffer into 256 byte blocks and compute ECC info for each block -----
	for(j=0,k=0; j<dwDataBuffLen; j+= DATA_BLOCK_LEN)
	{
		//----- 3. Initialize the ROW parity terms -----
		dataXOR = 0;
		P8=0;   P8p=0;   P16=0;  P16p=0;  P32=0;  P32p=0;  P64=0;   P64p=0; 

⌨️ 快捷键说明

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