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

📄 mmcmng.c

📁 好记星的控件,包括button,list,对文件操作
💻 C
📖 第 1 页 / 共 4 页
字号:
        {
            if(__MmcWriteBytes(0, g_MmcEraseCounterBuf, g_MmcParam.uBlockSize, FALSE) != g_MmcParam.uBlockSize)
		        return FALSE;
        }
    }
    return TRUE;
}

#endif



INT    __MmcError(UINT16 wErr)
{
#ifdef  __DEBUG__
    NU_Printf("MmcError: %d \n", wErr);
    while(1)
        SysWatchClear();
#endif

    return FLASH_ERR_UNKNOW;
}

UINT16 __MmcBadRegister(UINT8 bBadType, UINT16 wBadBlock)
{
    UINT16  wBadTotal;
    UINT16  wInsert;

    wBadTotal = g_uMmcBlockBadUser + g_uMmcBlockBadNature +
        g_uMmcBlockBadReadFail + g_uMmcBlockBadUnknown;

    if(bBadType == FLASH_STATUS_BAD_USER)
        wInsert = g_uMmcBlockBadUser;
    else if(bBadType == FLASH_STATUS_BAD_NATURE)
        wInsert = g_uMmcBlockBadUser + g_uMmcBlockBadNature;
    else if(bBadType == FLASH_STATUS_BAD_READFAIL)
        wInsert = g_uMmcBlockBadUser + g_uMmcBlockBadNature + g_uMmcBlockBadReadFail;
    else if(bBadType == FLASH_STATUS_BAD_UNKNOWN)
        wInsert = g_uMmcBlockBadUser + g_uMmcBlockBadNature + g_uMmcBlockBadReadFail + g_uMmcBlockBadUnknown;

    if(wBadTotal > wInsert)
        memmove(&g_MmcTableBad[wInsert + 1], &g_MmcTableBad[wInsert], (wBadTotal - wInsert) * sizeof(UINT16));
    g_MmcTableBad[wInsert] = wBadBlock;

    return 0;
}

UINT16 __MmcBadDisplay(UINT8 bBadType)
{
/*    UINT8   szInfo[200];
    UINT16  wDispStart;
    UINT16  wDispNum;
    UINT16  i;

    if(bBadType == FLASH_STATUS_BAD_USER)
    {
        wDispStart = 0;
        wDispNum = g_uMmcBlockBadUser;
        sprintf(szInfo, "BadUser(%d):", wDispNum);
    }
    else if(bBadType == FLASH_STATUS_BAD_NATURE)
    {
        wDispStart = g_uMmcBlockBadUser;
        wDispNum = g_uMmcBlockBadNature;
        sprintf(szInfo, "BadNature(%d):", wDispNum);
    }
    else if(bBadType == FLASH_STATUS_BAD_READFAIL)
    {
        wDispStart = g_uMmcBlockBadUser + g_uMmcBlockBadNature;
        wDispNum = g_uMmcBlockBadReadFail;
        sprintf(szInfo, "BadReadFail(%d):", wDispNum);
    }
    else if(bBadType == FLASH_STATUS_BAD_UNKNOWN)
    {
        wDispStart = g_uMmcBlockBadUser + g_uMmcBlockBadNature + g_uMmcBlockBadReadFail;
        wDispNum = g_uMmcBlockBadUnknown;
        sprintf(szInfo, "BadUnknown(%d):", wDispNum);
    }

    for(i = 0; i < wDispNum; i ++)
        sprintf(&szInfo[strlen(szInfo)], "%d ", g_MmcTableBad[wDispStart + i]);

    szInfo[strlen(szInfo) + 1] = 0;
    szInfo[strlen(szInfo)] = '\n';

    NU_Printf(szInfo);
*/
    return 0;
}


UINT16 MmcBadDisplay()
{
    __MmcBadDisplay(FLASH_STATUS_BAD_USER);
    __MmcBadDisplay(FLASH_STATUS_BAD_NATURE);
    __MmcBadDisplay(FLASH_STATUS_BAD_READFAIL);
    __MmcBadDisplay(FLASH_STATUS_BAD_UNKNOWN);

    return 0;
}


