📄 mmcmng.c
字号:
/****************************************************************************/
/* */
/* Copyright (C) 2002 SHENZHEN MEIJIN CO.LTD */
/* */
/* FILE NAME: MmcMng.C */
/* MODULE NAME: FLASH MANAGER MODAL */
/* DESCRIPTION: FLASH管理模块源文件 */
/* */
/****************************************************************************/
/* DATE AUTHOR VERSION REMARKS */
/* =========== =========== ========= =====================================*/
/* 2003-03-?? 黄小明 Ver 1.00 创建 */
/****************************************************************************/
#define __OS_SOURCE_FILE__
/* 包含所需头文件 */
/* 包含所需头文件 */
#include "Base.h"
#include "IoDriver.h"
#include "MemMng.h"
#include "..\\..\\BuildPc\\PcSimu.h" // 这是PC上的驱动程序所独有的头文件
#include <stdio.h>
#include <direct.h>
//#include "SDCardIn.h"
#include "SDCardIn.h"
//-----------------------------------
#define FLASH_BLOCK_TABLE 1
#if 0
/* Flash命令类型 */
#define FLASH_COMMAND_FORMAT 0x1000 /*FLASH低级格式化*/
#define FLASH_COMMAND_GETINFO 0x1001 /*FLASH相关信息*/
#define FLASH_ERR_NONE 0 //没有错误
#define FLASH_ERR_NOFORMAT -1 //没有格式化
#define FLASH_ERR_NOPREPARE -2 //没有备用块
#define FLASH_ERR_LOWVOLTAGE -3 //低电压(格式化才检查)
#define FLASH_ERR_DRV -4 //驱动错误
#define FLASH_ERR_MEM -5 //内存申请错误
#define FLASH_ERR_COUNTER -6 //擦除计数器错误(调试使用)
#define FLASH_ERR_UNKNOW -7 //其他错误
#endif
//--------------
#define FLASH_LOGIC_OFFSET 0 //Flash逻辑编号存储偏移量
#define FLASH_MODIFY_OFFSET 2 //Flash块Modify标志位置
#define FLASH_STATUS_OFFSET 5 //Flash块状态标志位置
#define FLASH_ECC_OFFSET 520 //Flash块ECC校验位置
#define FLASH_ECC_LENGTH 3 //Flash块ECC校验长度
#define FLASH_REPLACE_OFFSET 12 //Flash块Replace标志位置
#define FLASH_REPLACE_MAXVALUE 256 //Flash块Replace标志最大值
//#define FLASH_CHECK_OFFSET (526 + 496) //Flash块Check标志位置
#define FLASH_CHECK_OFFSET 3 //Flash块Check标志位置
#define FLASH_CHECK_VALUE 0xA5B4 //Flash块Check值
#define FLASH_STATUS_GOOD 0xFF //好的BLOCK
#define FLASH_STATUS_BAD_USER 0xF0 //坏的BLOCK(使用过程中)
#define FLASH_STATUS_BAD_NATURE 0x00 //坏的BLOCK(出厂就是)
#define FLASH_STATUS_BAD_READFAIL 0x01 //坏的BLOCK(不能读取)
#define FLASH_STATUS_BAD_UNKNOWN 0x02 //坏的BLOCK(未识别的)
#define FLASH_FLAG_FREE 0xFF //Flash块标志,可直接写
#define FLASH_FLAG_MODIFY_TEMP 0x0F //Flash块标志,被临时修改
#define FLASH_FLAG_MODIFY 0x00 //Flash块标志,被修改
#define FLASH_SUCCESS_FLAG 0x00 //Flash块操作成功标志
#define FLASH_LOGIC_PREPARE 0x7FFF //备用块逻辑号
//============================
#define NU_Printf
#define SysWatchClear()
//==============================================================
/* 包含所需头文件 */
//#include "Os.h"
//#include "FlsMngIn.h"
//#include "SysWatch.h"
#ifdef _BOARD
#define TIMER_CONTROL_REG 0x481AE
#else
#define TIMER_CONTROL_REG 0x4818E
#endif
/*#define FLASH_ERASE_COUNTER 1
#define FLASH_ECC_CHECK 1*/
/*
typedef struct tagNFLASH_PARAMETER
{
UINT8 chipID; // Chip ID
UINT8 factoryID; // factory ID
UINT8 factoryName[10]; // factory name string
UINT32 uDataPerPage; // data size per page
UINT32 uSparePerPage; // spare size per page
UINT32 uPageSum; // total page number,
UINT32 uPagePerBlock; // page number per block
UINT32 uDataPerBlock; // data size per block
UINT32 uSparePerBlock; // spare size per block
UINT32 uBlockSum; // total block number
UINT32 uUserBlockNum; // user block
UINT32 uPrepareBlockNum; // prepare block
} NFLASH_PARAMETER, *PNFLASH_PARAMETER;
*/
//====================================================================
#define FLASH_CRC 0xFFFF
#define FLASH_PAGE_SIZE 512
static NU_DRIVER *g_pMmcDriver; /*Mmc device handle*/
NFLASH_PARAMETER g_MmcParam; /*Mmc Parameter*/
static UINT8* g_MmcReadBuf; /*Mmc Read Buffer*/
static UINT8* g_MmcSpareBuf; /*Mmc Read Buffer*/
static UINT8* g_MmcEccBuf; /*Mmc Read Buffer*/
static INT g_MmcPhyNum; /*victor for quick R/W */
static INT g_MmcLogicNum; //Huangxm Edit 2004/5/8
static INT g_MmcModify; /*victor for quick R/W */
static INT g_MmcDirty; /*victor for quick R/W */
UINT8* g_MmcTableLog2Phy; /*Mmc Log2Phy Table*/
UINT16* g_MmcTablePrepare;
UINT16* g_MmcTableBad;
UINT16 g_uMmcBlockUser; /*Mmc Block User*/
UINT16 g_uMmcBlockPrepare; /*Mmc Block Prepare*/
UINT16 g_uMmcBlockBadUser; /*Mmc Block User*/
UINT16 g_uMmcBlockBadNature; /*Mmc Block User*/
UINT16 g_uMmcBlockBadReadFail; /*Mmc Block Prepare*/
UINT16 g_uMmcBlockBadUnknown; /*Mmc Block Prepare*/
UINT32 g_dwMmcEraseCounter;
UINT8* g_MmcEraseCounterBuf; /*Mmc Read Buffer*/
INT __MmcTableCreate(BOOL bShowProgress);
INT __MmcTableRead();
BOOL __MmcEraseBlock(UINT32 dwOffset, BOOL bCreateBad);
UINT32 __MmcWriteBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen, BOOL bCreateBad);
UINT32 __MmcReadBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen);
UINT32 __MmcWriteSpareBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen, BOOL bCreateBad);
UINT32 __MmcReadSpareBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen);
UINT8 __MmcReadBlockStatus(UINT16 uBlock, UINT8* pSpareBuf);
UINT32 __MmcGetPhysicalPage(UINT32 dwLogicalPage);
// victor for quick R/W
INT __MmcReadBytesBuf(INT offset, UINT8 *pB, INT size);
INT __MmcWriteBytesBuf(INT offset, UINT8 *pB, INT size);
INT __MmcReadPhyEraseUnit(INT dwPhysicalPage, INT dwLogicPage);
UINT8 __MmcReadModifyFlag(UINT32 dwPage);
UINT8 __MmcWriteModifyFlag(UINT32 dwPage, UINT8 bModify);
UINT8 __MmcWriteEccFlag(UINT32 dwPage, UINT32 dwEcc);
UINT32 __MmcEccCalc(UINT8* pBuf);
BOOL __MmcCheckEcc();
BOOL __MmcGetEraseCounter();
BOOL __MmcSetEraseCounter();
UINT16 __MmcBadRegister(UINT8 bBadType, UINT16 wBadBlock);
VOID TableExtract(UINT8 *target, UINT8 *source, UINT count);
#define GraphResetLcdRange()
//检查表的完整性
BOOL __MmcTableCheck()
{
UINT16 *pMmcTablePhy2Log;
UINT16 wBlockBadTotal;
UINT16 wBlockPhy;
UINT16 i;
wBlockBadTotal = g_uMmcBlockBadUser + g_uMmcBlockBadNature +
g_uMmcBlockBadReadFail + g_uMmcBlockBadUnknown;
if(FLASH_BLOCK_TABLE + g_uMmcBlockUser + g_uMmcBlockPrepare + wBlockBadTotal
!= (UINT16)g_MmcParam.uBlockNum)
return FALSE;
if(g_uMmcBlockUser != g_MmcParam.uUserBlockNum)
return FALSE;
pMmcTablePhy2Log = (UINT16 *)MemAlloc(g_MmcParam.uBlockNum * sizeof(UINT16));
if(pMmcTablePhy2Log == NULL)
return FALSE;
memset(pMmcTablePhy2Log, 0xFF, g_MmcParam.uBlockNum * sizeof(UINT16));
for(i = 0; i < g_uMmcBlockUser; i ++)
{
wBlockPhy = *(UINT16 *)(g_MmcTableLog2Phy + i * sizeof(UINT16));
if(pMmcTablePhy2Log[wBlockPhy] != 0xFFFF)
return FALSE;
pMmcTablePhy2Log[wBlockPhy] = i;
}
for(i = 0; i < g_uMmcBlockPrepare; i ++)
{
wBlockPhy = g_MmcTablePrepare[i];
if(pMmcTablePhy2Log[wBlockPhy] != 0xFFFF)
return FALSE;
pMmcTablePhy2Log[wBlockPhy] = 0xF0F0;
}
for(i = 0; i < wBlockBadTotal; i ++)
{
wBlockPhy = g_MmcTableBad[i];
if(pMmcTablePhy2Log[wBlockPhy] != 0xFFFF)
return FALSE;
pMmcTablePhy2Log[wBlockPhy] = 0xF0F0;
}
MemFree(pMmcTablePhy2Log);
return TRUE;
}
//INT MmcModInitial(UINT32 uInitMode, VOID *buf)
INT MmcModInitial(void)
{
OPTION preempt_status;
NU_DRIVER_REQUEST request; /*device request*/
if ((g_pMmcDriver = GetIODriverFromName(DRV_NAME_SDCARD))== NULL) /*Get Lcd device handle*/
{
return FLASH_ERR_DRV; /*No default Lcd*/
}
/*得到Mmc基本信息*/
request.nu_function = NU_STATUS;
request.nu_supplemental = FLASH_IO_GETPARAM;
request.nu_request_info.nu_status.nu_logical_unit = 0;
NU_Request_Driver(g_pMmcDriver, &request);
if(request.nu_status != NU_SUCCESS)
return FLASH_ERR_DRV;
memcpy((UINT8 *)&g_MmcParam, request.nu_request_info.nu_status.nu_extra_status, sizeof(NFLASH_PARAMETER));
// g_MmcParam.uBlockNum /= 32;
/* memcpy((UINT8 *)pMmcParam, request.nu_request_info.nu_status.nu_extra_status, sizeof(NFLASH_PARAMETER));*/
/*申请全局Buffer*/
preempt_status = NU_Change_Preemption(NU_NO_PREEMPT);
{
g_MmcTableLog2Phy = (UINT8 *)MemAlloc(g_MmcParam.uBlockNum * sizeof(UINT16));
g_MmcTablePrepare = (UINT16 *)MemAlloc(g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
g_MmcTableBad = (UINT16 *)MemAlloc(g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
g_MmcReadBuf = (UINT8 *)MemAlloc(g_MmcParam.uBlockSize);
g_MmcSpareBuf = (UINT8 *)MemAlloc(g_MmcParam.uBlockSize / g_MmcParam.uDataSize * g_MmcParam.uSpareSize);
g_MmcEccBuf = (UINT8 *)MemAlloc(FLASH_PAGE_SIZE);
}
NU_Change_Preemption(preempt_status);
if(!g_MmcReadBuf || !g_MmcSpareBuf || !g_MmcEccBuf || !g_MmcTableLog2Phy)
return FLASH_ERR_MEM;
#ifdef FLASH_ERASE_COUNTER
if(__MmcGetEraseCounter() != TRUE)
return FLASH_ERR_COUNTER;
#endif
// victor for quick R/W
g_MmcPhyNum = -1;
g_MmcModify = 0;
g_MmcDirty = 0;
#if 1
return __MmcTableRead();
#endif
#if 0 //dennyhan
if( uInitMode == SYS_INIT_COLDRST )
{
/*读出Mmc对应表*/
return __MmcTableRead();
}
else
{
MFlashInitParam *pMmcInitParam;
pMmcInitParam =(MFlashInitParam *)buf;
/* TableExtract(g_MmcTableLog2Phy, pMmcInitParam->FlashTableLog2Phy, g_MmcParam.uBlockNum * sizeof(UINT16));
TableExtract((UINT8 *)g_MmcTablePrepare, (UINT8 *)pMmcInitParam->FlashTablePrepare, g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
TableExtract((UINT8 *)g_MmcTableBad, (UINT8 *)pMmcInitParam->FlashTableBad, g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
*/
memcpy(g_MmcTableLog2Phy, pMmcInitParam->FlashTableLog2Phy,g_MmcParam.uBlockNum * sizeof(UINT16));
memcpy(g_MmcTablePrepare, pMmcInitParam->FlashTablePrepare,g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
memcpy(g_MmcTableBad, pMmcInitParam->FlashTableBad, g_MmcParam.uPrepareBlockNum * sizeof(UINT16));
g_uMmcBlockUser = pMmcInitParam->uFlashBlockUser;
g_uMmcBlockBadUser = pMmcInitParam->uFlashBlockBadUser;
g_uMmcBlockPrepare = pMmcInitParam->uFlashBlockPrepare;
g_uMmcBlockBadNature = pMmcInitParam->uFlashBlockBadNature;
g_uMmcBlockBadReadFail = pMmcInitParam->uFlashBlockBadReadFail;
g_uMmcBlockBadUnknown = pMmcInitParam->uFlashBlockBadUnknown;
if(__MmcTableCheck() == FALSE)
return __MmcTableRead();
}
#endif
return FLASH_ERR_NONE;
}
/****************************************************************************/
/* FUNCTION: MmcIoCtrl */
/* DESCRIPTION:Mmc相关命令 */
/* INPUTS:
NONE */
/* OUTPUTS: NONE */
/* RETURN: 初始化成功返回成功状态“NU_SUCCESS”,否则返回失败状态 */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* 谢永良 2003-03-12 创建 */
/****************************************************************************/
INT CardIoCtrl(UINT16 driveno, UINT16 command, VOID *buffer)
{
INT flashErr;
driveno = driveno;
switch(command)
{
/*Mmc 低级格式化*/
case FLASH_COMMAND_FORMAT:
flashErr = __MmcTableCreate(TRUE);
if(flashErr == FLASH_ERR_NONE)
flashErr = __MmcTableRead();
return flashErr;
/*Mmc 查询相关信息*/
case FLASH_COMMAND_GETINFO:
((MFlashInfo *)buffer)->uPageSum = g_uMmcBlockUser * (g_MmcParam.uBlockSize / g_MmcParam.uDataSize);
((MFlashInfo *)buffer)->uPageSize = g_MmcParam.uDataSize;
return TRUE;
}
return FALSE;
}
INT MmcFormat(void)
{
return CardIoCtrl(0, FLASH_COMMAND_FORMAT, NULL);
}
/************************************************************************
* FUNCTION
*
* pc_flash_raw_open
*
* DESCRIPTION
*
* This function doesn't do anything for the FLASH Disk. It is
* included for devtable consistency.
*
* AUTHOR
*
* Victor Li
*
* INPUTS
*
* None.
*
* OUTPUTS
*
* None.
*
*************************************************************************/
INT CardRawOpen(UINT16 driveno)
{
driveno = driveno;
return FALSE;
}
/************************************************************************
* FUNCTION
*
* pc_flash_open
*
* DESCRIPTION
*
* This function prepares the FLASH Disk for usage by searching root
* directory and allocating a block memory for loading root directory.
*
* AUTHOR
*
* Victor Li
*
* INPUTS
*
* driveno The number assigned to the
* FLASH Disk (not used)
*
* OUTPUTS
*
* YES Successful Completion.
* NO Couldn't allocate all of the
* pages.
*
*************************************************************************/
INT CardOpen(UINT16 driveno)
{
/* We don't use drive no. You could have multiple drives if wanted */
driveno = driveno;
return TRUE;
}
/************************************************************************
* FUNCTION
*
* pc_flash_close
*
* DESCRIPTION
*
* This function deallocates all of the memory associated with the
* FLASH Disk. The actual code here is commented out since we
* probably don't want to loose the data on a close.
*
* AUTHOR
*
* Victor Li
*
* INPUTS
*
* driveno The number assigned to the
* FLASH Disk (not used)
*
* OUTPUTS
*
* YES Successful Completion.
* NO Couldn't allocate all of the
* pages.
*
*************************************************************************/
INT CardClose(UINT16 driveno)
{
driveno = driveno;
return TRUE;
}
/************************************************************************
* FUNCTION
*
* pc_flash_io
*
* DESCRIPTION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -