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

📄 flash.c

📁 WinCE 5.0的PXA270Bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:

        if ((i & 0x00000008) == 0x00000008)
            EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... lower flash.\r\n");
        if ((i & 0x00080000) == 0x00080000)
            EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... upper flash.\r\n");

        if ((i & 0x00000030) == 0x00000030)
            EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... lower flash.\r\n");
        if ((i & 0x00300000) == 0x00300000)
            EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... upper flash.\r\n");

        if ((i & 0x00000020) == 0x00000020)
            EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... lower flash.\r\n");
        if ((i & 0x00200000) == 0x00200000)
            EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... upper flash.\r\n");

        if (i != 0x00800080)
        {
            EdbgOutputDebugString("ERROR: FlashErase: status register returned 0x%X\r\n", i);
            EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash.  System halted!\r\n");
            return(FALSE);
        }
        if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_erased > 0) )
        {
            // We need to take care of the first 16K blocks if there are any
            pFlash += (L3_BLOCK_SIZE / 4);
            num_l3_blocks_erased--;
        }
        else
        {
            pFlash += (BLOCK_SIZE / 4);
        }
    }
    pFlash = (volatile UINT32 *)(FlashStart);

    // Clear the status register
    *pFlash = 0x00500050;

    if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_to_erase > 0) )
    {
        EdbgOutputDebugString("INFO: FlashErase: erasing flash %X to %X.  Please wait... \r\n", FlashStart, FlashStart + (((num_blocks-num_l3_blocks_to_erase)*256*1024) + (num_l3_blocks_to_erase*64*1024)) - 1);
    }
    else
    {
        EdbgOutputDebugString("INFO: FlashErase: erasing flash %X to %X.  Please wait... \r\n", FlashStart, FlashStart + (num_blocks*256*1024) - 1);
    }

    // For L3, need to set for use within the FOR loop
    num_l3_blocks_erased = num_l3_blocks_to_erase;

    // Erase each block.
    for (j = 0; j < num_blocks; j++)
    {
        // Issue erase and confirm command
        *pFlash = 0x00200020;
        *pFlash = 0x00d000d0;
        while ((*pFlash & 0x00800080) != 0x00800080);

        // Check if the flash block erased successfully.
        // Was either block locked?
        status = *pFlash;
        if ((status & 0x00200000) || (status & 0x00000020))
        {
            if (status & 0x00200000)
            {
                EdbgOutputDebugString("ERROR: FlashErase: block erase failure.  Lock bit upper flash set!\r\n");
            }

            if (status & 0x00000020)
            {
                EdbgOutputDebugString("ERROR: FlashErase: block erase failure.  Lock bit lower flash set!\r\n");
            }

            EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash.\r\n");
            return(FALSE);
        }
        EdbgOutputDebugString(".");

        if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_erased > 0) )
        {
            pFlash += (L3_BLOCK_SIZE / 4);
            num_l3_blocks_erased--;
        }
        else
        {
            pFlash += (BLOCK_SIZE / 4);
        }
    }

    EdbgOutputDebugString("\r\n");
    pFlash = (volatile UINT32 *)(FlashStart);

    // Put the flash back into read mode
    if ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
    {
        // Setting the number of 16K blocks that we have to deal with
        num_l3_blocks_erased = num_l3_blocks_to_erase;

        // Put each block back into read mode
        for (j = 0; j < num_blocks; j++)
        {
            *pFlash = 0x00FF00FF;

            if ( num_l3_blocks_erased )
            {
                pFlash += (L3_BLOCK_SIZE / 4);
                num_l3_blocks_erased--;
            }
            else
            {
                pFlash += (BLOCK_SIZE / 4);
            }
        }
        // Now reset the flash pointer
        pFlash = (volatile UINT32 *)(FlashStart);
    }
    else
    {
        *pFlash = 0x00FF00FF;
    }

    // Flash erase verification.
    for (i = 0; i < FlashLength / 4; i++)
    {
        if (*pFlash++ != 0xFFFFFFFF)
        {
            EdbgOutputDebugString("ERROR: FlashErase: erase verification failure at address 0x%X Data 0x%X.\r\n", pFlash-1, *(pFlash-1));
            EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash.\r\n");
            return(FALSE);
        }
    }


    return(TRUE);
}


BOOL FlashInit(UINT32 FlashStart, UINT32 FlashLength)
{
    // Read the device ID and determine the flash part type.
    //
    g_FlashDeviceType = DetectFlashDevice(FlashStart);

    return((g_FlashDeviceType != NONE) ? TRUE : FALSE);
}


BOOL FlashRead(UINT32 FlashStart, UINT8 *pDataBuffer, UINT32 DataLength)
{
    if (!pDataBuffer) return(FALSE);

    // TODO - check flash address...
    memcpy((void *)pDataBuffer, (const void *)FlashStart, DataLength);

    return(TRUE);
}