/*读出Mmc对应表*/
INT	__MmcTableRead()
{
    BOOL    bPrepare;
    UINT8   status;
	UINT16	i;
    UINT16  wLogic, wCheck;
    UINT32  dwOffset;
    UINT8   pageStatusSpare[2][16];
    UINT8   pageCheckSpare[16];

	memset((VOID *)(g_MmcTableLog2Phy), 0xFF, g_MmcParam.uBlockNum * sizeof(UINT16));

    //建立初始化的逻辑物理对应表
    g_uMmcBlockUser = 0;
    g_uMmcBlockBadUser = 0;
    g_uMmcBlockPrepare = 0;
    g_uMmcBlockBadNature = 0;
    g_uMmcBlockBadReadFail = 0;
    g_uMmcBlockBadUnknown = 0;

	for(i = FLASH_BLOCK_TABLE; i < g_MmcParam.uBlockNum; i ++)
	{
		status = __MmcReadBlockStatus(i, (UINT8 *)pageStatusSpare);

        if(status == FLASH_STATUS_GOOD)
		{
            wLogic = *(UINT16 *)(&pageStatusSpare[0][FLASH_LOGIC_OFFSET]);

            dwOffset = (UINT32)(i + 1) * g_MmcParam.uBlockSize - g_MmcParam.uDataSize;
            if(__MmcReadSpareBytes(dwOffset, pageCheckSpare, g_MmcParam.uSpareSize) != g_MmcParam.uSpareSize)
                return __MmcError(2);
            wCheck = *(UINT16 *)(&pageCheckSpare[FLASH_CHECK_OFFSET]);

            //Check标志错
            if(wCheck != FLASH_CHECK_VALUE)
                bPrepare = TRUE;
            //备用块逻辑号标志
            else if(wLogic == FLASH_LOGIC_PREPARE)
                bPrepare = TRUE;
            //逻辑号大于最大理论值
            else if(wLogic >= g_MmcParam.uUserBlockNum)
                return __MmcError(5);
            //当前逻辑号已经被使用,需要比较Replace标志
            else if(*(UINT16 *)(g_MmcTableLog2Phy + wLogic * sizeof(UINT16)) != 0xFFFF)
            {
                UINT8   replaceNew, replacePrev;
                UINT16  wBlockPrev;

                //保留当前的Replace标志
                replaceNew = pageStatusSpare[0][FLASH_REPLACE_OFFSET];
                //得到前一个使用该逻辑号的物理块
                wBlockPrev = *(UINT16 *)(g_MmcTableLog2Phy + wLogic * sizeof(UINT16));

                //读取第一个Page的Spare区
                dwOffset = (UINT32) wBlockPrev * g_MmcParam.uBlockSize;
                if(__MmcReadSpareBytes(dwOffset, (UINT8 *)pageStatusSpare, 2 * g_MmcParam.uSpareSize) != 2 * g_MmcParam.uSpareSize)
                    return __MmcError(2);
                    //return FALSE;
                //得到前一个使用该逻辑号的物理块的Replace标志
                replacePrev = pageStatusSpare[0][FLASH_REPLACE_OFFSET];

                //发现当前的逻辑号才是正确的,前一个使用该逻辑号的物理块要做备用处理
                if((replacePrev + 1) % FLASH_REPLACE_MAXVALUE == replaceNew)
                {
                    if(g_uMmcBlockPrepare >= g_MmcParam.uPrepareBlockNum)
                        return FLASH_ERR_NOFORMAT;
                    g_MmcTablePrepare[g_uMmcBlockPrepare] = wBlockPrev;
                    g_uMmcBlockPrepare ++;
        			g_uMmcBlockUser --;
                    bPrepare = FALSE;
                }
                else
                    bPrepare = TRUE;
            }
            else
                bPrepare = FALSE;

            if(bPrepare == TRUE)
            {
                if(g_uMmcBlockPrepare >= g_MmcParam.uPrepareBlockNum)
                    return FLASH_ERR_NOFORMAT;
                g_MmcTablePrepare[g_uMmcBlockPrepare] = i;
                g_uMmcBlockPrepare ++;
            }
            else if(wLogic < g_MmcParam.uUserBlockNum)
            {
                *(UINT16 *)(g_MmcTableLog2Phy + wLogic * sizeof(UINT16)) = i;
    			g_uMmcBlockUser ++;
            }
            else
                return __MmcError(5);
                //return FALSE;
		}
        else if(status == FLASH_STATUS_BAD_USER)
        {
            __MmcBadRegister(FLASH_STATUS_BAD_USER, i);
            g_uMmcBlockBadUser ++;
        }
        else if(status == FLASH_STATUS_BAD_NATURE)
        {
            __MmcBadRegister(FLASH_STATUS_BAD_NATURE, i);
            g_uMmcBlockBadNature ++;
        }
        else if(status == FLASH_STATUS_BAD_READFAIL)
        {
            __MmcBadRegister(FLASH_STATUS_BAD_READFAIL, i);
            g_uMmcBlockBadReadFail ++;
        }
        else if(status == FLASH_STATUS_BAD_UNKNOWN)
        {
            __MmcBadRegister(FLASH_STATUS_BAD_UNKNOWN, i);
            g_uMmcBlockBadUnknown ++;
        }
	}

    if(g_uMmcBlockPrepare < 1)
        return FLASH_ERR_NOPREPARE;

    //检查逻辑物理对应表是否存在缺口
    for(i = 0; i < g_MmcParam.uUserBlockNum/*g_uMmcBlockUser*/; i ++)
    {
        if(*(UINT16 *)(g_MmcTableLog2Phy + i * sizeof(UINT16)) == 0xFFFF)
            return __MmcError(6);
            //return FALSE;
    }
    return FLASH_ERR_NONE;
}

