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

📄 flash.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
    UINT32 base, 
    UINT32 block, 
    BOOL lock
    )
{
    return TRUE;
}

//------------------------------------------------------------------------------

static BOOL
LockDownBlock2(
    OAL_FLASH_INFO *pInfo,
    UINT32 base, 
    UINT32 block
    )
{
    return TRUE;
}

//------------------------------------------------------------------------------

static BOOL
EraseBlock2(
    OAL_FLASH_INFO *pInfo,
    UINT32 base, 
    UINT32 block
    )
{
    UINT32 code;
    UINT8 bits;
   
    // Start block reset
    WriteCommand(pInfo, base, 0x0555, 0xAA);
    WriteCommand(pInfo, base, 0x02AA, 0x55);
    WriteCommand(pInfo, base, 0x0555, 0x80);
    WriteCommand(pInfo, base, 0x0555, 0xAA);
    WriteCommand(pInfo, base, 0x02AA, 0x55);
    WriteCommand(pInfo, block, 0, 0x30);
   
    // Wait until it is done
    while (TRUE)
        {
        bits = BitsAnd(pInfo, block, 0);
        if ((bits & (1 << 5)) == 0) continue;
        code = INREG32((UINT32*)block);
        if (code == 0xFFFFFFFF) break;
        break;
        }

    // Switch back to read mode
    WriteCommand(pInfo, base, 0, 0xF0);

    return (code == 0xFFFFFFFF);
}

//------------------------------------------------------------------------------

static BOOL
StartEraseBlock2(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    return FALSE;
}

//------------------------------------------------------------------------------

static UINT32
ContinueEraseBlock2(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    return OAL_FLASH_ERASE_FAILED;
}

//------------------------------------------------------------------------------

static UINT32
WriteData2(
    OAL_FLASH_INFO *pInfo, 
    UINT32 base, 
    UINT32 pos, 
    VOID *pBuffer
    )
{
    UINT32 size = 0;
    UINT32 code;
    UINT8 bits;

    // Set flash memory to write mode
    WriteCommand(pInfo, base, 0x555, 0xAA);
    WriteCommand(pInfo, base, 0x2AA, 0x55);
    WriteCommand(pInfo, base, 0x555, 0xA0);

    // Now write info and wait until it is done
    switch (pInfo->width)
        {
        case 4:
            OUTREG32((UINT32*)pos, *(UINT32*)pBuffer);
            while (TRUE)
                {
                bits = BitsAnd(pInfo, pos, 0);
                if ((bits & (1 << 5)) == 0) continue;
                code = INREG32((UINT32*)pos);
                break;
                }
            if (code == *(UINT32*)pBuffer) size = sizeof(UINT32);
            break;
        case 2:
            OUTREG16((UINT16*)pos, *(UINT16*)pBuffer);
            while (TRUE)
                {
                bits = BitsAnd(pInfo, pos, 0);
                if ((bits & (1 << 5)) == 0) continue;
                code = INREG16((UINT16*)pos);
                break;
                }
            if (code == *(UINT16*)pBuffer) size = sizeof(UINT16);
            break;
        case 1:
            OUTREG8((UINT8*)pos, *(UINT8*)pBuffer);
            while (TRUE)
                {
                bits = BitsAnd(pInfo, pos, 0);
                if ((bits & (1 << 5)) == 0) continue;
                code = INREG8((UINT8*)pos);
                break;
                }
            if (code == *(UINT8*)pBuffer) size = sizeof(UINT8);
            break;
        }

    return size;
}

#endif OAL_FLASH_NO_COMMAND_SET_2

