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

📄 fmd.c

📁 windows mobile 6.13 dnldr下载源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <fmd.h>
#include "nand.h"

#define MAX_PAGE_SIZE  2112

extern FLASH_CHIP_STRU g_stFlashChipInfo;

/*******************************************************************************
  Function:     BMM_TranslateInfo
  Description:  本接口用于块信息(BMM信息和SECTOR信息)与SpareArea之间的转换
  Input:        1、SpareArea缓冲区指针
                2、BMM信息缓冲区指针
                3、SECTOR信息缓冲区指针
                4、转换类型
  Output:       转换生成的数据
  Return:      FMD_SUCCESS:操作成功;
                其他:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
DWORD BMM_TranslateInfo(PSectorInfo pSectorInfoBuff, LPBYTE pSectorBuff, DWORD dwTranslateType)
{
    unsigned char ucTempBuf[8] = {0};

    /*参数判断*/
    if(SPAREAREA_TO_BLOCKINFO == dwTranslateType)
    {
        /*根据SpareArea的实际结构从中获取相应的SECTORINFO信息;*/
        if(NULL != pSectorInfoBuff)
        {
            ucTempBuf[0] = *(pSectorBuff);
            ucTempBuf[1] = *(pSectorBuff + 1);
            ucTempBuf[2] = *(pSectorBuff + 5);
            ucTempBuf[3] = *(pSectorBuff + 6);
            ucTempBuf[4] = *(pSectorBuff + 7);
            ucTempBuf[5] = *(pSectorBuff + 13);
            ucTempBuf[6] = *(pSectorBuff + 16);
            ucTempBuf[7] = *(pSectorBuff + 17);
            memcpy((UINT8*)pSectorInfoBuff, ucTempBuf, 8);
        }
    }
    else
    {
        /*根据SpareArea的实际结构将相应的SECTORINFO信息写入到SpareArea对应位置中;*/
        if(NULL != pSectorInfoBuff)
        {
            memcpy(ucTempBuf, (UINT8*)pSectorInfoBuff, 8);
            *(pSectorBuff) = ucTempBuf[0];
            *(pSectorBuff + 1) = ucTempBuf[1];
            *(pSectorBuff + 5) = ucTempBuf[2];
            *(pSectorBuff + 6) = ucTempBuf[3];
            *(pSectorBuff + 7) = ucTempBuf[4];
            *(pSectorBuff + 13) = ucTempBuf[5];
            *(pSectorBuff + 16) = ucTempBuf[6];
            *(pSectorBuff + 17) = ucTempBuf[7];
        }
    }
    return FMD_SUCCESS;
}

/*******************************************************************************
  Function:     FMD_Init
  Description:  本接口用于FMD设备初始化
  Input:        1、注册表项
                2、FLASH结构体(pRegIn)
  Output:       1、FLASH结构体(pRegOut)
                2、物理扇区空闲区地址
  Return:      设备句柄
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
PVOID  FMD_Init(void)
{
    DWORD dwFlashID = 0;

    g_stFlashChipInfo.pBaseAddress = 0;
    g_stFlashChipInfo.dwPhyIntr = NANDC_PHY_INTRRUPT;
    g_stFlashChipInfo.dwNandcBaseAddr = NANDC_DATA_BASE_ADDR;
    g_stFlashChipInfo.SectorSize = NF_SECTOR_SIZE;
    g_stFlashChipInfo.SectorsPerBlock = NF_SECTORS_PER_BLOCK;
    g_stFlashChipInfo.SpareSize = NF_SPARE_SIZE;
    g_stFlashChipInfo.bRunWithIntr = FALSE;
    g_stFlashChipInfo.BlockSize = g_stFlashChipInfo.SectorSize*g_stFlashChipInfo.SectorsPerBlock;
    g_stFlashChipInfo.pNvBlock = (PBYTE)MemAlloc(g_stFlashChipInfo.BlockSize);

    g_stFlashChipInfo.pfnCheckOrgBadBlock = NULL;

    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO: FMD_Init]:pBaseAddress=0x%x.\r\n"), (ULONG)g_stFlashChipInfo.pBaseAddress));
    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO: FMD_Init]:dwNandcBaseAddr=0x%x.\r\n"), (ULONG)g_stFlashChipInfo.dwNandcBaseAddr));
    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO: FMD_Init]:dwPhyIntr=0x%x.\r\n"), (ULONG)g_stFlashChipInfo.dwPhyIntr));

    if(FMD_SUCCESS != NF_Init(&dwFlashID))
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_Init]: NF_Init.\r\n")));
        return NULL;
    }

    if(MT29F2G16ABD == dwFlashID)
    {
        g_stFlashChipInfo.pfnCheckOrgBadBlock = CheckMT29FBadBlock;
    }

    if(!ReplaceBadBlockSign())
    {
        return NULL;
    }

    if(!InitNv())
    {
       OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR InitNv]FMD_Init : InitNv Nv region is not ready.\r\n")));
    }

    return((PVOID)g_stFlashChipInfo.TotalBlockNumbers);
}
/*******************************************************************************
  Function:     FMD_Deinit
  Description:  本接口用于去初始化FMD设备
  Input:        由FMD_Init返回的句柄
  Output:       none
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_Deinit(PVOID pBaseAddress)
{
    return(TRUE);
}

/*******************************************************************************
  Function:     FMD_GetInfo
  Description:  本接口用于读取FLASH中BLOCK SIZE大小等参数信息
  Input:        FLASH信息缓冲区指针
  Output:       FLASH信息
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_GetInfo(PFlashInfo pFlashInfo)
{
    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD_GetInfo]: TotalFlashBlocks = 0x%x\r\n"),g_stFlashChipInfo.TotalBlockNumbers));
    pFlashInfo->flashType           = NAND;
    pFlashInfo->dwNumBlocks         = g_stFlashChipInfo.TotalBlockNumbers;
    pFlashInfo->dwBytesPerBlock     = g_stFlashChipInfo.BlockSize;
    pFlashInfo->wDataBytesPerSector = (WORD)g_stFlashChipInfo.SectorSize;
    pFlashInfo->wSectorsPerBlock    = (WORD)g_stFlashChipInfo.SectorsPerBlock;

    return(TRUE);
}

#if 0
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_GetInfoEx

Description:    Determines the size characteristics for the Flash memory device.
                     Includes support for multiple regions.

Notes:          If pFlashInfo is NULL, then this just returns the number of reserved regions.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_GetInfoEx(PFlashInfoEx pFlashInfo, PDWORD pdwNumRegions)
{
    pFlashInfo->cbSize               = sizeof(FlashInfoEx);
    pFlashInfo->flashType            = NAND;
    pFlashInfo->dwNumBlocks          = g_stFlashChipInfo.TotalBlockNumbers;
    pFlashInfo->dwDataBytesPerSector = (WORD)g_stFlashChipInfo.SectorSize;
    pFlashInfo->dwNumRegions         = 1;

    return(TRUE);
}
#endif

/*******************************************************************************
  Function:     FMD_GetPhysSectorAddr
  Description:  本接口用于读取FLASH指定逻辑扇区的实际扇区地址
  Input:        逻辑扇区地址
  Output:       实际扇区地址
  Return:      none
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
VOID FMD_GetPhysSectorAddr (DWORD dwSector, PSECTOR_ADDR pStartSectorAddr)
{

}


/*******************************************************************************
  Function:     FMD_ReadSector
  Description:  本接口用于把从一个扇区开始的一段地址的数据读取出来
  Input:        1、起始扇区地址
                2、数据缓冲区指针
                3、扇区信息缓冲区指针
                4、待读取的扇区数
  Output:       扇区数据
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    DWORD                 i                      = 0;
    DWORD                 ret                    = 0;
    BOOL                  bLastMode              = FALSE;
    BYTE                  pcSectorBuf[MAX_PAGE_SIZE]      = {0};
    volatile SECTOR_ADDR  physicalSectorAddr     = 0;
    volatile SECTOR_ADDR  physicalSectorInfoAddr = 0;
    volatile DWORD Size = 0;

    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD_ReadSector]:startSectorAddr = 0x%x\r\n"), startSectorAddr));
    //----- 1. Check the input parameters -----
    //         NOTE: The FAL insures that the starting sector address is in the allowable range.
    if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
    {
        return(FALSE);
    }

    for(i = startSectorAddr ; i < (startSectorAddr + dwNumSectors) ; i++)
    {
        //----- Compute the physical address for the requested -----
        physicalSectorAddr = g_stFlashChipInfo.pBaseAddress*2 + i*NF_SECTOR_ADDR_SHIFT;
        physicalSectorInfoAddr = physicalSectorAddr + g_stFlashChipInfo.SectorSize;

        if(NULL != pSectorBuff)
        {
            /*调用NF_PageRead读取SECTOR的MainArea的数据;*/
            ret = NF_PageRead(physicalSectorAddr, pcSectorBuf, (g_stFlashChipInfo.SectorSize+g_stFlashChipInfo.SpareSize));
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_ReadSector]:NF_PageRead Error!physicalSectorAddr = 0x%x,ret = 0x%x\r\n"), physicalSectorAddr, ret));
                return FALSE;
            }
            memcpy(pSectorBuff, pcSectorBuf, g_stFlashChipInfo.SectorSize);
            pSectorBuff+=g_stFlashChipInfo.SectorSize;

            if(NULL != pSectorInfoBuff)
            {
                /*调用BMM_TranslateInfo转换SpareArea成SECTOR信息;*/
                ret = BMM_TranslateInfo(pSectorInfoBuff, pcSectorBuf+g_stFlashChipInfo.SectorSize, SPAREAREA_TO_BLOCKINFO);
                if(FMD_SUCCESS != ret)
                {
                    OALMSG(ZONE_FMD_ERR, (TEXT("[NANDFMD:FMD_ReadSector]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
                    return FALSE;
                }
                pSectorInfoBuff++;
            }
        }
        else if(NULL != pSectorInfoBuff)
        {
            /*调用NF_PageRead读取SECTOR的SpareArea的数据(此时不会出现ECC纠正错误NF_ECC_CORRECT_ERROR);*/
            ret = NF_PageRead(physicalSectorInfoAddr, g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_ReadSector]:NF_PageRead SpareArea Error!ret = 0x%x\r\n"),ret));
                return FALSE;
            }
            /*调用BMM_TranslateInfo转换SpareArea成SECTOR信息;*/
            ret = BMM_TranslateInfo(pSectorInfoBuff, g_stFlashChipInfo.pucSpareArea, SPAREAREA_TO_BLOCKINFO);
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_ReadSector]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
                return FALSE;
            }
            pSectorInfoBuff++;
        }
    }

    return(TRUE);
}