VOID    __MmcBadError(UINT16 wBlock, UINT16 wErr)
{
#ifdef  __DEBUG__
    NU_Printf("MmcBad%d: %d \n", wErr, wBlock);
#endif
    return ;
}



UINT8	__MmcReadBlockStatus(UINT16 uBlock, UINT8* pSpareBuf)
{
	UINT32	dwOffset;
    UINT8   status1, status2;

    //读出前面两个Page的Spare区
    dwOffset = (UINT32) uBlock * g_MmcParam.uBlockSize;
    if(__MmcReadSpareBytes(dwOffset, pSpareBuf, 2 * g_MmcParam.uSpareSize) != 2 * g_MmcParam.uSpareSize)
        return FLASH_STATUS_BAD_READFAIL;

    pSpareBuf += FLASH_STATUS_OFFSET;
    status1 = *pSpareBuf;
    pSpareBuf += g_MmcParam.uSpareSize;
    status2 = *pSpareBuf;

    if((status1 == FLASH_STATUS_GOOD) && (status2 == FLASH_STATUS_GOOD))
        return FLASH_STATUS_GOOD;
    else if((status1 == FLASH_STATUS_BAD_NATURE) || (status2 == FLASH_STATUS_BAD_NATURE))
        return FLASH_STATUS_BAD_NATURE;
    else if((status1 == FLASH_STATUS_BAD_USER) || (status2 == FLASH_STATUS_BAD_USER))
        return FLASH_STATUS_BAD_USER;
    else
        return FLASH_STATUS_BAD_UNKNOWN;
}

