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

📄 flash.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
{
    BOOL rc = FALSE;
    UINT32 base, code1, code2, code3, i;
    

    OALMSG(OAL_FUNC, (L"+OALFlashInfo(0x%08x, ...)\r\n", pBase));

    // Just to avoid possible problems
    memset(pInfo, 0, sizeof(*pInfo));

    // Make sure that we talk to uncached address
    base = (UINT32)OALCAtoUA(pBase);
    
    // Try 32-bit geometry
    OUTREG32((UINT32*)(base + 4 * 0x55), 0x98989898);
    code1 = INREG32((UINT32*)(base + 4 * 0x10));
    code2 = INREG32((UINT32*)(base + 4 * 0x11));
    code3 = INREG32((UINT32*)(base + 4 * 0x12));
    if (code1 == 'QQQQ' && code2 == 'RRRR' && code3 == 'YYYY') {
        pInfo->width = 4;
        pInfo->parallel = 4;
    } else if (code1 == 'Q\0Q\0' && code2 == 'R\0R\0' && code3 == 'Y\0Y\0') {
        pInfo->width = 4;
        pInfo->parallel = 2;
    } else if (code1 == 'Q\0\0\0' && code2 == 'R\0\0\0' && code3 == 'Y\0\0\0') {
        pInfo->width = 4;
        pInfo->parallel = 1;
    } else {
        // Now try luck with 16-bit geometry
        OUTREG16((UINT16*)(base + 2 * 0x55), 0x0098);
        code1 = INREG16((UINT16*)(base + 2 * 0x10));
        code2 = INREG16((UINT16*)(base + 2 * 0x11));
        code3 = INREG16((UINT16*)(base + 2 * 0x12));
        if (code1 == 'QQ' && code2 == 'RR' && code3 == 'YY') {
            pInfo->width = 2;
            pInfo->parallel = 2;
        } else if (code1 == '\0Q' && code2 == '\0R' && code3 == '\0Y') {
            pInfo->width = 2;
            pInfo->parallel = 1;
        } else {
            // So last oppurtinity is 8-bit mode
            OUTREG8((UINT8*)(base + 0x55), 0x98);
            code1 = INREG8((UINT8*)(base + 0x10));
            code2 = INREG8((UINT8*)(base + 0x11));
            code3 = INREG8((UINT8*)(base + 0x12));
            if (code1 == 'Q' && code2 == 'R' && code3 == 'Y') {
                pInfo->width = 1;
                pInfo->parallel = 1;
            } else {
                goto cleanUp;
            }                
        }
    }        

    // Read primary command set, size, burst size and number of regions
    pInfo->set = ReadInfo(base, 0x13, 1, pInfo->width);
    pInfo->size = 1 << ReadInfo(base, 0x27, 1, pInfo->width);
    pInfo->burst = 1 << ReadInfo(base, 0x2A, 1, pInfo->width);
    pInfo->regions = ReadInfo(base, 0x2C, 1, pInfo->width);

    // If there is more regions than expected
    if (pInfo->regions > 8) goto cleanUp;
   
    // Read region info
    for (i = 0; i < pInfo->regions; i++) {
        code1 = ReadInfo(base, 0x2d + (i << 2), 4, pInfo->width);
        pInfo->aBlocks[i] = (code1 & 0xFFFF) + 1;
        pInfo->aBlockSize[i] = (code1 >> 8) & 0x00FFFF00;
        if (pInfo->aBlockSize[i] == 0) pInfo->aBlockSize[i] = 128;
    }

    // Switch back to read mode
    switch (pInfo->set) {
    case 1:  // Intel/Sharp
        WriteCommand(base, 0, 0xFF, pInfo->width, pInfo->parallel);
        break;
    case 2:  // AMD/Fujitsu
        WriteCommand(base, 0, 0xF0,  pInfo->width, pInfo->parallel);
        break;
    }      

    rc = TRUE;

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

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

BOOL OALFlashErase(VOID *pBase, VOID *pStart, UINT32 size)
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base, start, end, chip, block;
    UINT32 ixReg, ixBlock;

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


    // Erase must work from uncached memory
    base = (UINT32)OALCAtoUA(pBase);
    start = (UINT32)OALCAtoUA(pStart);
    
    // First get end address
    end = start + size;
   
    // Ther read first chip info
    if (!OALFlashInfo((VOID*)base, &info)) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALFlashErase failed get flash memory info\r\n"
        ));
        goto cleanUp;
    }

    ixReg = ixBlock = 0;
    block = chip = base;
    while (block < end) {

        // Should block be erased?
        if (
            start < (block + info.aBlockSize[ixReg] * info.parallel) && 
            end >= block
        ) {
            switch (info.set) {
            case 1: // Intel/Sharp
                if (!EraseBlock1(chip, block, &info)) {
                    goto cleanUp;
                }
                break;
            case 2: // AMD
                if (!EraseBlock2(chip, block, &info)) {
                    goto cleanUp;
                }                    
                break;
            default:
                OALMSG(OAL_ERROR, (
                    L"ERROR: Flash type %d isn't supported\r\n", info.set
                ));
                goto cleanUp;
            }
        }         

        // Move to next block
        block += info.aBlockSize[ixReg] * info.parallel;
        if (block >= end) break;
        if (++ixBlock >= info.aBlocks[ixReg]) {
            ixBlock = 0;
            if (++ixReg >= info.regions) {
                // Try read next chip info
                if (!OALFlashInfo((VOID*)block, &info)) break;
                ixReg = 0;
                chip = block;
            }
        }
    }

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

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

BOOL OALFlashWrite(VOID *pBase, VOID *pStart, UINT32 size, VOID *pBuffer)
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base, start, end, chip, pos, count;
    UINT8 *pPos;

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

    // Flash must work from uncached memory
    base = (UINT32)OALCAtoUA(pBase);
    start = (UINT32)OALCAtoUA(pStart);

    // First get end address
    end = start + size;
    chip = base;
    pPos = (UINT8*)pBuffer;

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

        // Program data chunk
        switch (info.set) {
        case 1:
            count = WriteData1(chip, pos, &info, pPos);
            break;
        case 2:
            count = WriteData2(chip, pos, &info, pPos);
            break;
        default:
            OALMSG(OAL_ERROR, (
                L"ERROR: Flash type %d isn't supported\r\n", info.set
            ));
            goto cleanUp;
        }

        // If we write nothing some problem 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;

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

    switch (info.set) {
    case 1:
        WriteCommand(chip, 0, 0xFF, info.width, info.parallel);
        break;
    case 2:
        WriteCommand(chip, 0, 0xF0, info.width, info.parallel);
        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;
}

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

⌨️ 快捷键说明

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