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

📄 flash.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 3 页
字号:
    // Indicate status

    EdbgOutputDebugString( "-OEMStartEraseFlash(rc=1)\r\n" );
    return TRUE;
}

//------------------------------------------------------------------------------
//  Function:  OEMFinishEraseFlash
//
//  Desc...
//

BOOL OEMFinishEraseFlash( void )
{
BOOL	rc;

	EdbgOutputDebugString( "+OEMFinishEraseFlash\r\n" );

    if( !gnBlocks )
    {
		EdbgOutputDebugString( "ERROR: OEMFinishEraseFlash: not initialized\r\n" );

        return( FALSE );
    }

    // Continue erasing flash until all blocks are erased

    while( (gnRetries < MAX_RETRIES) && (gnBlocks != gnErased) )
    {
        OEMContinueEraseFlash();
    }

	// Indicate status

    rc = (gnBlocks == gnErased);
	EdbgOutputDebugString( "-OEMFinishEraseFlash(rc=%d)\r\n", rc );
    return( rc );
}

//------------------------------------------------------------------------------
//  Function:  name( args )
//
//  Desc...
//

void OEMContinueEraseFlash (void)
{
    volatile DWORD *pdwSR;
    char *pszErrorMsg;
    BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().

//	EdbgOutputDebugString( "+OEMContinueEraseFlash\r\n" );

    pdwSR= (DWORD *)(gdwFlashAreaBase + dwBlockIndex * dwFlashBlockSize);

	// TBD - the following 2 tests don't appear necessary looking at
	// TBD - above function.

    if( !gnBlocks || (gnBlocks == gnErased) )
    {
		EdbgOutputDebugString( "ERROR: OEMCcontinueEraseFlash: done or not initialized\r\n" );
        return;				
    }

    if( gnRetries >= MAX_RETRIES )
    {
		EdbgOutputDebugString( "ERROR: OEMCcontinueEraseFlash: exceeded retries\r\n" );
        return;		        
    }

    // Now fill the command queue with erase block commands
    // Converting Block to address 

    switch( gStatus[dwBlockIndex] )
    {
    case eDIRTY:

        // Initialize reading of ESRs
		FlashWriteCommand(pdwSR, bByteMode ? 0x70707070 : 0x00700070);

        // If the block is busy, come back to it later
		if ( FlashSR1(pdwSR, bByteMode ? 0x80808080 : 0x00800080) )
        {
            // Tell it to erase the next block
            FlashWriteCommand(pdwSR, bByteMode ? 0x20202020 : 0x00200020);
            FlashWriteCommand(pdwSR, bByteMode ? 0xD0D0D0D0 : 0x00D000D0);
            gStatus[dwBlockIndex]=ePENDING;
        }
        break;

    case ePENDING:

        // Initialize reading of ESRs
		FlashWriteCommand(pdwSR, bByteMode ? 0x70707070 : 0x00700070);

        // If the block is busy, come back to it later
        if( FlashSR1(pdwSR, bByteMode ? 0x80808080 : 0x00800080) )
        {
            // Check for operation errors

            if( FlashError( pdwSR, &pszErrorMsg ) )
            {
                // This will make the routine loop back and try to erase the block again.

                gStatus[dwBlockIndex] = eDIRTY;
                EdbgOutputDebugString( "ERROR: Attempting To Erase Block %u: %s\r\n", dwBlockIndex, pszErrorMsg );
                gnRetries++;
            }
            else
            {      
                // Success. advance to next block
                // EdbgOutputDebugString( "eERASED:%u\r\n", dwBlock );

                EdbgOutputDebugString( "INFO: eERASED:%u (%X)\r\n", dwBlockIndex, pdwSR );

                gStatus[dwBlockIndex] = eERASED;
                gnErased ++;
                dwBlockIndex++;
            };
        }
        break;

    case eERASED:

        break;				// already erased

    default:

        // Erasing a written block!! should never happen

        EdbgOutputDebugString ("ERROR: Flash block %u written and erased again!!!\r\n", dwBlockIndex);
        return;
    }
}