// TODO - block-aligned address.
BOOL FlashWrite(UINT32 FlashStart, UINT8 *pDataBuffer, UINT32 DataLength)
{
    UINT32 i,j,b;
    UINT32 sizeFlashCache; // size in bytes of the flash cache
    UINT32 chunksPerBlock;
    UINT32 count;
    UINT32 val = 0;
    UINT32 dwLength = DataLength;

    volatile UINT32 *pFlash         = (volatile UINT32 *) FlashStart;
    volatile UINT32 *pBlockAddress  = (volatile UINT32 *) (FlashStart);
    volatile UINT32 *pDeviceAddress = (volatile UINT32 *) FlashStart;
    volatile UINT32 *pFlashCache    = (UINT32 *) pDataBuffer;

    volatile UINT32 *pdwFlashStart;
    volatile UINT32 *pdwRamStart;



    if (g_FlashDeviceType == NONE)
    {
        EdbgOutputDebugString("ERROR: FlashWrite: unrecognized flash part.\r\n");
        return(FALSE);
    }

    if (!FlashErase(FlashStart, DataLength))
    {
        return(FALSE);
    }
        
    b = 0;

    if (g_FlashDeviceType == J3)
    {
        sizeFlashCache = 64;   // 64 bytes total, 32 bytes per device
        chunksPerBlock = 4096; // 256K / 64bytes = 4096
    }
    else if ((g_FlashDeviceType == K3) || (g_FlashDeviceType == K18) || (g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
    {
        sizeFlashCache = 128;  // 128 bytes total, 64 bytes per device
        chunksPerBlock = 2048; // 256K / 128bytes = 2048
    }

    EdbgOutputDebugString("INFO: FlashWrite: writing to flash...\r\n");

    while (DataLength > 0)
    {
        // Calculate the number of DWORDS to program in each iteration based on the size in bytes
        // of the flash cache.
        if (DataLength > sizeFlashCache)
            count = sizeFlashCache / 4;
        else
            count = DataLength / 4;

        // Issue Write to Buffer Command
        *pBlockAddress = 0x00E800E8;

        // Check that the write buffer is available.
        // Read the Extended Status Register and
        // wait for the assertion of XSR[7] before continuing.
        while ( (*pBlockAddress & 0x00800080) != 0x00800080)
        {
            *pBlockAddress = 0x00E800E8;
        }

        // Configure the size of the buffer that we will write.
        // Write the word count (device expects a 0 based number)
        *pBlockAddress = ((count - 1) << 16 | (count - 1));

        pdwFlashStart = pDeviceAddress;
        pdwRamStart   = pFlashCache;

        // Write up to "count" DWORDS into the Flash memory staging area
        for (i = 0; i < count; i++)
        {
            *pDeviceAddress++ = *pFlashCache++;
        }

        // increment the number of 64 or 128 byte segments written.
        b++;

        // Now program the buffer into Flash
        *pBlockAddress = 0x00D000D0;

        i = 0;
        while ((i & 0x00800080) != 0x00800080)
        {
            i = *pBlockAddress;
        }

        DataLength -= count << 2;

        // Read back the segment just written
        *pFlash = 0x00FF00FF;
        for (i = 0; i < count; i++)
        {
            if ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
            {
                *pdwFlashStart = 0x00FF00FF;
            }

            if (*pdwFlashStart++ != *pdwRamStart++)
            {
                EdbgOutputDebugString("ERROR: FlashWrite: flash programming failure at address 0x%x (expected 0x%x actual 0x%x).\r\n", pdwFlashStart-1, *(pdwRamStart-1), *(pdwFlashStart-1));
                return(FALSE);
            }
        }

        if ((b % chunksPerBlock) == 0)
        {
            EdbgOutputDebugString(".");
        }
    }

    // Verify the data written to flash...
    //
    pFlash      = (volatile UINT32 *) FlashStart;
    pFlashCache = (UINT32 *) pDataBuffer;

    // Put Flash into read mode.
    *pFlash = 0x00FF00FF;

    EdbgOutputDebugString("INFO: FlashWrite: verifying the data written to flash...\r\n");

    for ( j = 0; j < dwLength/4; j++ )
    {
        if (*pFlash++ != *pFlashCache++)
        {
            EdbgOutputDebugString( "ERROR: FlashWrite: verification failure at address 0x%x (expected 0x%x actual 0x%x))\r\n", pFlash-1, *(pFlashCache-1), *(pFlash-1) );
            return(FALSE);
        }
    }

    EdbgOutputDebugString("INFO: FlashWrite: flash programmed successfully!\r\n");

    return(TRUE);
}

// END: these routines will be replaced by the FMD when it's done.

⌨️ 快捷键说明

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