/*******************************************************************************
  Function:     FMD_WriteSector
  Description:  本接口用于写一块缓冲区的内容到从一个扇区开始的一段地址中
  Input:        1、起始扇区地址
                2、数据缓冲区指针
                3、扇区信息缓冲区指针
                4、待写入的扇区数
  Output:       none
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    DWORD    i                                  = 0;
    DWORD    ret                                = 0;
    BOOL     bLastMode                          = FALSE;
    BYTE     pcSectorBuf[MAX_PAGE_SIZE]         = {0};
    volatile SECTOR_ADDR physicalSectorAddr     = 0;
    volatile SECTOR_ADDR physicalSectorInfoAddr = 0;

    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD_WriteSector]:startSectorAddr = 0x%x\r\n"), startSectorAddr));
    //----- 1. Check the input parameters -----
    //         NOTE: The FAL insures that the starting sector address is in the allowable range.
    if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
    {
        return FALSE;
    }

    for(i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
    {
        physicalSectorAddr = g_stFlashChipInfo.pBaseAddress*2 + i*NF_SECTOR_ADDR_SHIFT;
        physicalSectorInfoAddr = physicalSectorAddr + g_stFlashChipInfo.SectorSize;
        if(NULL != pSectorBuff)
        {
            memset(pcSectorBuf+g_stFlashChipInfo.SectorSize, 0xFF, g_stFlashChipInfo.SpareSize);
            if(NULL != pSectorInfoBuff)
            {
                ret = BMM_TranslateInfo(pSectorInfoBuff, pcSectorBuf+g_stFlashChipInfo.SectorSize, BLOCKINFO_TO_SPAREAREA);
                if(FMD_SUCCESS != ret)
                {
                    OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_WriteSector]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
                    return FALSE;
                };
                pSectorInfoBuff++;
            };

            memcpy(pcSectorBuf, pSectorBuff, g_stFlashChipInfo.SectorSize);
            /*调用NF_PageProgram写入扇区的MainArea;*/
            ret = NF_PageProgram(physicalSectorAddr, pcSectorBuf, g_stFlashChipInfo.SectorSize+g_stFlashChipInfo.SpareSize);
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR,(TEXT("[ERROR FMD_WriteSector]:NF_PageProgram Error!ret = 0x%x\r\n"), ret));
                return FALSE;
            };
            pSectorBuff += g_stFlashChipInfo.SectorSize;
        }
        else if(NULL != pSectorInfoBuff)
        {
            /*调用BMM_TranslateInfo转换SECTOR信息成SpareArea信息;*/
            memset(g_stFlashChipInfo.pucSpareArea, 0xFF, g_stFlashChipInfo.SpareSize);
            ret = BMM_TranslateInfo(pSectorInfoBuff, g_stFlashChipInfo.pucSpareArea, BLOCKINFO_TO_SPAREAREA);
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_WriteSector]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
                return FALSE;
            }
            /*调用NF_PageProgram写入扇区的SpareArea;*/
            ret = NF_PageProgram(physicalSectorInfoAddr, g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
            if(FMD_SUCCESS != ret)
            {
                OALMSG(ZONE_FMD_ERR,(TEXT("[ERROR FMD_WriteSector]:NF_PageProgram Error!ret = 0x%x\r\n"), ret));
                return FALSE;
            }
            pSectorInfoBuff++;
        };
    }

    return TRUE;
}

/*******************************************************************************
  Function:     FMD_GetBlockStatus
  Description:  本接口用于读取块状态
  Input:        待操作块地址
  Output:       none
  Return:      块状态
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
    ULONG ulBlock = 0;
    DWORD ret = 0;
    DWORD dwStatus = 0;

    ulBlock = g_stFlashChipInfo.pBaseAddress/g_stFlashChipInfo.BlockSize + blockID;

    /*调用NF_PageRead读取SpareArea信息;*/
    ret = NF_PageRead(ulBlock*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                      g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)

⌨️ 快捷键说明

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