//------------------------------------------------------------------------------
//  Function:  name( args )
//
//  Desc...
//

void DumpDwords(PDWORD pdw, int len)
{
    int lc;

    lc = 0;
    EdbgOutputDebugString("Dumpping %d dwords", len);

    for( lc = 0 ; len ; ++pdw, ++lc, --len )
    {
        if( !(lc & 3) )
            EdbgOutputDebugString("\r\n%X -", pdw);
        EdbgOutputDebugString(" %X", *pdw);
    }

    EdbgOutputDebugString("\r\n");
}

UINT16 FlashError_IntelStrata( volatile DWORD *pdwSR, char **ppszErrorMsg )
{

    BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().
    BOOL bError = FALSE;
    int reason = 0;

    // Read Status Register command
    FlashWriteCommand(pdwSR, bByteMode ? 0x70707070UL : 0x00700070);

    // Check DEVICE PROTECT STATUS
    if (!FlashSR0(pdwSR, bByteMode ? 0x02020202 : 0x00020002)) reason += 1;
    // Check PROGRAMMING VOLTAGE STATUS
    if (!FlashSR0(pdwSR, bByteMode ? 0x08080808 : 0x00080008)) reason += 2;
    // Check PROGRAMMING AND SET LOCK-BIT STATUS
    if (!FlashSR0(pdwSR, bByteMode ? 0x10101010 : 0x00100010)) reason += 4;
    // Check ERASE AND CLEAR LOCK-BITS STATUS
    if (!FlashSR0(pdwSR, bByteMode ? 0x20202020 : 0x00200020)) reason += 8;

    switch (reason) {

    case 0: // no error
        return 0;

    case 4: // simple programming error
        *ppszErrorMsg = "Device programming error.";
        break;

    case 8: // simple erasing error
        *ppszErrorMsg = "Device erasing error.";
        break;

    case 5: // write failed by block protection
    case 9: // erase failed by block protection
        *ppszErrorMsg = "This block is protected.";
        break;

    case 6: // write failed by low Vpen
    case 10:// erase failed by low Vpen
        *ppszErrorMsg = "Vpen is low, cannot erase/program device.";
        break;

    case 12: // command sequence error
        *ppszErrorMsg = "Bad command sequence.";
        break;

    case 13:
             // I don't know why, but actually Intel 28F128J3A device returns
             // 0xAA error status in lock bit clear when Vpen is low.
        *ppszErrorMsg = "Vpen is low, cannot erase/program device";
        break;

    default: // unexpected state
        *ppszErrorMsg = "Unexpected device state.";
        break;

    }

    FlashWriteCommand(pdwSR, 0x50505050UL); // Clear Status Register command

    // If the error is simple erase or write error, allows retry.
    if (reason == 4 || reason == 8) return 1;
    else return 2; // fatal error

}

