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

📄 drv_29lv160.c

📁 motorola mpc系列 mpc852cpu bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
    int cLength, iRawWiteLen;
    volatile _U16 *flashPtr;
    volatile _U16 *gBuffer;
#ifdef DRV_DEBUG_FLASH
    int i;
#endif

    flashPtr    = (volatile _U16 *)ulFlashAddr;
    cLength     = (int)((ulLength + 1)/2);         /* 计算半字长度. */
    iRawWiteLen = cLength;
    gBuffer     = (_U16 *)ulRamAddr;

#ifdef DRV_DEBUG_FLASH
    (void)Drv_Print("\r\n Write 0x%x, from 0x%x, size is 0x%x", ulFlashAddr, ulRamAddr, ulLength);
#endif
    while( cLength > 0 )
    {
        *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_14CYC_CMD;          
        *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_25CYC_WORD_ADDR)   = DRV_29LV160_25CYC_CMD;
        *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_PROGRAM_CMD;
        *flashPtr = *gBuffer;

        /* 检测写入是否成功. */
        if(Drv_29LV160_Detect( (_U16 *)flashPtr, *gBuffer) )
        {
#ifdef DRV_DEBUG_FLASH
            (void)Drv_Print("\r\n warning: write flash may failed at:0x%x.", (int)flashPtr);
            return FAILURE;
#endif
        }
        cLength--;
        flashPtr++;
        gBuffer++;

        /* 每block清狗4次 */
        if( cLength%(iRawWiteLen/4) == 0 )
        {
            if( funcgDrvFeedDogHook != NULL )
            {
                funcgDrvFeedDogHook();
            }

            Drv_FeedHardWatchDog();
        }
    }

#ifdef DRV_DEBUG_FLASH
    flashPtr = (volatile _U16 *)ulFlashAddr;
    gBuffer  = (_U16 *)ulRamAddr;
    cLength  = ulLength/2;
    for( i = 0; i < cLength; i++)            /*写入的数据全部校验一次.*/
    {
        if( *flashPtr++ != *gBuffer++ )
        {
            (void)Drv_Print("\r\n Error(%d): write failed in SST39vf160 at 0x%x on verification.",
                      __LINE__, (int)flashPtr);
            return FAILURE;
        }
    }
    if( ulLength%2 )
    {
        if( (*flashPtr++ & 0x00ff) != (*gBuffer++ & 0x00ff) )   /*奇数长度的最后一个字节.*/
        {
            (void)Drv_Print("\r\n Error(%d): write failed in SST39vf160 at 0x%x on verification.",
                      __LINE__, (int)flashPtr);
            return FAILURE;
        }
    }
#endif

    Drv_29LV160Reset();

    return SUCCESS;
}

/* 可能会报告擦除检测失败,原因在于检测时间太短,正常擦除全部2M需要30秒,我们的检测时间只有5秒 */
void Drv_29LV160EraseChip(void)
{
#ifdef DRV_DEBUG_FLASH
    volatile _U16 *flashPtr = NULL;
    int i;
#endif

    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_14CYC_CMD;            /*连续解锁.*/
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_25CYC_WORD_ADDR)   = DRV_29LV160_25CYC_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_ERASE_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_14CYC_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_25CYC_WORD_ADDR)   = DRV_29LV160_25CYC_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_ERASE_CHIP_CMD;            /*写入擦除命令.*/

    if( Drv_29LV160_Detect((_U16 *)FLASH_START_ADDR, 0xffff) != SUCCESS )
    {
#ifdef DRV_DEBUG_FLASH
        (void)Drv_Print("\r\n warning: Chip Erase time out!");
#endif
    }

#ifdef DRV_DEBUG_FLASH
    /* 校验是否全为0xffff. */
    flashPtr = (volatile _U16 *)FLASH_START_ADDR;
    for( i = 0; i < FLASH_SIZE; i += 2, flashPtr++ )
    {
       if( *flashPtr != 0xffff )
       {
            (void)Drv_Print("\r\n Debug: Erase failed at 0x%x. Read value is 0x%x.", (int)flashPtr, *flashPtr);
            Drv_29LV160Reset();
            return;
       }
    }
#endif

    Drv_29LV160Reset();

    return;
}

void Drv_29LV160EraseBlock(_U32 ulBlockBaseAddr)
{
#ifdef DRV_DEBUG_FLASH
    volatile _U16 *flashPtr = NULL;
    int i;
#endif

    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_14CYC_CMD;            /*连续解锁.*/
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_25CYC_WORD_ADDR)   = DRV_29LV160_25CYC_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_ERASE_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_1346CYC_WORD_ADDR) = DRV_29LV160_14CYC_CMD;
    *((volatile _U16 *)FLASH_START_ADDR + DRV_29LV160_25CYC_WORD_ADDR)   = DRV_29LV160_25CYC_CMD;
    *(volatile _U16 *)ulBlockBaseAddr = DRV_29LV160_ERASE_SECTOR_CMD;

    if( Drv_29LV160_Detect((_U16 *)ulBlockBaseAddr, 0xffff) != SUCCESS )
    {
#ifdef DRV_DEBUG_FLASH
        (void)Drv_Print("\r\n warning: Chip Erase time out!\n");
#endif
        return;
    }
