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

📄 drv_28f128.c

📁 Flash型号: 28F128 功能说明:驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
        WriteFlashStatus( (_U16 *)FlashAddr, WRITE_FLASH_BYTE ) ;

        /* Actual data write to flash address */
        WriteFlashStatus( (_U16 *)FlashAddr, *pucValue ) ;

        ucByte = ReadFlashStatus( (_U16 *)FlashAddr ) ;

        loop = 0 ;
        /* Poll CSR until CSR.7 = 1 (WSM) */
        while ((!(BIT_7 & ucByte)) && (loop ++ < ESR_POLLING_TIMEOUT))
        {
		    if ((DELAY_WRITE == Drv_FlashStatus)&&(loop % 2048 == 0))
			{
//			   	Drv_Print("\r\n %d",__LINE__);
			    (void)taskDelay(1);
			}
            ucByte = ReadFlashStatus( (_U16 *)FlashAddr ) ;
        }

        if (loop >= ESR_POLLING_TIMEOUT)
        {
            return FAILURE;
        }

	    if ((DELAY_WRITE == Drv_FlashStatus)&&(cnt % (FLASH_BLOCK_SIZE/16) == 0))
		{
//		   	Drv_Print("\r\n %d",__LINE__);
		    (void)taskDelay(1);
		}

        FlashAddr++ ;
        pucValue++;


    }
    if (DELAY_WRITE == Drv_FlashStatus)
    {
//    	Drv_Print("\r\n %d",__LINE__);
        (void)taskDelay(1);
    }

	FlashAddr--;
    /* Switch to read array status */
    WriteFlashStatus( (_U16 *)FlashAddr, CLEAR_FLASH_STATUS ) ;
    WriteFlashStatus( (_U16 *)FlashAddr, READ_FLASH_ARRAY ) ;

    return SUCCESS;
}

/****************************************************************************
 function    : write flash status register
 return      : void
****************************************************************************/
void WriteFlashStatus( _U16 *FlashAddr, _U16 value )
{
     FlashAddr[0] = value;
}

/****************************************************************************
 function    : read flash status register
 return      : flash status
****************************************************************************/
_U16 ReadFlashStatus( _U16 *FlashAddr )
{
    WriteFlashStatus((_U16 *)FlashAddr, READ_FLASH_STATUS);
    return( *(_U16 *)FlashAddr ) ;
}

/****************************************************************************
 function    : erase flash by block
 return      : SUCCESS if erase success
               FAILURE if erase fail
****************************************************************************/
_U32 FlashErase(_U16 *addr)
{
    _U32 loop;
    _U8 ucByte;
    _U32 ErasAddr;

//    Drv_Print("\r\n Call Erase Flash!");

    ErasAddr = (_U32)addr & FLASH_BLOCK_MASK;

	/* clear lock bit */
    WriteFlashStatus( (_U16 *)ErasAddr, SET_FLASH_LOCK_CMD1 ) ;
    WriteFlashStatus( (_U16 *)ErasAddr, RESUME_FLASH_CMD ) ;
    ucByte = (_U8)ReadFlashStatus( (_U16 *)ErasAddr ) ;

    /* Poll CSR until CSR.7 = 1 (WSM) */
    loop = 0 ;
    while ((!(BIT_7 & ucByte)) && (loop ++ < ESR_POLLING_TIMEOUT))
    {
        ucByte = (_U8)ReadFlashStatus( (_U16 *)ErasAddr ) ;
    }

    if (loop >= ESR_POLLING_TIMEOUT)
    {
        Drv_Print("\r\n line %d",__LINE__);
        return FAILURE;
    }


    /* Switch to read array status */
    WriteFlashStatus( (_U16 *)ErasAddr, CLEAR_FLASH_STATUS ) ;
    WriteFlashStatus( (_U16 *)ErasAddr, READ_FLASH_ARRAY ) ;

    /* Write Erase Command 20H */
    WriteFlashStatus((_U16 *)ErasAddr, ERASE_FLASH_BLOCK);
    /* Write Confirm Command D0H */
    WriteFlashStatus((_U16 *)ErasAddr, RESUME_FLASH_CMD);

    if (DELAY_WRITE == Drv_FlashStatus)
    {
//       	Drv_Print("\r\n %d",__LINE__);
        (void)taskDelay(1);
    }

    ucByte = (_U8)ReadFlashStatus( (_U16 *)ErasAddr ) ;


    /* Poll CSR until CSR.7 = 1 (WSM) */
    loop = 1 ;
    while ((!(BIT_7 & ucByte)) && (loop ++ < ESR_POLLING_TIMEOUT))
    {
	    if ((DELAY_WRITE == Drv_FlashStatus)&&(loop%50 == 0))
	    {
//	    	Drv_Print("\r\n %d",__LINE__);
	        (void)taskDelay(1);
	    }
        ucByte = (_U8)ReadFlashStatus( (_U16 *)ErasAddr ) ;
    }

    if (loop >= ESR_POLLING_TIMEOUT)
    {
        Drv_Print("\r\n line %d",__LINE__);
        return FAILURE;
    }
    /* Switch to read array status */
    WriteFlashStatus( (_U16 *)ErasAddr, CLEAR_FLASH_STATUS ) ;
    WriteFlashStatus( (_U16 *)ErasAddr, READ_FLASH_ARRAY ) ;

    return SUCCESS;
}

