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

📄 drv_29lv160.c

📁 motorola mpc系列 mpc852cpu bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "vxWorks.h"
#include "config.h"
#include "typedef.h"
#include "Bsp.h"


#define DRV_29LV160_BIT_7                   0x8080
#define DRV_29LV160_BIT_6                   0x4040

#define DRV_29LV160_1346CYC_WORD_ADDR       0x555
#define DRV_29LV160_25CYC_WORD_ADDR         0x2AA

#define DRV_29LV160_14CYC_CMD               0xAAAA
#define DRV_29LV160_25CYC_CMD               0x5555

#define DRV_29LV160_RESET_CMD               0xF0F0
#define DRV_29LV160_PROGRAM_CMD             0xA0A0
#define DRV_29LV160_ERASE_CMD               0x8080
#define DRV_29LV160_ERASE_CHIP_CMD          0x1010
#define DRV_29LV160_ERASE_SECTOR_CMD        0x3030
#define DRV_29LV160_ID_CODE_CMD             0x9090

#define DRV_29LV160_TIMEOUT                 0x800000

#define DRV_29LV160_TYPE_TOP_BOOT           0xC4
#define DRV_29LV160_TYPE_BOTTOM_BOOT        0x49
#define DRV_29GL320_TYPE_TOP_BOOT           0x7E01
#define DRV_29GL320_TYPE_BOTTOM_BOOT        0x7E00
#define DRV_MX29LV320_TYPE_TOP_BOOT         0xA7
#define DRV_MX29LV320_TYPE_BOTTOM_BOOT      0xA8

#define DRV_29LV160_BLOCK_SIZE              0x00010000

_U8  aucgBlockMapMem[DRV_29LV160_BLOCK_SIZE];
_U8  ucgDrvFlashDebugFlag = 0;
_U32 ulgDrvFlashType = DRV_29LV160_TYPE_BOTTOM_BOOT;
Drv_Func funcgDrvFeedDogHook = NULL;

extern _U32 ulgDrvFlashLength;
extern void Drv_FeedHardWatchDog();

void Drv_29LV160Reset(void);

_U32 Drv_29LV160GetBlockSize( _U32 ulFlashAddr )
{
    _U32 ulBlockCnt;
    _U32 ulAddrInBlock, ulRet;

    switch( ulgDrvFlashType )
    {
        case DRV_29LV160_TYPE_TOP_BOOT:
            ulBlockCnt = (ulFlashAddr - FLASH_START_ADDR)/DRV_29LV160_BLOCK_SIZE;
            if (ulBlockCnt == FLASH_SIZE/DRV_29LV160_BLOCK_SIZE - 1)
            {
                ulAddrInBlock = ulFlashAddr % DRV_29LV160_BLOCK_SIZE;
                if (ulAddrInBlock < DRV_29LV160_BLOCK_SIZE/2)
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/2;
                }
                else if (ulAddrInBlock >= DRV_29LV160_BLOCK_SIZE/4)
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/4;
                }
                else
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/8;
                }
            }
            else
            {
                ulRet = DRV_29LV160_BLOCK_SIZE;
            }
            break;

        case DRV_29LV160_TYPE_BOTTOM_BOOT:
            ulBlockCnt = (ulFlashAddr - FLASH_START_ADDR)/DRV_29LV160_BLOCK_SIZE;
            if( ulBlockCnt == 0 )
            {
                if (ulFlashAddr - FLASH_START_ADDR >= DRV_29LV160_BLOCK_SIZE/2)
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/2;
                }
                else if (ulFlashAddr - FLASH_START_ADDR < DRV_29LV160_BLOCK_SIZE/4)
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/4;
                }
                else
                {
                    ulRet = DRV_29LV160_BLOCK_SIZE/8;
                }
            }
            else
            {
                ulRet = DRV_29LV160_BLOCK_SIZE;
            }
            break;
            
        case DRV_MX29LV320_TYPE_TOP_BOOT:
        case DRV_29GL320_TYPE_TOP_BOOT:
            ulBlockCnt = (ulFlashAddr - FLASH_START_ADDR)/DRV_29LV160_BLOCK_SIZE;
            if (ulBlockCnt == FLASH_SIZE/DRV_29LV160_BLOCK_SIZE - 1)
            {
                ulRet = DRV_29LV160_BLOCK_SIZE/8;
            }
            else
            {
                ulRet = DRV_29LV160_BLOCK_SIZE;
            }
            break;
        case DRV_MX29LV320_TYPE_BOTTOM_BOOT:
        case DRV_29GL320_TYPE_BOTTOM_BOOT:
            ulBlockCnt = (ulFlashAddr - FLASH_START_ADDR)/DRV_29LV160_BLOCK_SIZE;
            if (ulBlockCnt == 0)
            {
                ulRet = DRV_29LV160_BLOCK_SIZE/8;
            }
            else
            {
                ulRet = DRV_29LV160_BLOCK_SIZE;
            }
            break;
        default:
            ulRet = DRV_29LV160_BLOCK_SIZE;
            break;
    }

    return ulRet;
}

