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

📄 flash.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
            {
            switch (info.set)
                {

#ifndef OAL_FLASH_NO_COMMAND_SET_1                
                case 1: // Intel/Sharp
                case 3:
                    if (!EraseBlock1(&info, chip, blockStart))
                        {
                        goto cleanUp;
                        }
                    break;
#endif OAL_FLASH_NO_COMMAND_SET_1                

#ifndef OAL_FLASH_NO_COMMAND_SET_2
                case 2: // AMD
                    if (!EraseBlock2(&info, chip, blockStart))
                        {
                        goto cleanUp;
                        }                    
                    break;
#endif OAL_FLASH_NO_COMMAND_SET_2

                default:
                OALMSG(OAL_ERROR, (
                    L"ERROR: Flash type %d isn't supported\r\n", info.set
                ));
                    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 info
                if (!OALFlashInfo((VOID*)blockStart, &info)) break;
                region = 0;
                chip = blockStart;
                }
            }
        }

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

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

BOOL 
OALFlashEraseStart(
    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;

    // There can be only one pending erase
    if (s_erase.pending) goto cleanUp;

    // First detect flash at base
    if (!OALFlashInfo((VOID*)base, &info))
        {
        goto cleanUp;
        }

    // Find first block to be erased
    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) break;

        // This should not happen...
        if (blockEnd >= end) goto cleanUp;

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

    // Start erase
    switch (info.set)
        {

#ifndef OAL_FLASH_NO_COMMAND_SET_1                
        case 1: // Intel/Sharp
        case 3:
            if (!StartEraseBlock1(&info, chip, blockStart))
                {
                goto cleanUp;
                }
            break;
#endif OAL_FLASH_NO_COMMAND_SET_1                

#ifndef OAL_FLASH_NO_COMMAND_SET_2
        case 2: // AMD
            if (!StartEraseBlock2(&info, chip, blockStart))
                {
                goto cleanUp;
                }                    
            break;
#endif OAL_FLASH_NO_COMMAND_SET_2

        default:
            goto cleanUp;
        }


    // Save context for continue...
    s_erase.info = info;
    s_erase.base = chip;
    s_erase.end = end;
    s_erase.pos = blockStart;
    s_erase.region = region;
    s_erase.block = block;
    s_erase.pending = TRUE;
    
    rc = TRUE;

cleanUp:
    return rc;
}

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

UINT32 
OALFlashEraseContinue(
    )
{
    UINT32 rc = OAL_FLASH_ERASE_FAILED;
    OAL_FLASH_INFO *pInfo = &s_erase.info;
    
    // There must be pending erase
    if (!s_erase.pending) goto cleanUp;

    // Look if erase is done
    switch (s_erase.info.set)
        {

#ifndef OAL_FLASH_NO_COMMAND_SET_1                
        case 1: // Intel/Sharp
        case 3:
            rc = ContinueEraseBlock1(&s_erase.info, s_erase.base, s_erase.pos);
            break;
#endif OAL_FLASH_NO_COMMAND_SET_1                

#ifndef OAL_FLASH_NO_COMMAND_SET_2
        case 2: // AMD
            rc = ContinueEraseBlock2(&s_erase.info, s_erase.base, s_erase.pos);
            break;
#endif OAL_FLASH_NO_COMMAND_SET_2

        default:
            goto cleanUp;
        }

    // If erase is pending or failed we are done
    if (rc != OAL_FLASH_ERASE_DONE) goto cleanUp;

    // Move to next block
    s_erase.pos += pInfo->aBlockSize[s_erase.region] * pInfo->parallel;
    // Are we done?
    if (s_erase.pos >= s_erase.end) goto cleanUp;

    // Is is next chip?
    if (++s_erase.block >= pInfo->aBlocks[s_erase.region])
        {
        s_erase.block = 0;
        if (++s_erase.region >= pInfo->regions)
            {
            s_erase.base = s_erase.pos;
            // Try read next chip info
            if (!OALFlashInfo((VOID*)s_erase.base, pInfo)) goto cleanUp;
            s_erase.region = 0;
            }
        }
    
cleanUp:
    if (rc != OAL_FLASH_ERASE_PENDING) s_erase.pending = FALSE;    
    return rc;
}