//小心重入
_U32 Drv_WriteFlashDelay( _U32 FlashAddr, _U32 ByteCount, _U32 RamAddr )
{
    _U32 ret = SUCCESS;

    if (DEFAULT_STATUS == Drv_FlashStatus)
    {
        Drv_FlashStatus = DELAY_WRITE;
        ret = Drv_WriteFlash(FlashAddr,ByteCount,RamAddr );
        Drv_FlashStatus = DEFAULT_STATUS;
    }
    else
    {
        Drv_Print("\r\n !!!ReCall Drv_WriteFlashDelay!!! ");
        ret = FAILURE;
    }

    return ret;
}


//以下程序为判断是否不擦除block直接写flash的程序,发现很慢.不用
#if 0
_U32 Drv_WriteFlash( _U32 FlashAddr, _U32 ByteCount, _U32 RamAddr )
{
    if (DEFAULT_STATUS == Drv_FlashStatus)
        return Drv_WriteFlashIO(FlashAddr,ByteCount,RamAddr );
    else
    {
        Drv_Print("\r\n ReCall Drv_WriteFlash!");
        return FAILURE;
    }
}

static _U32 CheckFlashMem(_U32 pMem , _U32 pFlashBlock , _U32 Length , _U8 *retStatus, _U32 *StartOffset,_U32 *EndOffset)
{
    _U32 CompLen;
    _U8  *pMemValue , *pFlashValue , TmpValue;

    if ((retStatus==NULL)||(StartOffset==NULL)||(EndOffset==NULL))
        return FAILURE;

    *StartOffset = 0;
	*EndOffset = Length;
    *retStatus = FLASH_NO_OPERATOR;
    pMemValue = (_U8 *)pMem;
    pFlashValue = (_U8 *)pFlashBlock;

    CompLen = Length;
    while (CompLen != 0)
    {
        if (*pMemValue != *pFlashValue)
        {
			if (0 == *StartOffset)
				*StartOffset = Length - CompLen;

            *retStatus = FALSH_DIREC_WRITE;
            TmpValue = *pMemValue & *pFlashValue;
			*EndOffset = Length - CompLen;

            if (TmpValue != *pMemValue)
            {
                *retStatus = FALSH_ERASE_WRITE;
                return SUCCESS;
            }
        }
        pMemValue++;
        pFlashValue++;
        CompLen--;
    }
    return SUCCESS;

}

/*****************************************************************************
function :     write flash
return   :     SUCCESS if write success
               FAILURE if write fail
******************************************************************************/
_U32 Drv_WriteFlashIO( _U32 FlashAddr, _U32 ByteCount, _U32 RamAddr )
{
        _U32 AddrTemp, StartOffset,EndOffset,  LenTmp = 0;
        long WriteCount = 0;
        _U8 *pSrc, *pDst, *pTmp , retStatus;

        /* Check input flash address */
        if ( (FlashAddr < FLASH_START_ADDR)
           ||(FlashAddr > FLASH_END_ADDR) )
        {
            Drv_Print("\r\n Input flash address error, FlashAddr = 0x%lx", FlashAddr);
            return FAILURE;
        }

        /* Get flash address(in flash) */
        pTmp = (_U8 *)FlashAddr;

        /* Remained byte count that wait to write into flash */
        WriteCount = (long)ByteCount;

        /* Source address(in ram) */
        pSrc = (_U8 *)RamAddr;

        while (WriteCount > 0)
        {
            /* Get current writing flash block address */
            AddrTemp = (_U32)pTmp & FLASH_BLOCK_MASK;

            /* Read current block to  BlockMapMem */
            if (Drv_ReadFlash(AddrTemp, FLASH_BLOCK_SIZE, (_U32)(_U8*)BlockMapMem) != SUCCESS)
            {
                Drv_Print("\r\n ReadFlash error!");
                return FAILURE;
            }

            /* Get writing ram address(in ram), offset from 0 to ByteCount */
            pSrc = (_U8 *)(pSrc + LenTmp);

            /* Get writing block address(in BlockMapMem), because AddrTemp in block,
               so offset is (FlashAddr - AddrTemp), base is BlockMapMem. BlockMapMem
               is map of flash */
            pDst = (_U8 *)(FlashAddr - AddrTemp + BlockMapMem);

            /* Get write count */
            if ((_U32)WriteCount + FlashAddr - (FlashAddr & FLASH_BLOCK_MASK) >= FLASH_BLOCK_SIZE)
            {
                LenTmp = AddrTemp + FLASH_BLOCK_SIZE - FlashAddr;
            }
            else
            {
                /* If last block, only write remain content */
                LenTmp = (_U32)WriteCount;
            }


            if  (FAILURE == CheckFlashMem((_U32)pSrc, (_U32)pDst, LenTmp, &retStatus, &StartOffset, &EndOffset))
            {
                Drv_Print("\r\n CheckFlashMem Error! \r\n");
                return FAILURE;

            }

            /* If content is same in a block, no erase no write */
            if (retStatus == FALSH_ERASE_WRITE)
            {
                memcpy((char *)(pDst+StartOffset), (char *)(pSrc+StartOffset), LenTmp-StartOffset);

                if (FlashErase((_U16 *)AddrTemp) == FAILURE)
                {
                    Drv_Print("\r\n Erase error!");
                }

                (void)WriteFlashSeg((_U16 *)AddrTemp, FLASH_BLOCK_SIZE, BlockMapMem);
            }
            else if (retStatus == FALSH_DIREC_WRITE)
            {
                (void)WriteFlashSeg((_U16 *)(AddrTemp+pDst + StartOffset) , (EndOffset-StartOffset), (_U8 *)(pSrc + StartOffset));
            }

            pTmp = (_U8 *)(AddrTemp + FLASH_BLOCK_SIZE);

            WriteCount -= (long)LenTmp;

            FlashAddr += LenTmp;
        }

        return SUCCESS;
}
#endif