void Drv_29LV160IsOnBoard( void )
{
    _U32 ulReadAddr;
    _U16 usDevID, usManuID, usSecPV, usTmp1, usTmp2;

/* 
	*((_U32 *)(0xFFF00000+0x10c)) = 0xff800934;
 	*((_U32 *)(0xFFF00000+0x108)) = (0x10000000 | 0x00000400 | 0x00000001);
 	Drv_Print( "\r\nOR1=0x%x", *(_U32 *)(0xFFF00000+0x010C) );
 	Drv_Print( "\r\nBR1=0x%x", *(_U32 *)(0xFFF00000+0x0108) );
*/
    Drv_29LV160Reset();

    *((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_ID_CODE_CMD;

    ulReadAddr = FLASH_START_ADDR;

    usManuID = *((volatile _U16 *)ulReadAddr);
    usDevID  = *((volatile _U16 *)(ulReadAddr + (1<<1)));
    usSecPV  = *((volatile _U16 *)(ulReadAddr + (2<<1)));


    if( (usDevID & 0xFF) == DRV_29LV160_TYPE_TOP_BOOT )
    {
        ulgDrvFlashType     = DRV_29LV160_TYPE_TOP_BOOT;
        ulgDrvFlashLength   = 0x00200000;
        (void)Drv_Print("\r\nFlash type is 29LV160(top boot), init OK!");
    }
    else if( (usDevID & 0xFF) == DRV_29LV160_TYPE_BOTTOM_BOOT )
    {
        ulgDrvFlashType = DRV_29LV160_TYPE_BOTTOM_BOOT;
        ulgDrvFlashLength   = 0x00200000;
        (void)Drv_Print("\r\nFlash type is 29LV160(bottom boot), init OK!");
    }
    else if( (usDevID & 0xFF) == ((DRV_29GL320_TYPE_BOTTOM_BOOT & 0xFF00) >> 8) )
    {
        usTmp1 = *(_U16 *)(ulReadAddr + (0x0E<<1));
        usTmp2 = *(_U16 *)(ulReadAddr + (0x0F<<1));
        if ((usTmp2 & 0xFF) == (DRV_29GL320_TYPE_BOTTOM_BOOT & 0xFF))
        {
            ulgDrvFlashType = DRV_29GL320_TYPE_BOTTOM_BOOT;
            ulgDrvFlashLength   = 0x00400000;
            (void)Drv_Print("\r\nFlash type is 29GL320(bottom boot), init OK!");
        }
        else
        {
            ulgDrvFlashType = DRV_29GL320_TYPE_TOP_BOOT;
            ulgDrvFlashLength   = 0x00400000;
            (void)Drv_Print("\r\nFlash type is 29GL320(top boot), init OK!");
        }
    }
    else if( (usDevID & 0xFF) == DRV_MX29LV320_TYPE_TOP_BOOT )
    {
        ulgDrvFlashType = DRV_MX29LV320_TYPE_TOP_BOOT;
        ulgDrvFlashLength   = 0x00400000;
        (void)Drv_Print("\r\nFlash type is 29LV320(top boot), init OK!");
    }
    else if( (usDevID & 0xFF) == DRV_MX29LV320_TYPE_BOTTOM_BOOT )
    {
        ulgDrvFlashType = DRV_MX29LV320_TYPE_BOTTOM_BOOT;
        ulgDrvFlashLength   = 0x00400000;
        (void)Drv_Print("\r\nFlash type is 29LV320(bottom boot), init OK!");
    }
    else
    {
        ulgDrvFlashLength   = 0x00400000;
        (void)Drv_Print("\r\n Error: Don't support this flash type, default 4M!");
    }

    Drv_29LV160Reset();

#if 0
{
    int i;
    _U32 *pulBuff;

    pulBuff = malloc(2*1024*1024+16);
    if( pulBuff == NULL )
    {
        Drv_Print("\r\nNot Enough Memory!");
        return;
    }

    for( i = 0; i < 2*1024*1024/4; i++ )
    {
        pulBuff[i] = i;
    }

    Drv_Print("\r\nWrite Flash ");

    if( Drv_WriteFlash( 0x10000000, 2*1024*1024, (_U32)pulBuff ) == SUCCESS )
    {
        Drv_Print("OK!");
    }
    else
    {
        Drv_Print("Failure!");
    }
    
    for( i = 0; i < 2*1024*1024/4; i++ )
    {
        if( *(_U32 *)(0x10000000+i*4) != i )
        {
            Drv_Print("\r\nRead Flash=0x%lx i=0x%lx", *(_U32 *)(0x10000000+i*4), i );
        }
    }
    Drv_Print("\r\nRead Flash Finished!");
    
    BSP_PrintMemSimple( (char *)0x10000000, 64);
    BSP_PrintMemSimple( (char *)0x10000000+2*1024*1024-64, 64);
}
#endif

    return;
}

_U32 Drv_29LV160_Detect(_U16 *ptr,  _U16 trueData)
{
    int timeTmp = DRV_29LV160_TIMEOUT;
    volatile _U16 *pFlash = ptr;
    _U16 buf1, buf2,curTrueData;

    /* 先检测d7位. 如果FLASH正在忙,将读到真值的反,否则读到真值 */
    curTrueData = (trueData & DRV_29LV160_BIT_7);
    while( (*pFlash & DRV_29LV160_BIT_7) != curTrueData )
    {
        if( timeTmp-- <= 0 )
        {
            break;
        }
        /*if ((*pFlash & DRV_29LV160_BIT_5) == DRV_29LV160_BIT_5)
        {
            break;
        }*/
    }
    if( (*pFlash & DRV_29LV160_BIT_7) != curTrueData )
    {
        (void)Drv_Print("\r\n line = %d, Detect fail, Addr is 0x%x!", __LINE__, pFlash);
        return FAILURE;
    }
#ifdef DRV_DEBUG_FLASH
    (void)Drv_Print("\r\n line = %d, timeTmp = %d", __LINE__, timeTmp);
#endif

    timeTmp = DRV_29LV160_TIMEOUT;

    /* (为保险)再检测d6位. */
    buf1 = (*pFlash & DRV_29LV160_BIT_6);
    for( ;; )
    {
        buf2  = (*pFlash & DRV_29LV160_BIT_6);
        if( buf1 == buf2 )
        {
            break;
        }
        else
        {
            buf1 = buf2;
        }
        if( timeTmp-- <= 0 )
        {
            return FAILURE;
        }
    }

#ifdef DRV_DEBUG_FLASH
    (void)Drv_Print("\r\n line = %d, timeTmp = %d", __LINE__, timeTmp);
#endif
    return SUCCESS;
}

/*
本函数需要屏蔽由于芯片类型不同而引起的差异
*/
_U32 Drv_29LV160Write( _U32 ulFlashAddr, _U32 ulLength, _U32 ulRamAddr )
{

⌨️ 快捷键说明

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