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

📄 fmd.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 2 页
字号:

        // Read spare data
        NAND_SendFullCommand(BSP_NAND_CMD_READ2, sector, 0);
        // Read NAND spare area data
        NAND_Read((UINT8*)&sa, sizeof(sa));

    }        

    // Select B area
    OUTREG16(&g_fmd.pNANDRegs->CMD, BSP_NAND_CMD_READ2);
    // Issue command
    NAND_SendFullCommand(BSP_NAND_CMD_WRITE, sector, 0);

    // Create spare area info (we already have ECC from above)
    sa.oemReserved = pSectorInfo->bOEMReserved;
    sa.reserved1 = pSectorInfo->dwReserved1;
    sa.reserved2 = pSectorInfo->wReserved2;
    sa.badBlock = pSectorInfo->bBadBlock;
    sa.unused = 0xFF;
    if (sa.badBlock != 0xFF) {
        sa.badBlock1 = 0;
        sa.badBlock2 = 0;
    } else {
        sa.badBlock1 = 0xFFFF;
        sa.badBlock2 = 0xFFFF;
    }
    
    // Write spare info to the media
    NAND_Write((UINT8*)&sa, sizeof(sa));

    // Finish up the write operation
    if (!NAND_FinishCommand(BSP_NAND_CMD_WRITE2)) goto cleanUp;

    // Done
    rc = TRUE;