/*重新建立Mmc对应表*/
INT	__MmcTableCreate(BOOL bShowProgress)
{
	UINT16	i/*, j*/;
    UINT16  wLogic;
    UINT32  dwOffset;
    UINT8   pageStatusSpare[2][16];
//    UINT32  dwEcc;

	//dennyhan changed the following
//    if(SysGetLowVoltageStatus() == SYSTEM_FLASH_LOWVOL)
//        return FLASH_ERR_LOWVOLTAGE;
//---------------------------------------------

    if(bShowProgress == TRUE)
    {
        NU_Printf("\nSDCard Erasing...\n");
    }
    //计算ECC
    memset(g_MmcReadBuf, 0xFF, g_MmcParam.uBlockSize);
    memset(g_MmcSpareBuf, 0xFF, g_MmcParam.uBlockSize / g_MmcParam.uDataSize * g_MmcParam.uSpareSize);

#ifdef  FLASH_ECC_CHECK
    dwEcc = __MmcEccCalc(g_MmcReadBuf);
    for(i = 0; i < g_MmcParam.uBlockSize / g_MmcParam.uDataSize; i ++)
    {
        //写每个Page的ECC
        dwOffset = (UINT32) i * g_MmcParam.uSpareSize + (FLASH_ECC_OFFSET - FLASH_PAGE_SIZE);
        memcpy(&g_MmcSpareBuf[dwOffset], &dwEcc, FLASH_ECC_LENGTH);
    }
#endif

    //写每块的Replace标志
    g_MmcSpareBuf[FLASH_REPLACE_OFFSET] = 0;

    //写每块的Check
    *(UINT16 *)(&g_MmcSpareBuf[FLASH_CHECK_OFFSET + 496]) = FLASH_CHECK_VALUE;

	/*擦除全部块数据*/
    wLogic = 0;
	for(i = 0; i < g_MmcParam.uBlockNum; i ++)
    {
        if((bShowProgress == TRUE) && (i % 50 == 0))
            NU_Printf(">");

        //擦除每块,检查这一块是否有效
        /*读每一块的状态*/
    	if(__MmcReadBlockStatus(i, (UINT8 *)pageStatusSpare) != FLASH_STATUS_GOOD)
        {
            __MmcBadError(i, 1);
            continue;
        }
        if(__MmcEraseBlock((UINT32)i * g_MmcParam.uBlockSize, FALSE) != TRUE)
        {
            __MmcBadError(i, 2);
            continue;
        }
#ifdef  FLASH_ERASE_COUNTER
        if(__MmcSetEraseCounter() != TRUE)
            return FLASH_ERR_COUNTER;
#endif

        //第一块不写逻辑号
        if(i < FLASH_BLOCK_TABLE)
            continue;
        //备份块写备份逻辑号
        if((wLogic >= g_MmcParam.uUserBlockNum) || (wLogic == FLASH_LOGIC_PREPARE))
//        if(i >= (g_MmcParam.uBlockNum - FLASH_BLOCK_PREPARE))
            wLogic = FLASH_LOGIC_PREPARE;

        //写每块的逻辑号到第一个Page
        dwOffset = (FLASH_LOGIC_OFFSET);
        *(UINT16 *)(&g_MmcSpareBuf[dwOffset]) = wLogic;

        //写整个Spare区到FALSH中
        dwOffset = (UINT32) i * g_MmcParam.uBlockSize;
        if(__MmcWriteSpareBytes(dwOffset, g_MmcSpareBuf,
            g_MmcParam.uBlockSize / g_MmcParam.uDataSize * g_MmcParam.uSpareSize,
            FALSE) !=
            g_MmcParam.uBlockSize / g_MmcParam.uDataSize * g_MmcParam.uSpareSize)
        {
            __MmcBadError(i, 8);
            continue;
        }

        if(wLogic != FLASH_LOGIC_PREPARE)
            wLogic ++;
	}

    if(bShowProgress == TRUE)
    {
        NU_Printf("\nErase End!");
        GraphResetLcdRange();
    }

    return FLASH_ERR_NONE;
}