//------------------------------------------------------------------------------
//
// Function: OALFlashWrite
//
// Note: please pass through Uncached Address (pBase, pStart)!
//
BOOL
OALFlashWrite(
    VOID *pBase, 
    VOID *pStart, 
    UINT32 size, 
    VOID *pBuffer
    )
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    DWORD base = (DWORD)pBase;
    DWORD start = (DWORD)pStart;
    DWORD end = start + size;
    DWORD chipStart;
    DWORD chipEnd;
    DWORD pos, count;
    UCHAR *pPos;

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

    chipStart = base;
    pPos = (UCHAR*)pBuffer;

    // First read first chip info
    while (TRUE)
    {
        if (!OALFlashInfo((VOID*)chipStart, &info))
        {
                OALMSG(OAL_ERROR, (
                    L"ERROR: OALFlashWrite - failed get flash info at 0x%08x\r\n",
                    chipStart
                ));
                goto cleanUp;
        }
        chipEnd = chipStart + info.size * info.parallel;
        // Is start address on this chip
        if (start >= chipStart && start < chipEnd) break;
        // Move to next chip
        chipStart = chipEnd;
    }
   
    pos = start;
    while (pos < end)
        {

        // How many data we can write
        if (end > chipEnd)
            {
            count = chipEnd - pos;
            }
        else
            {
            count = end - pos;
            }
        
        // Program data chunk
        switch (info.set)
            {

#ifndef OAL_FLASH_NO_COMMAND_SET_1                
            case 1:
            case 3:
                count = WriteData1(&info, chipStart, pos, pPos);
                break;
#endif OAL_FLASH_NO_COMMAND_SET_1

#ifndef OAL_FLASH_NO_COMMAND_SET_2
            case 2:
                count = WriteData2(&info, chipStart, pos, pPos);
                break;
#endif OAL_FLASH_NO_COMMAND_SET_2

            default:
            OALMSG(OAL_ERROR, (
                L"ERROR: Flash type %d isn't supported\r\n", info.set
            ));
                goto cleanUp;
            }

        // If we write nothing something wrong happen
        if (count == 0)
            {
            rc = FALSE;
            OALMSG(OAL_ERROR, (
                L"ERROR: Flash write at 0x%08x failed\r\n", pos
            ));
            goto cleanUp;
            }
      
        // Move position
        pos += count;
        pPos += count;

        // Break when we are done
        if (pos >= end) break;
        
        // If we run out of chip move to next one
        if (pos > chipEnd)
            {
            switch(info.set) {
                case 1:
                case 3:
                    WriteCommand(&info, chipStart, 0, 0xFF);
                    break;
                case 2:
                    WriteCommand(&info, chipStart, 0, 0xF0);
                    break;
                }
            chipStart = chipEnd;
            if (!OALFlashInfo((VOID*)chipStart, &info)) break;
            chipEnd = chipStart + info.size * info.parallel;
            }         
        }

    // Done
    //rc = TRUE;
    switch (info.set) {
    case 1:
    case 3:
        WriteCommand(&info, chipStart, 0, 0xFF);
        break;
    case 2:
        WriteCommand(&info, chipStart, 0, 0xF0);
        break;
    }

    // Do final check
    pPos = (UINT8*)pBuffer;
    for (pos = start; pos < end - sizeof(UINT32) + 1; pos += sizeof(UINT32)) {
        if (*(UINT32*)pPos != *(UINT32*)pos) break;
        pPos += sizeof(UINT32);
    }

    // If we reach end, all is ok
    rc = (pos >= end - sizeof(UINT32) + 1);
    OALMSG(!rc&&OAL_ERROR, (
        L"ERROR: Flash failed at 0x%08x -- write 0x%08x, but read 0x%08x\r\n",
        pos, *(UINT32*)pPos, *(UINT32*)pos
    ));
    
cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashWrite(rc = %d)", rc));
    return rc;
}

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

BOOL 
OALFlashLockDown(
    VOID *pBase,
    VOID *pStart,
    DWORD 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;


    // Ther read first chip info
    if (!OALFlashInfo((VOID*)base, &info))
        {
            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)
            {
            switch (info.set)
                {

#ifndef OAL_FLASH_NO_COMMAND_SET_1
                case 1: // Intel/Sharp
                case 3:
                    if (!LockDownBlock1(&info, chip, blockStart))
                        {
                        goto cleanUp;
                        }
                    break;
#endif OAL_FLASH_NO_COMMAND_SET_1

#ifndef OAL_FLASH_NO_COMMAND_SET_2
                case 2: // AMD
                    if (!LockDownBlock2(&info, chip, blockStart))
                        {
                        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 info
                if (!OALFlashInfo((VOID*)block, &info)) break;
                region = 0;
                chip = block;
                }
            }
        }

    rc = TRUE;
   
cleanUp:
    return rc;
}

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

⌨️ 快捷键说明

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