//------------------------------------------------------------------------------
//  Common code
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//  Function:  OALFlashInfo
//
//  This function read NOR flash memory layout via CFI. 
//
//  Note: please pass through Uncached Address (pBase)!
//
BOOL
OALFlashInfo(
    VOID *pBase, 
    OAL_FLASH_INFO *pInfo
    )
{
    BOOL rc = FALSE;
    UINT32 base = (UINT32)pBase;
    UINT32 code1, code2, code3;
    UINT32 i;
    
    OALMSG(OAL_FUNC, (L"+OALFlashInfo(0x%08x, ...)\r\n", pBase));

    // Just to avoid possible problems
    memset(pInfo, 0, sizeof(*pInfo));

    // Try 32-bit geometry
    OUTREG32((UINT32*)(base + 4 * 0x55), 0x98989898);
    code1 = INREG32((UINT32*)(base + 4 * 0x10));
    code2 = INREG32((UINT32*)(base + 4 * 0x11));
    code3 = INREG32((UINT32*)(base + 4 * 0x12));
    if (code1 == 'QQQQ' && code2 == 'RRRR' && code3 == 'YYYY')
        {
        pInfo->width = 4;
        pInfo->parallel = 4;
        }
    else if (code1 == 'Q\0Q\0' && code2 == 'R\0R\0' && code3 == 'Y\0Y\0')
        {
        pInfo->width = 4;
        pInfo->parallel = 2;
        }
    else if (code1 == 'Q\0\0\0' && code2 == 'R\0\0\0' && code3 == 'Y\0\0\0')
        {
        pInfo->width = 4;
        pInfo->parallel = 1;
        }
    else 
        {
        // Now try luck with 16-bit geometry
        OUTREG16((UINT16*)(base + 2 * 0x55), 0x0098);
        code1 = INREG16((UINT16*)(base + 2 * 0x10));
        code2 = INREG16((UINT16*)(base + 2 * 0x11));
        code3 = INREG16((UINT16*)(base + 2 * 0x12));
        if (code1 == 'QQ' && code2 == 'RR' && code3 == 'YY')
            {
            pInfo->width = 2;
            pInfo->parallel = 2;
            }
        else if (code1 == '\0Q' && code2 == '\0R' && code3 == '\0Y')
            {
            pInfo->width = 2;
            pInfo->parallel = 1;
            }
        else 
            {
            // So last opportunity is 8-bit mode
            OUTREG8((UINT8*)(base + 0x55), 0x98);
            code1 = INREG8((UINT8*)(base + 0x10));
            code2 = INREG8((UINT8*)(base + 0x11));
            code3 = INREG8((UINT8*)(base + 0x12));
            if (code1 == 'Q' && code2 == 'R' && code3 == 'Y')
                {
                pInfo->width = 1;
                pInfo->parallel = 1;
                }
            else 
                {
                goto cleanUp;
                }                
            }
        }        

    // Read primary command set, size, burst size and number of regions
    pInfo->set = ReadInfo(pInfo, base, 0x13, 0, 1);
    pInfo->size = 1 << ReadInfo(pInfo, base, 0x27, 0, 1);
    pInfo->burst = 1 << ReadInfo(pInfo, base, 0x2A, 0, 1);
    pInfo->regions = ReadInfo(pInfo, base, 0x2C, 0, 1);

    // Verify that parallel chips are same
    for (i = 1; i < pInfo->parallel; i++)
        {
            if ( (pInfo->set != ReadInfo(pInfo, base, 0x13, i, 1)) ||
                 (pInfo->size != (1 << ReadInfo(pInfo, base, 0x27, 0, 1))) ||
                 (pInfo->burst != (1 << ReadInfo(pInfo, base, 0x2A, 0, 1))) ||
                 (pInfo->regions != ReadInfo(pInfo, base, 0x2C, 0, 1)) )
                {
                    goto cleanUp;
                }
            
        }
    
    // If there is more regions than expected
    if (pInfo->regions > 8) goto cleanUp;
   
    // Read region info
    for (i = 0; i < pInfo->regions; i++)
        {
        code1 = ReadInfo(pInfo, base, 0x2d + (i << 2), 0, 4);
        pInfo->aBlocks[i] = (code1 & 0xFFFF) + 1;
        pInfo->aBlockSize[i] = (code1 >> 8) & 0x00FFFF00;
        if (pInfo->aBlockSize[i] == 0) pInfo->aBlockSize[i] = 128;
        }

    // Switch back to read mode
    switch (pInfo->set)
        {
        case 1:  // Intel/Sharp
        case 3:
            WriteCommand(pInfo, base, 0, 0xFF);
            break;
        case 2:  // AMD/Fujitsu
            WriteCommand(pInfo, base, 0, 0xF0);
            break;
        }      

    rc = TRUE;

cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashInfo(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------

BOOL
OALFlashTiming(
    VOID *pBase, 
    OAL_FLASH_TIMING *pTimingInfo
    )
{
    BOOL rc = FALSE;
    UINT32 base = (UINT32)pBase;
    OAL_FLASH_INFO info;

    // Ther read first chip info
    if (!OALFlashInfo((VOID*)base, &info)) goto cleanUp;

    // Switch to CFI Query
    WriteCommand(&info, base, 0x55, 0x98);
    
    // Read timeout parameters
    pTimingInfo->writeDelay    = ReadInfo(&info, base, 0x1F, 0, 1);
    pTimingInfo->writeTimeout  = ReadInfo(&info, base, 0x23, 0, 1);
    pTimingInfo->bufferDelay   = ReadInfo(&info, base, 0x20, 0, 1);
    pTimingInfo->bufferTimeout = ReadInfo(&info, base, 0x24, 0, 1);
    pTimingInfo->eraseDelay    = ReadInfo(&info, base, 0x21, 0, 1);
    pTimingInfo->eraseTimeout  = ReadInfo(&info, base, 0x25, 0, 1);

    // Switch back to read mode
    switch (info.set)
        {
        case 1:  // Intel/Sharp
        case 3:
            WriteCommand(&info, base, 0, 0xFF);
            break;
        case 2:  // AMD/Fujitsu
            WriteCommand(&info, base, 0, 0xF0);
            break;
        }      

    rc = TRUE;
    
cleanUp:
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  OALFlashLock
//
//  This function locks/unlocks region on NOR flash memory. 
//
BOOL 
OALFlashLock(
    VOID *pBase,
    VOID *pStart,
    DWORD size,
    BOOL lock
    )
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base = (UINT32)pBase;
    UINT32 start = (UINT32)pStart;
    UINT32 end, chip, blockStart, blockEnd;
    UINT32 region, block;


    // First get end addresss
    end = start + size;
   
    // Ther read first chip info
    if (!OALFlashInfo((VOID*)base, &info))
        {
            goto cleanUp;
        }

    region = block = 0;
    blockStart = chip = base;
    while (blockStart < end)
        {

        // Block end
        blockEnd = blockStart + info.aBlockSize[region] * info.parallel;

        // Should block be erased?
        if (start < blockEnd && end >= blockStart)
            {
            switch (info.set)
                {

#ifndef OAL_FLASH_NO_COMMAND_SET_1                
                case 1: // Intel/Sharp
                case 3:
                    if (!LockBlock1(&info, chip, blockStart, lock))
                        {
                        goto cleanUp;
                        }
                    break;
#endif OAL_FLASH_NO_COMMAND_SET_1                
                    
#ifndef OAL_FLASH_NO_COMMAND_SET_2
                case 2: // AMD
                    if (!LockBlock2(&info, chip, blockStart, lock))
                        {
                        goto cleanUp;
                        }                    
                    break;
#endif OAL_FLASH_NO_COMMAND_SET_2
                default:
                    goto cleanUp;
                }
            }         

        // Move to next block
        blockStart = blockEnd;
        if (blockStart >= end) break;
        if (++block >= info.aBlocks[region])
            {
            block = 0;
            if (++region >= info.regions)
                {
                // Try read next chip layout
                if (!OALFlashInfo((VOID*)block, &info)) break;
                region = 0;
                chip = block;
                }
            }
        }

    rc = TRUE;
   
cleanUp:
    return rc;
}

//------------------------------------------------------------------------------
//
// Function: OALFlashErase
//
// Note: please pass through Uncached Addresses (pBase, pStart)!
//
BOOL OALFlashErase(
    VOID *pBase,
    VOID *pStart,
    UINT32 size
    )
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base = (UINT32)pBase;
    UINT32 start = (UINT32)pStart;
    UINT32 end = start + size;
    UINT32 chip, blockStart, blockEnd;
    UINT32 region, block;

    OALMSG(OAL_FUNC, (
        L"+OALFlashErase(0x%08x, 0x%08x, 0x%08x)\r\n", pBase, pStart, size
    ));

    // Read first chip layout
    if (!OALFlashInfo((VOID*)base, &info))
    {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALFlashErase failed get flash memory info\r\n"
        ));
            goto cleanUp;
    }

    region = block = 0;
    blockStart = chip = base;
    while (blockStart < end)
        {

        // Block end (+1)
        blockEnd = blockStart + info.aBlockSize[region] * info.parallel;

        // Should block be erased?
        if (start < blockEnd && end >= blockStart)

⌨️ 快捷键说明

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