//以下为FLASH测试程序,先擦除一个block,在直接写block,一个一个block地测试
_U8 TestBlock[0x20000];
_U8 CmpBlock[0x20000];
void TestFlashQuick()
{
    _U32 FlashAddr;
    _U32 i;
    _U32 *pValue;

    FlashAddr = FLASH_BASE_ADDR;

    while(FlashAddr != FLASH_BASE_ADDR + FLASH_SIZE)
    {
        (void)FlashErase((_U16 *)FlashAddr);
        pValue = (_U32 *)TestBlock;
        for (i = 0;i<0x20000;i+=4)
        {
            *pValue = i;
            pValue++;
        }
        Drv_Print("\r\n Begin WriteSeg...");

        if (FAILURE == WriteFlashSeg((_U16 *)FlashAddr, FLASH_BLOCK_SIZE, TestBlock))
        {
		    Drv_Print(" fail!addr:0x%x",FlashAddr);
        }
        else
        {
		    Drv_Print(" ok!addr:0x%x",FlashAddr);
        }

        (void)Drv_ReadFlash( FlashAddr, 0x20000, (_U32)CmpBlock );

        Drv_Print("\r\n compary block...");

        if (memcmp(CmpBlock,TestBlock,0x20000)!=0)
        {
		    Drv_Print(" fail!addr:0x%x",FlashAddr);
        }
        else
        {
		    Drv_Print(" ok!addr:0x%x",FlashAddr);
        }

        FlashAddr = FlashAddr + 0x20000;
    }

    Drv_Print("\r\n Quick Test Flash Over!!");
}

void Drv_TestFlashAll(void)
{
    _U32 FlashAddr;
    _U32 i;
    _U32 *pValue;
    _U32 AddCount = 0;

    FlashAddr = FLASH_BASE_ADDR;

    Drv_Print("\r\n Begin Write Data:");
	i = 1;
    while(FlashAddr != FLASH_BASE_ADDR + FLASH_SIZE)
    {
        (void)FlashErase((_U16 *)FlashAddr);
        pValue = (_U32 *)TestBlock;
        AddCount = 0;
        while(AddCount<0x20000)
        {
            *pValue = i;
            pValue++;
            i += 4;
            AddCount += 4;
        }

        if (FAILURE == WriteFlashSeg((_U16 *)FlashAddr, FLASH_BLOCK_SIZE, TestBlock))
        {
        	Drv_Print("\r\n Write flash seg failed.");
        }
		Drv_Print("#");
        FlashAddr = FlashAddr + 0x20000;
    }

    Drv_Print("\r\n end write data!");

    FlashAddr = FLASH_BASE_ADDR;
	i = 1;
    while(FlashAddr != FLASH_BASE_ADDR + FLASH_SIZE)
    {

        pValue = (_U32 *)TestBlock;
        AddCount = 0;
        while(AddCount<0x20000)
        {
            *pValue = i;
            pValue++;
            i += 4;
            AddCount += 4;
        }

        (void)Drv_ReadFlash( FlashAddr, 0x20000, (_U32)CmpBlock );


        Drv_Print("\r\n Compary block!addr:0x%x...",FlashAddr);

        if (memcmp(CmpBlock,TestBlock,0x20000)!=0)
        {
            Drv_Print("Block error!");
        }
        else
        {
        	Drv_Print("OK!");
        }

        FlashAddr = FlashAddr + 0x20000;

    }

    Drv_Print("\r\n Test all flash over!!");
}

⌨️ 快捷键说明

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