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

📄 flash.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  This file implements CFI NOR flash memory erase and write functions.
//
#include <windows.h>
#include <oal.h>

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

static struct {
    BOOL pending;
    OAL_FLASH_INFO info;
    UINT32 base;
    UINT32 end;
    UINT32 pos;
    UINT32 region;
    UINT32 block;
} s_erase;

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

static UCHAR
BitsOr(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    ULONG offset
    )
{
    UCHAR bits = 0;
    DWORD data;    
    ULONG width = pInfo->width;
    ULONG parallel = pInfo->parallel;

    switch (width)
        {
        case 4:
            data = INREG32((UINT32*)(base + (offset << 2)));
            switch (parallel)
                {
                case 4:
                    bits  = (UCHAR)(((data >> 24)&0xFF) | ((data >> 16)&0xFF));
                    bits |= (UCHAR)(((data >>  8)&0xFF) | ((data >>  0)&0xFF));
                    break;
                case 2:
                    bits  = (UCHAR)(((data >> 16)&0xFF) | ((data >> 0)&0xFF));
                    break;                    
                case 1:
                    bits = (UCHAR)(data&0xFF);
                    break;
                }
            break;
        case 2:
            data = INREG16((UINT16*)(base + (offset << 1)));
            switch (parallel)
                {
                case 2:
                    bits = (UCHAR)(((data >> 8)&0xFF) | ((data >> 0)&0xFF));
                    break;                    
                case 1:
                    bits = (UCHAR)(data&0xFF);
                    break;
                }
            break;
        case 1:
            bits = INREG8((UINT8*)(base + offset));
            break;
        }            

    return bits;   
}

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

static UCHAR
BitsAnd(
    OAL_FLASH_INFO *pInfo,
    DWORD base,
    ULONG offset
    )
{
    UINT8 bits = 0;
    UINT32 data;    
    ULONG width = pInfo->width;
    ULONG parallel = pInfo->parallel;

    switch (width)
        {
        case 4:
            data = INREG32((UINT32*)(base + (offset << 2)));
            switch (parallel)
                {
                case 4:
                    bits  = (UCHAR)(((data >> 24)&0xFF) & ((data >> 16)&0xFF));
                    bits &= (UCHAR)(((data >>  8)&0xFF) & ((data >>  0)&0xFF));
                    break;
                case 2:
                    bits = (UCHAR)(((data >> 16)&0xFF) & ((data >> 0)&0xFF));
                    break;                    
                case 1:
                    bits = (UCHAR)(data&0xFF);
                    break;
                }
            break;
        case 2:
            data = INREG16((UINT16*)base);
            switch (parallel)
                {
                case 2:
                    bits  = (UCHAR)(((data >> 8)&0xFF) & ((data >> 0) & 0xFF));
                    break;                    
                case 1:
                    bits = (UCHAR)(data&0xFF);
                    break;
                }
            break;
        case 1:
            bits = INREG8((UINT8*)base);
            break;
        }            

    return bits;   
}

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

static UINT32
ReadInfo(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    ULONG offset, 
    ULONG shift,
    ULONG size
    )
{
    DWORD data = 0;
    ULONG count = (INT32)size;
    
    switch (pInfo->width)
        {
        case 4:        
            if (shift >= 4) shift = 0;
            while (count-- > 0)
                {
                data <<= 8;
                data |= INREG32(
                        (UINT32*)(base + ((offset + count) << 2) + shift)
                    ) & 0xFF;
                }
            break;
        case 2:        
            if (shift >= 2) shift = 0;
            while (count-- > 0)
                {
                data <<= 8;
                data |= INREG16(
                        (UINT16*)(base + ((offset + count) << 1) + shift)
                    ) & 0xFF;
                }
            break;
        case 1:
            while (count-- > 0)
                {
                data <<= 8;
                data |= INREG8((UINT8*)(base + offset + count));
                }
            break;
        }

    return data;            
}

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

static VOID
WriteCommand(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    ULONG offset,
    UCHAR cmd
    )
{
    DWORD code;
    ULONG width = pInfo->width;
    ULONG parallel = pInfo->parallel;
        
    switch (width)
        {
        case 4:
            if (parallel == 4)
                {
                code = cmd | (cmd << 8) | (cmd << 16) | (cmd << 24);
                }
            else if (parallel == 2) 
                {
                code = cmd | (cmd << 16);
                }
            else if (parallel == 1)
                {
                code = cmd;
                }
            else
                {
                break;
                }
            OUTREG32((UINT32*)(base + (offset << 2)), code);
            break;
        case 2:
            if (parallel == 2)
                {
                code = cmd | (cmd << 8);
                }
            else if (parallel == 1)
                {
                code = cmd;
                }
            else
                {
                break;
                }
            OUTREG16((UINT16*)(base + (offset << 1)), code);
            break;
        case 1:
            if (parallel != 1) break;
            code = cmd;
            OUTREG8((UINT8*)(base + offset), code);
            break;
        }
}