cleanUp:
    // Restor flash write protection
    CLRREG32(&g_fmd.pGPMCRegs->ulGPMC_CONFIG,  BIT4);
	LeaveCriticalSection(&g_fmd.cs);
    ASSERT(rc);
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function: FMD_GetBlockStatus
//
DWORD FMD_GetBlockStatus(BLOCK_ID blockId)
{
    DWORD rc = 0;
    SECTOR_ADDR sector;
    SectorInfo sectorInfo;

    // Check if we know flash geometry
    if (g_fmd.pNANDInfo == NULL) goto cleanUp;

    // Calculate sector
    sector = blockId * g_fmd.pNANDInfo->sectorsPerBlock;

    if (!FMD_ReadSector(sector, NULL, &sectorInfo, 1)) {
        rc = BLOCK_STATUS_UNKNOWN;
        goto cleanUp;
    }

    if (sectorInfo.bBadBlock != 0xFF) {
        rc |= BLOCK_STATUS_BAD;
    }

    if ((sectorInfo.bOEMReserved & OEM_BLOCK_READONLY) == 0) {
        rc |= BLOCK_STATUS_READONLY;
    }

    if ((sectorInfo.bOEMReserved & OEM_BLOCK_RESERVED) == 0) {
        rc |= BLOCK_STATUS_RESERVED;
    }

cleanUp:
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function: FMD_SetBlockStatus
//
BOOL FMD_SetBlockStatus(BLOCK_ID blockId, DWORD status)
{
    BOOL rc = FALSE;
    SECTOR_ADDR sector;
    SectorInfo sectorInfo;


    // Remove flash write protection
    SETREG32(&g_fmd.pGPMCRegs->ulGPMC_CONFIG,BIT4);

    // Check if we know flash geometry
    if (g_fmd.pNANDInfo == NULL) goto cleanUp;

    // Calculate sector
    sector = blockId * g_fmd.pNANDInfo->sectorsPerBlock;

    if ((status & BLOCK_STATUS_BAD) != 0) {
        // Read the sector info
        if (!FMD_ReadSector(sector, NULL, &sectorInfo, 1)) goto cleanUp;
        // Set the bad block marker
        sectorInfo.bBadBlock = 0;
        // Complete the write (no erase, we changed 0xFF -> 0x00)
        if (!FMD_WriteSector(sector, NULL, &sectorInfo, 1)) goto cleanUp;
    }

    if ((status & BLOCK_STATUS_READONLY) != 0) {
        // We don't currently support setting a block to read-only, so fail
        // if request is for read-only and block is not currently read-only.
        if ((FMD_GetBlockStatus(blockId) & BLOCK_STATUS_READONLY) != 0) {
            goto cleanUp;
        }
    }

    // Done
    rc = TRUE;

cleanUp:
    // Restore flash write protection
    CLRREG32(&g_fmd.pGPMCRegs->ulGPMC_CONFIG,BIT4);
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  FMD_EraseBlock
//
//  Erase the given block
//
BOOL FMD_EraseBlock(BLOCK_ID blockId)
{
    BOOL rc = FALSE;
    UINT32 sector;

    // Check if we know flash geometry
    if (g_fmd.pNANDInfo == NULL) goto cleanUp;

    // Calculate sector
    sector = blockId * g_fmd.pNANDInfo->sectorsPerBlock;

    // Obtain hardware lock
    EnterCriticalSection(&g_fmd.cs);
    // Remove flash write protection
    SETREG32(&g_fmd.pGPMCRegs->ulGPMC_CONFIG,BIT4);

    // Write the command
    OUTREG16(&g_fmd.pNANDRegs->CMD, BSP_NAND_CMD_ERASE);
    // Write page address
    OUTREG16(&g_fmd.pNANDRegs->ADDRESS, sector & 0xFF);
    OUTREG16(&g_fmd.pNANDRegs->ADDRESS, (sector >> 8) & 0xFF);
    if (g_fmd.pNANDInfo->extendedAddress) {
        OUTREG16(&g_fmd.pNANDRegs->ADDRESS, (sector >> 16) & 0xFF);
    }        

    //  Complete erase operation
    if (!NAND_FinishCommand(BSP_NAND_CMD_ERASE2)) goto cleanUp;
    // Done
    rc = TRUE;

cleanUp:
		// Restore flash write protection
		CLRREG32(&g_fmd.pGPMCRegs->ulGPMC_CONFIG,BIT4);
        // Release hardware lock
        LeaveCriticalSection(&g_fmd.cs);
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  FMD_PowerUp
//
VOID FMD_PowerUp()
{
    // Obtain hardware lock
    EnterCriticalSection(&g_fmd.cs);

    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;
    // Write the command
    OUTREG16(&g_fmd.pNANDRegs->CMD, BSP_NAND_CMD_RESET);
    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;

cleanUp:
    // Release hardware lock
    LeaveCriticalSection(&g_fmd.cs);
}

//------------------------------------------------------------------------------
//
//  Function:  FMD_PowerDown
//
VOID FMD_PowerDown(VOID)
{
    // Obtain hardware lock
    EnterCriticalSection(&g_fmd.cs);

    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;
    // Write the command
    OUTREG16(&g_fmd.pNANDRegs->CMD, BSP_NAND_CMD_RESET);
    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;

cleanUp:
    // Release hardware lock
    LeaveCriticalSection(&g_fmd.cs);
}

//------------------------------------------------------------------------------
//
//  Function:  FMD_OEMIoControl
//
BOOL FMD_OEMIoControl(
    DWORD code, UCHAR *pInBuffer, DWORD inSize, UCHAR *pOutBuffer,
    DWORD outSize, DWORD *pOutSize
) {
    return FALSE;
}

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

static BOOL NAND_SendFullCommand(UINT8 cmd, SECTOR_ADDR sector, UINT32 offset)
{
    BOOL rc = FALSE;
    
    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;
    // Write the command
    OUTREG16(&g_fmd.pNANDRegs->CMD, cmd);
    // Write the address
    OUTREG16(&g_fmd.pNANDRegs->ADDRESS, offset);
    OUTREG16(&g_fmd.pNANDRegs->ADDRESS, sector & 0xFF);
    OUTREG16(&g_fmd.pNANDRegs->ADDRESS, (sector >> 8) & 0xFF);
    if (g_fmd.pNANDInfo->extendedAddress) {
        OUTREG16(&g_fmd.pNANDRegs->ADDRESS, (sector >> 16) & 0xFF);
    }        
    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;

    // Done
    rc = TRUE;

cleanUp:
    return rc;
}

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

static BOOL NAND_FinishCommand(UINT8 cmd)
{
    BOOL rc = FALSE;

    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;
    //  Write the command
    OUTREG16(&g_fmd.pNANDRegs->CMD, cmd);
    // Wait for NAND
    if (!NAND_WaitForReady()) goto cleanUp;
    // Write STATUS command
    OUTREG16(&g_fmd.pNANDRegs->CMD, BSP_NAND_CMD_STATUS);
    //  Read status
    rc = (INREG16(&g_fmd.pNANDRegs->DATA) & BSP_NAND_STATUS_ERROR) == 0;

cleanUp:
    return rc;
}

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

static VOID NAND_Read(UINT8 *pBuffer, UINT32 bytes)
{
    UINT16 data;

    while (bytes > 1) {
        data = INREG16(&g_fmd.pNANDRegs->DATA);
        *pBuffer++ = (UINT8)data;
        *pBuffer++ = (UINT8)(data >> 8);
        bytes -= 2;
    }
    if (bytes > 0) {
        data = INREG16(&g_fmd.pNANDRegs->DATA);
        *pBuffer++ = (UINT8)data;
        bytes--;
    }
}

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

static VOID NAND_Write(UINT8 *pBuffer, UINT32 bytes)
{
    UINT16 data;

    while (bytes > 1) {
        data = *pBuffer++;
        data |= *pBuffer++ << 8;
        OUTREG16(&g_fmd.pNANDRegs->DATA, data);
        bytes -= 2;
    }
    if (bytes > 0) {
        data = *pBuffer++ | 0xFF00;
        OUTREG16(&g_fmd.pNANDRegs->DATA, data);
        bytes--;
    }
}

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

_inline static BOOL NAND_WaitForReady()
{
    // Internal Wait monitoring implmented in GPMC, So no need to 
    // check the status of the NAND Flash ready bit.
    // In case if the status bit is to be monitored then uncomment the 
    // code below.
    //while ((INREG32(&g_fmd.pGPMCRegs->ulGPMC_STATUS) & BIT8 ) == 0);
    return TRUE;
}

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

⌨️ 快捷键说明

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