flashmngl05.c

来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,671 行 · 第 1/5 页

C
1,671 行
字号

            retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

            if (retVal !=
                (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
            {
	        	if((retVal == NFLS_ERR_TIMEOUT) || (retVal == NFLS_ERR_ECC)){	// We must go ahead in spite of this block has some error
					// label this block to bad block
			        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
				        g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock,
			            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);
					error0 = TRUE;
					// Perhaps we should reset the flash at this time
					// ???????????????????????????
	   			}else{
	                return retVal;
	   			}
            }

            // write page to swap block
            if ((PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)
                && (!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_NODIRTY)))
            {
                address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
                    + i * g_pFlashParam->uDataPerPage;

                retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE,
                    address, g_pFlashBuf,
                    g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

                if (retVal !=
                    (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
                {
	            	if(retVal == NFLS_ERR_TIMEOUT){	// need swap g_FlashPhyNum1 to another block
						retVal = FlashMngBlockCopy(g_FlashPhyNum1, i);
						if(retVal < 0){
							return retVal;
						}
						g_FlashPhyNum1 = retVal;
						goto Block_Retry;
	            	}else{
		                return retVal;
	            	}
                }
            }
        }

        // set transfered flag(end transfer)
        retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
            g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock,
            g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

        if (retVal != (INT)g_pFlashParam->uSparePerPage)
        {
            return retVal;
        }

        BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_ORG;

        retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
            g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock,
            g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

        if (retVal != (INT)g_pFlashParam->uSparePerPage)
        {
            return retVal;
        }

        BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_PREPARE;

        retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
            g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock,
            g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

        if (retVal != (INT)g_pFlashParam->uSparePerPage)
        {
            return retVal;
        }

        for (i = 0; i < g_pFlashParam->uUserBlockNum; i++)
        {
            if (g_FlashTableLog2Phy[i] == g_FlashPhyNum0)
            {
                g_FlashTableLog2Phy[i] = g_FlashPhyNum1;
                break;
            }
        }

		if(error0 == TRUE){
		    for(i = 1; i < g_uFlashBlockPrepare; i++){
				g_FlashTablePrepare[i - 1] = g_FlashTablePrepare[i];
		    }
			g_uFlashBlockPrepare --;
		}else{
	        g_FlashTablePrepare[0] = g_FlashPhyNum0;
		}
    }

    return NFLS_ERR_NO;
}