//------------------------------------------------------------------------------
//  Command Set 1 support (Intel)
//------------------------------------------------------------------------------

#ifndef OAL_FLASH_NO_COMMAND_SET_1

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

static BOOL
LockBlock1(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block, 
    BOOL lock
    )
{
    UCHAR command;
    UCHAR bits;

    command = lock ? 0x01 : 0xD0;
    
    // Set block lock
    WriteCommand(pInfo, block, 0, 0x60);
    WriteCommand(pInfo, block, 0, command);

    // Verify it is correct
    WriteCommand(pInfo, block, 0x02, 0x90);
    if (lock)
        {
        bits = BitsAnd(pInfo, block, 0x02);
        }
    else
        {
        bits = BitsOr(pInfo, block, 0x02);
        }
    
    // Reset memory back to normal state
    WriteCommand(pInfo, block, 0, 0xFF);

    return (((bits & (1 << 0)) != 0) == lock);
}

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

static BOOL
LockDownBlock1(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    UCHAR bits;

    // Set block lock-down
    WriteCommand(pInfo, block, 0, 0x60);
    WriteCommand(pInfo, block, 0, 0x2F);

    // Verify it is correct
    WriteCommand(pInfo, block, 0x02, 0x90);
    bits = BitsAnd(pInfo, block, 0x02);
    
    // Reset memory back to normal state
    WriteCommand(pInfo, block, 0, 0xFF);

    return ((bits & (1 << 1)) != 0);
}

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

static BOOL
EraseBlock1(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    BOOL rc;
    UCHAR bits;

    // Start block reset
    WriteCommand(pInfo, base, 0, 0x50);
    WriteCommand(pInfo, block, 0, 0x20);
    WriteCommand(pInfo, block, 0, 0xD0);

    // Wait until it is done
    do {
        WriteCommand(pInfo, base, 0, 0x70);
        bits = BitsAnd(pInfo, base, 0);
       }
    while ((bits & (1 << 7)) == 0);

    // Reset memory back to normal state
    WriteCommand(pInfo, base, 0, 0xFF);

    // Bit 5 is zero if erase succeeded
    WriteCommand(pInfo, base, 0, 0x70);
    bits = BitsOr(pInfo, base, 0);
    rc = (bits & (1 << 5)) == 0;
    
    // Switch back to read mode
    WriteCommand(pInfo, base, 0, 0xFF);

    return rc;
}

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

static BOOL
StartEraseBlock1(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    // Erase status register
    WriteCommand(pInfo, block, 0, 0x50);

    // Start block reset
    WriteCommand(pInfo, block, 0, 0x20);
    WriteCommand(pInfo, block, 0, 0xD0);

    return TRUE;
}

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

static UINT32
ContinueEraseBlock1(
    OAL_FLASH_INFO *pInfo,
    DWORD base, 
    DWORD block
    )
{
    UINT32 rc = OAL_FLASH_ERASE_PENDING;
    UINT8 bits;

    // Check if erase is done
    WriteCommand(pInfo, block, 0, 0x70);
    bits = BitsAnd(pInfo, block, 0);
    if ((bits & (1 << 7)) == 0) goto cleanUp;
        
    // Bit 5 is zero if erase succeeded
    rc = (bits & (1 << 5)) == 0 ? OAL_FLASH_ERASE_DONE : OAL_FLASH_ERASE_FAILED;
    
cleanUp:
    // Switch back to read mode
    WriteCommand(pInfo, block, 0, 0xFF);
    return rc;
}

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

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

    // Issue write command
    WriteCommand(pInfo, base, 0, 0x40);
   
    // Now write info and wait until it is done
    switch (pInfo->width)
        {
        case 4:
            OUTREG32((UINT32*)pos, *(UINT32*)pBuffer);
            break;
        case 2:
            OUTREG16((UINT16*)pos, *(UINT16*)pBuffer);
            break;
        case 1:
            OUTREG8((UINT8*)pos, *(UINT8*)pBuffer);
            break;
        }

    // Wait until write is done
    WriteCommand(pInfo, base, 0, 0x70);
    bits = BitsAnd(pInfo, pos, 0);
    while ((bits & (1 << 7)) == 0)
        {
        WriteCommand(pInfo, base, 0, 0x70);
        bits = BitsAnd(pInfo, pos, 0);
        }
    
    // Bit 4 is zero if write succeeded
    if ((bits & (1 << 4)) == 0) size = pInfo->width;

    // Reset memory back to normal state
    WriteCommand(pInfo, base, 0, 0xFF);

    // Return result
    return size;
}

#endif OAL_FLASH_NO_COMMAND_SET_1

//------------------------------------------------------------------------------
//  Command Set 2 support (AMD)
//------------------------------------------------------------------------------

#ifndef OAL_FLASH_NO_COMMAND_SET_2

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

static BOOL
LockBlock2(
    OAL_FLASH_INFO *pInfo,

⌨️ 快捷键说明

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