📄 drv_28f128.c
字号:
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 + -