#ifdef DRV_DEBUG_FLASH
    /* 校验是否全为0xffff. */
    flashPtr = (volatile _U16 *)ulBlockBaseAddr;
    for( i = 0; i < DRV_29LV160_BLOCK_SIZE/2; i += 2, flashPtr++ )
    {
       if( *flashPtr != 0xffff )
       {
            (void)Drv_Print("\r\n Debug: Erase failed at 0x%x. Read value is 0x%x.", (int)flashPtr, *flashPtr);
            Drv_29LV160Reset();
            return;
       }
    }
#endif

    Drv_29LV160Reset();

    return;
}

void Drv_29LV160Read(_U32 ulFlashAddr, _U32 ulLength, _U32 ulRamAddr)
{

    if (ulLength > FLASH_SIZE)
    {
        return;
    }

    memcpy((void *)ulRamAddr, (void *)ulFlashAddr, ulLength);
}

void Drv_29LV160Reset(void)
{
    *(volatile _U16 *)(FLASH_START_ADDR)  = DRV_29LV160_RESET_CMD;
    return;
}

_U32 Drv_ReadFlash(_U32 ulFlashAddr, _U32 ulLength, _U32 ulRamAddr)
{
    if (ucgDrvFlashDebugFlag != 0)
    {
        (void)Drv_Print("\r\n Read flash 0x%x, length is 0x%x, to 0x%x.",
            ulFlashAddr, ulLength, ulRamAddr);
    }
    Drv_29LV160Reset();

    Drv_29LV160Read(ulFlashAddr, ulLength, ulRamAddr);

    return SUCCESS;
}

_U32 Drv_WriteFlash(_U32 ulFlashAddr, _U32 ulLength, _U32 ulRamAddr)
{
    long    WriteCount = 0;
    _U8     *pSrc, *pDst, *pTmp;
    _U32    ulAddrBlockEdge, ulWriteLen = 0, ulCurBlockSize;


    if( ucgDrvFlashDebugFlag != 0 )
    {
        (void)Drv_Print( "\r\n Write flash 0x%x, length is 0x%x, from 0x%x.",
                         ulFlashAddr, ulLength, ulRamAddr );
    }
    if( (ulFlashAddr < FLASH_START_ADDR)
      ||(ulFlashAddr > FLASH_END_ADDR) )
    {
        (void)Drv_Print("\r\n Input flash address error, FlashAddr = 0x%lx", ulFlashAddr);
        return FAILURE;
    }

    /* Get input parameter */
    pTmp = (_U8 *)ulFlashAddr;
    pSrc = (_U8 *)ulRamAddr;
    WriteCount = (long)ulLength;

    while( WriteCount > 0 )
    {
        /* Block size will change by address */
        ulCurBlockSize  = Drv_29LV160GetBlockSize( (_U32)pTmp );
        /* Get current writing flash block address */
        ulAddrBlockEdge = ( (_U32)pTmp & ~(ulCurBlockSize - 1) );

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

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

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

        /* Get write count */
        if( (_U32)WriteCount + ulFlashAddr - ulAddrBlockEdge >= ulCurBlockSize )
        {
            ulWriteLen = ulAddrBlockEdge + ulCurBlockSize - ulFlashAddr;
        }
        else
        {
            /* If last block, only write remain content */
            ulWriteLen = (_U32)WriteCount;
        }

        /* If content is same in a block, no erase no write */
        if( memcmp(pDst, pSrc, ulWriteLen) != 0 )
        {
            memcpy((char *)pDst, (char *)pSrc, ulWriteLen);

            if( funcgDrvFeedDogHook != NULL )
            {
                funcgDrvFeedDogHook();
            }
            Drv_FeedHardWatchDog();

            Drv_29LV160EraseBlock( ulAddrBlockEdge );

            if( funcgDrvFeedDogHook != NULL )
            {
                funcgDrvFeedDogHook();
            }
            Drv_FeedHardWatchDog();



            if( Drv_29LV160Write(ulAddrBlockEdge, ulCurBlockSize, (_U32)aucgBlockMapMem) != SUCCESS )
            {
                return FAILURE;
            }
        }

        pTmp = (_U8 *)(ulAddrBlockEdge + ulCurBlockSize);

        WriteCount -= (long)ulWriteLen;

        ulFlashAddr += ulWriteLen;
    }
    return SUCCESS;
}

_U32 Drv_FlashTestWrite( _U8 *FlashAddr, _U32 ByteCount, _U8 *RamAddr )
{
    return Drv_29LV160Write((_U32)FlashAddr, (_U32)ByteCount, (_U32)RamAddr);
}

_U32 Drv_FlashDebug(_U32 ulDebugFlag)
{
    if (ulDebugFlag == 0)
    {
        ucgDrvFlashDebugFlag = 0;
    }
    else
    {
        ucgDrvFlashDebugFlag = 1;
    }
    return 0;
}

_U32 Drv_WriteFlashDelay( _U32 FlashAddr, _U32 ByteCount, _U32 RamAddr )
{
    return Drv_WriteFlash(FlashAddr, ByteCount, RamAddr);
}



⌨️ 快捷键说明

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