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

📄 flash.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Write Word Count Low.  Decrement once since a count of 0 corresponds to a single write.
        if (dwDWORDsLeft > dwFlashPageSize) dwCount = dwFlashPageSize;
        else dwCount = dwDWORDsLeft;

        if (bByteMode) { // byte mode, 4 devices require each command in byte line
            do {
                 FlashWriteCommand(pdwSR, 0x70707070UL);
            } while (!FlashSR1(pdwSR,0x80808080UL)); // status check
			
			do {
                FlashWriteCommand(pdwSR, 0xe8e8e8e8UL); // Write to Buffer command
            } while (!FlashSR1(pdwSR,0x80808080UL));
            FlashWriteCommand(pdwSR, // set byte count
                (dwCount - 1) << 24 | (dwCount - 1) << 16 | (dwCount - 1) << 8 | dwCount - 1);
            for (i = 0; i < dwCount; i++) *pdwFlash++ = *pdwFlashCache++;
            FlashWriteCommand(pdwSR, 0xd0d0d0d0UL); // Program Buffer to Flash command
        }
        else { // word mode, 2 devices require each command in word line
            FlashWriteCommand(pdwSR, 0x00700070UL);
            while (!FlashSR1(pdwSR,0x00800080UL)); // status check
            do {
                FlashWriteCommand(pdwSR, 0x00e800e8UL); // Write to Buffer command
            } while (!FlashSR1(pdwSR,0x00800080UL));
            FlashWriteCommand(pdwSR, // set word count
                (dwCount-1) << 16 | dwCount - 1);
            for (i = 0; i < dwCount; i++) *pdwFlash++ = *pdwFlashCache++;
            FlashWriteCommand(pdwSR, 0x00d000d0UL); // Program Buffer to Flash command
        }
        dwDWORDsLeft -= dwCount;

    } // while there are still DWORDs to write to the page

    if (bByteMode) {
        FlashWriteCommand(pdwSR, 0x70707070UL); // Read Status Register command
        while (!FlashSR1(pdwSR, 0x80808080UL)); // Wait until operation complete
    }
    else {
        FlashWriteCommand(pdwSR, 0x00700070UL); // Read Status Register command
        while (!FlashSR1(pdwSR, 0x00800080UL)); // Wait until operation complete
    }

    // Check for operation errors
    if (FlashError_IntelStrata(pdwSR, ppszErrorMsg)) {
        return 1;
    }

    return 0;

}

UINT16 FlashClose_IntelStrata(
    DWORD dwPhysStart,
    DWORD dwPhysLen,
    char **ppszErrorMsg )
{

    volatile DWORD *pdwSR;
    DWORD dwStartBlock, dwEndBlock, dwCurBlock;
    DWORD dwStartBank, dwEndBank, dwCurBank;
    DWORD *pdwFlash, *pdwFlashCache;
    DWORD i, j, k;
    DWORD dwStart;
    DWORD dwFlashAreaBase;
    BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().

    dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area

	// Compute starting and ending block numbers
    dwStartBlock = (dwPhysStart & (0x04000000 - dwFlashBlockSize))
                    / dwFlashBlockSize;
    dwEndBlock = ((dwPhysStart + dwPhysLen) & (0x04000000 - dwFlashBlockSize))
                    / dwFlashBlockSize;

    EdbgOutputDebugString("Closing Out Flash Image at %X of length %X (Blocks %u to %u)\r\n",
        dwPhysStart, dwPhysLen, dwStartBlock, dwEndBlock );

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

    // Make sure that all the blocks have finished before letting them go on, otherwise you
    // might get bad values out of it.
    for (dwCurBlock = dwStartBlock; dwCurBlock <= dwEndBlock; dwCurBlock++) {
        pdwSR = (DWORD*)(dwFlashAreaBase + dwCurBlock * dwFlashBlockSize);
        // Wait for the page to indicate ready, meaning that everything has been written
        if (bByteMode) {
            FlashWriteCommand(pdwSR, 0x70707070UL); // Read Status Register command
            while(!FlashSR1(pdwSR, 0x80808080UL));
        }
        else {
            FlashWriteCommand(pdwSR, 0x00700070UL); // Read Status Register command
            while(!FlashSR1(pdwSR, 0x00800080UL));
        }
	}

    // Reset flash to read array mode
    dwStartBank = dwStartBlock / (dwFlashBankSize / dwFlashBlockSize);
    dwEndBank = dwEndBlock / (dwFlashBankSize / dwFlashBlockSize);
    for (dwCurBank = dwStartBank; dwCurBank <= dwEndBank; dwCurBank++) {
        pdwSR = (DWORD *)(dwFlashAreaBase + dwCurBank * dwFlashBankSize);
        if (bByteMode) FlashWriteCommand(pdwSR, 0xFFFFFFFFUL);
        else FlashWriteCommand(pdwSR, 0x00FF00FFUL);
    }

    // Do a compare against the FlashCache[] and see if it all looks right
    pdwFlashCache = (LPDWORD)FLASH_CACHE;
    EdbgOutputDebugString("Comparing Flash vs FlashCache...\r\n dwPhysStart=%Xh FLASH_CACHE=%Xh length=%Xh\r\n",
        dwPhysStart,pdwFlashCache,dwPhysLen);
    pdwFlash = (DWORD *)dwPhysStart;
    for (i = 0; i < dwPhysLen/4; i++) {
        j = *pdwFlash;
        k = *pdwFlashCache;
        if (j != k) {
            EdbgOutputDebugString( "Beat!\r\n" );
            EdbgOutputDebugString( "Flash               - FlashCache\r\n" );
            for (j = 0; j < 16; j++) {
                EdbgOutputDebugString("%X : %X - %X : %X\r\n",
                    pdwFlash, *pdwFlash, pdwFlashCache, *pdwFlashCache );
                pdwFlash++;
                pdwFlashCache++;
            }
            *ppszErrorMsg = "Error Comparing Flash vs FlashCache";
            return 1;
        }
        pdwFlash++;
        pdwFlashCache++;
    }
    EdbgOutputDebugString( "Jammin'!\r\n" );
    return 0;
}