/********************************************************************************/
/* FUNCTION:   FlashMngPageUpdate                                              */
/* DESCRIPTION:Update buffer to flash                                          */
/* INPUTS:                                                                      */
/* OUTPUTS:                                                                    */
/* RETURN:     NFLS_ERR_NO         ok                                          */
/*              return from FlashMngWriteDriver                                 */
/*              return from FlashMngReadDriver                                  */
/*              return from FlashMngBlockSwap                                   */
/********************************************************************************/
/*    NAME        DATE                REMARKS                                   */
/* ==========  ============   ==================================================*/
/*   Victor     2005-05-10      create                                          */
/********************************************************************************/
INT FlashMngPageUpdate(void)
{
    INT     retVal;//, i;
    UINT    i;
    UINT8   flashSpareBuf[64];
    UINT32  address;

Page_Retry:

    if (g_FlashModify)      // need update buffer to flash
    {
        if (g_FlashDirty)   // update to swap block
        {
            // if current page has been modified, must update block
            address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            FlashMngReadDriver(FLASH_IO_ONLYSPARE, address,
                &flashSpareBuf[0], g_pFlashParam->uSparePerPage);

            if (!(PAGE_STATUS(flashSpareBuf) & PAGE_STATUS_NODIRTY))
            {
                return FlashMngBlockSwap();
            }

            // set dirty flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_NODIRTY;

            // set available flag
            PAGE_STATUS(g_pFlashSpareBuf) |= PAGE_STATUS_AVAILABLE;

            if (g_FlashPageOffset == 0)
            {
                BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAP;
            }

            // write buffer to swap block
            address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

            if (retVal !=
                (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
            {
            	if(retVal == NFLS_ERR_TIMEOUT){	// need swap g_FlashPhyNum1 to another block
					retVal = FlashMngBlockCopy(g_FlashPhyNum1, g_FlashPageOffset);
					if(retVal < 0){
						return retVal;
					}
					g_FlashPhyNum1 = retVal;
					goto Page_Retry;
            	}else{
	                return retVal;
            	}
            }

            // abolish page in org block

            // set inavailable flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_AVAILABLE;

            address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE, address,
                g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

            if (retVal != (INT)g_pFlashParam->uSparePerPage)
            {
                return retVal;
            }
        }
        else    // update to org block
        {
            // set dirty flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_NODIRTY;

            // set available flag
            PAGE_STATUS(g_pFlashSpareBuf) |= PAGE_STATUS_AVAILABLE;

            // write buffer to org block
            address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

            if (retVal !=
                (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
            {
            	if(retVal == NFLS_ERR_TIMEOUT){	// need swap g_FlashPhyNum0 to another block
					retVal = FlashMngBlockCopy(g_FlashPhyNum0, g_FlashPageOffset);
					if(retVal < 0){
						return retVal;
					}
			        for (i = 0; i < g_pFlashParam->uUserBlockNum; i++)
			        {
			            if (g_FlashTableLog2Phy[i] == g_FlashPhyNum0)
			            {
			                g_FlashTableLog2Phy[i] = retVal;
			                break;
			            }
			        }
					g_FlashPhyNum0 = retVal;
					goto Page_Retry;
            	}else{
	                return retVal;
            	}
            }
        }
    }

    return NFLS_ERR_NO;
}

/********************************************************************************/
/* FUNCTION:   FlashMngReadPhyEraseUnit                                        */
/* DESCRIPTION:updata buffer to flash and load current page to buffer          */
/* INPUTS:      dwPhysicalPage      physical page                               */
/*              dwLogicalPage       logical page                                */
/* OUTPUTS:                                                                    */
/* RETURN:     >=0                 page offset in buffer                       */
/********************************************************************************/
/*    NAME        DATE                REMARKS                                   */
/* ==========  ============   ==================================================*/
/*   Victor     2005-05-10      create                                          */
/********************************************************************************/
INT FlashMngReadPhyEraseUnit(INT dwPhysicalPage, INT dwLogicalPage)
{
    INT curEraseNum, dwOffset;
    INT retVal;
    UINT32 address;

    // get erase unit number which contains "dwPhysicalPage"
    curEraseNum = dwPhysicalPage * NORMAL_PAGE_SIZE / g_pFlashParam->uDataPerBlock;
    dwOffset = (dwPhysicalPage % (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE))
        / (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE);

    // block update
    if (curEraseNum != g_FlashPhyNum0)
    {
        if (g_FlashPhyNum0 != -1)
        {
            if ((retVal = FlashMngBlockUpdate()) != NFLS_ERR_NO)
            {
                return retVal;
            }
        }

        g_FlashPhyNum0 = curEraseNum;
        g_FlashPhyNum1 = -1;
        g_FlashPageOffset = dwOffset;
        g_FlashModify = FALSE;
        g_FlashDirty = FALSE;
    }
    else if (dwOffset != g_FlashPageOffset)     // page update
    {
        if ((retVal = FlashMngPageUpdate()) != NFLS_ERR_NO)
        {
            return retVal;
        }

        g_FlashPageOffset = dwOffset;
        g_FlashModify = FALSE;
    }
    else
    {
        return (dwPhysicalPage % (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE))
            * NORMAL_PAGE_SIZE;
    }

    address =  g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
        + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

    retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
        g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

    if (retVal !=
        (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
    {
        return retVal;
    }


    if ((g_FlashDirty == TRUE)
        && !(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE))
    {
        address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
            + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

        retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
            g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

        if (retVal !=
            (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
        {
            return retVal;
        }
    }

    return (dwPhysicalPage % (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE))
        * NORMAL_PAGE_SIZE;
}

/********************************************************************************/
/* FUNCTION:   FlashUpdate                                                     */
/* DESCRIPTION:Update buffer to flash, incorporate org block and swap block    */
/* INPUTS:                                                                      */
/* OUTPUTS:                                                                    */
/* RETURN:     NFLS_ERR_NO         ok                                          */
/*              return from FlashMngBlockUpdate                                 */
/********************************************************************************/
/*    NAME        DATE    

⌨️ 快捷键说明

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