/*逻辑页转化为物理页*/
UINT32	__MmcGetPhysicalPage(UINT32 dwLogicalPage)
{
	UINT32	dwBlock;
	UINT32	dwPhysicalPage;

	/*得到逻辑块*/
	dwBlock	= dwLogicalPage / (g_MmcParam.uBlockSize / FLASH_PAGE_SIZE);
	dwPhysicalPage	= dwLogicalPage % (g_MmcParam.uBlockSize / FLASH_PAGE_SIZE);
	/*加上保留的块*/
	if(dwBlock >= g_uMmcBlockUser)
		return 0;

	/*查表得到物理块*/
	dwBlock	= *(UINT16 *)(g_MmcTableLog2Phy + dwBlock * sizeof(UINT16));
	/*得到物理页*/
	dwPhysicalPage	+= dwBlock * (g_MmcParam.uBlockSize / FLASH_PAGE_SIZE);

	return dwPhysicalPage;
}

/*擦除一块FLASH*/
BOOL	__MmcEraseBlock(UINT32 dwOffset, BOOL bCreateBad)
{
    NU_DRIVER_REQUEST   request;                                    /*device request*/

    request.nu_function = NU_STATUS;
    request.nu_supplemental = FLASH_IO_ERASEBLK;
	request.nu_request_info.nu_status.nu_extra_status = (VOID *)dwOffset;
	request.nu_request_info.nu_status.nu_logical_unit = 0;
    NU_Request_Driver(g_pMmcDriver, &request);

    if(request.nu_status == NU_SUCCESS)
		return TRUE;
	else
		return FALSE;
}

/*从Mmc Data区读数据*/
UINT32	__MmcReadBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen)
{
    NU_DRIVER_REQUEST   request;                                    /*device request*/

    request.nu_function = NU_INPUT;
    request.nu_supplemental = FLASH_IO_ONLYDATA;
	request.nu_request_info.nu_input.nu_offset = dwOffset;
	request.nu_request_info.nu_input.nu_request_size = dwLen;
	request.nu_request_info.nu_input.nu_buffer_ptr = pBuff;
	request.nu_request_info.nu_status.nu_logical_unit = 0;

    NU_Request_Driver(g_pMmcDriver, &request);

	if(request.nu_status != NU_SUCCESS)
		return 0;
	else
		return request.nu_request_info.nu_input.nu_actual_size;
}

#ifdef USB_EVALUATE
#define EVALUATE_NUM		20
extern UINT8 g_nEvaluateFlag;
extern UINT8 g_nEvaluateTimes;
#endif

/*向Mmc Data区写数据*/
UINT32	__MmcWriteBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen, BOOL bCreateBad)
{
   NU_DRIVER_REQUEST   request;                                    /*device request*/

#ifdef USB_EVALUATE

		if(dwLen > 10*1024)
		{
			if(g_nEvaluateTimes++ == EVALUATE_NUM && g_nEvaluateFlag == USB_EVALUATE_RING1)
			{
				g_nEvaluateTimes = 0;
				g_nEvaluateFlag = USB_EVALUATE_RING2; // CHECK receive & write TIME
			}
		}

		if(g_nEvaluateFlag == USB_EVALUATE_RING1)	// do not actully write to flash when evaluate ring0
			return dwLen;
#endif


    request.nu_function = NU_OUTPUT;
    request.nu_supplemental = FLASH_IO_ONLYDATA;
	request.nu_request_info.nu_output.nu_offset = dwOffset;
	request.nu_request_info.nu_output.nu_request_size = dwLen;
	request.nu_request_info.nu_output.nu_buffer_ptr = pBuff;
	request.nu_request_info.nu_status.nu_logical_unit = 0;
// For evaluate the USB performance. mann.


    NU_Request_Driver(g_pMmcDriver, &request);

	if(request.nu_status != NU_SUCCESS)
		return 0;
	else
		return request.nu_request_info.nu_output.nu_actual_size;

}

/*从Mmc Spare区读数据*/
UINT32	__MmcReadSpareBytes(UINT32 dwOffset, UINT8* pBuff, UINT32 dwLen)
{
    NU_DRIVER_REQUEST   request;                                    /*device request*/

⌨️ 快捷键说明

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