UINT16 IsFlash( DWORD dwPhysStart, DWORD dwPhysLen )
{
    volatile DWORD *pdwRIC;
    DWORD dwPhysEnd = dwPhysStart + dwPhysLen - 1;
    DWORD dwStartArea, dwEndArea;
    DWORD dwStartBank, dwCurrBank, dwEndBank;
    DWORD dwCurrOffset;
    DWORD dwFlashAreaBase;
    DWORD dwError = 0;

    // Flash Code, initially set to 0.
    gdwFlashCode = 0;

    // Check the address range

    dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area
    dwStartArea = (dwPhysStart & 0x1C000000) >> 26;
    dwEndArea = (dwPhysEnd & 0x1C000000) >> 26;
    if (dwStartArea != dwEndArea) { // must in the same area
        EdbgOutputDebugString("Error: Image exceeds the memory area boundary.\r\n");
        while (1); // wait forever
    }

    // Initially these bank numbers are set to 0. (assuming 64MB for single bank)
    dwStartBank = 0;
    dwCurrBank = 0;
    dwEndBank = 0;
    dwCurrOffset = 0;

    while (dwCurrBank <= dwEndBank) {
        pdwRIC = (volatile DWORD*)(dwFlashAreaBase + dwCurrOffset);
        // Read Identifier Code
        FlashWriteCommand(pdwRIC, 0x90909090UL);

        if (*(pdwRIC) == 0x00890089UL) { // Intel device in word mode
            pdwRIC++; // proceed to next DWORD
            // Read Identifier Code
            FlashWriteCommand(pdwRIC, 0x90909090UL);
            if (*(pdwRIC) == 0x00150015UL) {
                dwFlashPageSize  = 0x00000010; // 16 bytes per page
                dwFlashBlockSize = 0x00040000; // 256kB per block
                dwFlashBankSize  = 0x01000000; // 16MB per bank
                dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
                dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
                if (dwCurrBank >= dwStartBank) { // when in actually-used bank
                    pdwRIC--; // back to the top of current bank
                    EdbgOutputDebugString("Area %d : Found Intel 28F640J5. [DUAL WORD: 0x%x - 0x%x]\r\n",
                        dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
                    if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J5_DW) {
                        dwError = 1; // Other type flash memory is already detected.
                        break;
                    }
                    gdwFlashCode = FLASH_28F640J5_DW;
                    FlashWrite = FlashWrite_IntelStrata;
		            FlashError = FlashError_IntelStrata;
		            FlashClose = FlashClose_IntelStrata;
                }
            }
            else if (*(pdwRIC) == 0x00170017UL) {
                dwFlashPageSize  = 0x00000010; // 16 bytes per page
                dwFlashBlockSize = 0x00040000; // 256kB per block
                dwFlashBankSize  = 0x01000000; // 16MB per bank
                dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
                dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
                if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
                    pdwRIC--; // back to the top of current bank
                    EdbgOutputDebugString("Area %d : Found Intel 28F640J3. [DUAL WORD: 0x%x - 0x%x]\r\n",
                        dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
                    if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J3_DW) {
                        dwError = 1; // Other type flash memory is already detected.
                        break;
                    }
                    gdwFlashCode = FLASH_28F640J3_DW;
                    FlashWrite = FlashWrite_IntelStrata;
		            FlashError = FlashError_IntelStrata;
		            FlashClose = FlashClose_IntelStrata;
                }
            }
            else {
                EdbgOutputDebugString("Area %d : Found unknown or unsupported Intel device.\r\n");
                dwError = 2;
                break;
            }
        }
        else if (*(pdwRIC) == 0x89898989) { // Intel device in byte mode
            pdwRIC++; // proceed to next DWORD
            pdwRIC++; // proceed to next DWORD
            // When in byte mode, Identifier Code register is allocated
            // at the 2 DWORD after the vendor code.
            // Read Identifier Code
            FlashWriteCommand(pdwRIC, 0x90909090UL);
            if (*(pdwRIC) == 0x17171717UL) {
                dwFlashPageSize  = 0x00000020; // 32 bytes per page
                dwFlashBlockSize = 0x00080000; // 512kB per block
                dwFlashBankSize  = 0x02000000; // 32MB per bank
                dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
                dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
                if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
                    pdwRIC--; // back to the top of current bank
                    pdwRIC--;
                    EdbgOutputDebugString("Area %d : Found Intel 28F640J3. [QUAD BYTE: 0x%x - 0x%x]\r\n",
                        dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
                    if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J3_QB) {
                        dwError = 1; // Other type flash memory is already detected.
                        break;
                    }
                    gdwFlashCode = FLASH_28F640J3_QB;
                    FlashWrite = FlashWrite_IntelStrata;
		            FlashError = FlashError_IntelStrata;
		            FlashClose = FlashClose_IntelStrata;
                }
            }
            else if (*(pdwRIC) == 0x18181818UL) {
                dwFlashPageSize  = 0x00000020; // 32 bytes per page
                dwFlashBlockSize = 0x00080000; // 512kB per block
                dwFlashBankSize  = 0x04000000; // 64MB per bank
                dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
                dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
                if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
                    pdwRIC--; // back to the top of current bank
                    pdwRIC--;
                    EdbgOutputDebugString("Area %d : Found Intel 28F128J3. [QUAD BYTE: 0x%x - 0x%x]\r\n",
                        dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
                    if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F128J3_QB) {
                        dwError = 1; // Other type flash memory is already detected.
                        break;
                    }
                    gdwFlashCode = FLASH_28F128J3_QB;
                    FlashWrite = FlashWrite_IntelStrata;
		            FlashError = FlashError_IntelStrata;
		            FlashClose = FlashClose_IntelStrata;
                }
            }
            else {
                EdbgOutputDebugString("Area %d : Found unknown or unsupported Intel device.\r\n");
                dwError = 2;
                break;
            }
        }
        else if (*(pdwRIC) == 0x90909090UL) {
            // Confirm this is actually RAM space.
            *(pdwRIC    ) = 0x00000000; // +  0
            *(pdwRIC + 1) = 0x55555555; // +  4
            *(pdwRIC + 2) = 0xAAAAAAAA; // +  8
            *(pdwRIC + 3) = 0xFFFFFFFF; // + 12
            if (*pdwRIC == 0x00000000 && *(pdwRIC + 1) == 0x55555555
                && *(pdwRIC + 2) == 0xAAAAAAAA && *(pdwRIC + 3) == 0xFFFFFFFF) {
                // calculate address span for memory check (actually RAM, not flash)
                dwFlashBankSize = 0x01000000; // not actual
                dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // not actual
                dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // not actual
                if (dwCurrBank >= dwStartBank) { // when in actrually-used RAM
                    EdbgOutputDebugString("Area %d : Found RAM at 0x%x.\r\n", dwStartArea, pdwRIC);
                    if (gdwFlashCode != 0) { // Previous addresses are flash but current is not.
                        dwError = 3;
                        break;
                    }
                }
            }
            else { // unknown device or device not exist
                dwError = 2;
                break;
            }
        }
        else { // unknown device or device not exist
            dwError = 2;
            break;
        }
        dwCurrOffset += dwFlashBankSize;
        dwCurrBank = dwCurrOffset / dwFlashBankSize;

    }

    switch (dwError) {

        case 0: // normal end, without error
        if (gdwFlashCode == 0) return 0; // not flash (RAM)
        else return 1; // flash

        case 1: // Different flash memory is found.
        EdbgOutputDebugString("Error: Different types of flash memories cannot be written together.\r\n");
        PrintLED("Mem Fail");
        while (1); // wait forever

        case 2: // Failed to detect device.
        EdbgOutputDebugString("Error: Failed to detect device.\r\n");
        EdbgOutputDebugString("Addr %x Data %x %x %x %x.\r\n",
            pdwRIC, *pdwRIC, *(pdwRIC + 1), *(pdwRIC + 2), *(pdwRIC + 3));
        PrintLED("Mem Fail");
        while (1); // wait forever

        case 3: // Image exceeds flash memory space.
        EdbgOutputDebugString("Error: Image exceeds flash memory space.\r\n");
        PrintLED("Mem Fail");
        while (1);

        default: // What happened ?
        EdbgOutputDebugString("Error: Unexpected state.\r\n");
        PrintLED("Unhandle");
        while (1);

    }
}

⌨️ 快捷键说明

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