UINT16 FlashWrite_IntelStrata( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
    DWORD *pdwFlashCache;
    volatile DWORD *pdwFlash;
    DWORD dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset, dwDWORDsLeft;
    DWORD dwFlashAreaBase;
    DWORD i;

    BOOL bErasing=TRUE;
    DWORD dwStart;

    if (CheckFlashWriteProtect()) {
        *ppszErrorMsg = "Error : write protected.";
        return 1;
    }

    dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area
    dwStartBlock = (dwPhysStart & (0x04000000 - dwFlashBlockSize)) / dwFlashBlockSize;
    dwEndBlock = ((dwPhysStart + dwPhysLen) & (0x04000000 - dwFlashBlockSize)) / dwFlashBlockSize;
    dwBlocksLeft = dwEndBlock - dwStartBlock + 1;

    // Calculate how far from the beginning of the first block the starting address falls
    dwFirstBlockOffset = dwPhysStart & (dwFlashBlockSize - 1);

    EdbgOutputDebugString("FlashWrite: dwStartBlock %d dwEndBlock %d dwBlocksLeft %d dwFirstBlockOffset %Xh\r\n",
		dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset);

    // protect BLOCK 0 (ethernet bootloader block)
    if (dwStartBlock == 0 && dwFlashAreaBase == (AREA_0 + UNCACHED_BASE)) {
        *ppszErrorMsg = "Error : Block 0 is the bootloader block. Check the image start address.";
        return 1;
    }

    while (bErasing) {
        bErasing=FALSE;
        for (i = dwStartBlock; i <= dwEndBlock; i++) {
            if (gStatus[i] != eERASED) {
                bErasing=TRUE;
				OEMContinueEraseFlash();
            }
        }
    }

    dwStart= OEMEthGetSecs();
    while (OEMEthGetSecs() - dwStart < 3) ;

    while (dwBlocksLeft) {

        for (i = dwStartBlock; i <= dwEndBlock; i++) {
            EdbgOutputDebugString( "FlashWrite: Block %d\r\n", i );
            // Attempt to flash all erased blocks
            if (gStatus[i] == eERASED) {
                // Set up the FlashCache pointer and number of words to write
                // If this is the first block, we need to start further along
				if (i == dwStartBlock) {
                    pdwFlash = (DWORD *)(dwPhysStart | UNCACHED_BASE);
                    pdwFlashCache = (DWORD*)FLASH_CACHE;
                    dwDWORDsLeft = (dwFlashBlockSize - dwFirstBlockOffset) / 4;
                    // If the whole image is less than one block long
                    if (dwDWORDsLeft > dwPhysLen / 4)
                        dwDWORDsLeft = dwPhysLen / 4;
                }
                else {
                    pdwFlash = (DWORD *)(dwFlashAreaBase + i * dwFlashBlockSize);
                    pdwFlashCache = (DWORD*)(FLASH_CACHE
                        + (i - dwStartBlock) * dwFlashBlockSize - dwFirstBlockOffset);
                    // If this is the last block we need to cut short the number of DWORDs written
                    if (i == dwEndBlock) dwDWORDsLeft = (dwPhysLen % dwFlashBlockSize) / 4;
                    else dwDWORDsLeft = dwFlashBlockSize / 4;
                }

                if (FlashPageWrite_IntelStrata(pdwFlash, pdwFlashCache, dwDWORDsLeft, ppszErrorMsg))
                    return 1;

                dwBlocksLeft--;
                gStatus[i] = eFLASHED;
            } // If the block was successfully erased
        }
    } // while there are still blocks left to program

    // Close out all the pages.  Wait until they have finished programming and then compare them against
    //  the cache image for consistency.
    if (FlashClose_IntelStrata((dwPhysStart | UNCACHED_BASE), dwPhysLen, ppszErrorMsg)) return 1;
    else return 0;

}

UINT16 FlashPageWrite_IntelStrata(
    volatile DWORD *pdwFlash,
    DWORD *pdwFlashCache,
    DWORD dwDWORDsLeft,
    char **ppszErrorMsg )
{

    volatile DWORD *pdwSR;
    DWORD i, dwCount;
    BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE;
    // Strata series has 4 word or 8 byte page buffer for programming (J5/J3) and
    // reading (J3 only). In byte mode (4 devices in 32-bit bus), page size is set
    // to 32 bytes, and in word mode (2 devices in 32-bit bus), it is set to 16.

    if (CheckFlashWriteProtect()) {
        *ppszErrorMsg = "Error : write protected.";
        return 1;
    }

    pdwSR = (DWORD*)( ((DWORD)pdwFlash) & (~(dwFlashBlockSize - 1)) ); // 32bit
    EdbgOutputDebugString( "FlashPageWrite: From %Xh to %Xh Length %Xh\r\n",
        pdwFlashCache, pdwFlash, dwDWORDsLeft*4);

    // Loop until we've written the entire page
    while ( (long)dwDWORDsLeft > 0 ) {

⌨️ 快捷键说明

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