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

📄 fmd_lb.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    //  Disable the chip
    NF_nFCE_H();

    return bRet;
}

BOOL NAND_LB_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
    BOOL    bRet = TRUE;
    int NewSpareAddr = NAND_PAGE_SIZE;
    int NewSectorAddr = sectorAddr;

    DWORD SECCBuf1;

    //  Chip enable
    NF_nFCE_L();

    NF_CLEAR_RB();

    //  Write the command
    //  First, let's point to the spare area
    NF_CMD(CMD_WRITE);

    //  Write the address
    NF_ADDR((NewSpareAddr)&0xff);
    NF_ADDR((NewSpareAddr>>8)&0xff);
    NF_ADDR((NewSectorAddr)&0xff);
    NF_ADDR((NewSectorAddr>>8)&0xff);
    if(g_bNeedExtAddr)
    {
        NF_ADDR((NewSectorAddr>>16)&0xff);
    }

    // Initialize MECC module
    NF_RSTECC();
    NF_MECC_UnLock();

    //  Now let's write the SectorInfo data
    //  Write the first reserved field (DWORD)
    NF_WRDATA_BYTE(pInfo->bBadBlock);
    NF_WRDATA_WORD(pInfo->dwReserved1);
    NF_WRDATA_BYTE(pInfo->bOEMReserved);

    NF_MECC_Lock();

    SECCBuf1 = NF_RDMECC0();

    NF_WRDATA_BYTE(pInfo->wReserved2&0xff);
    NF_WRDATA_BYTE((pInfo->wReserved2>>8)&0xff);

    // Issue the write complete command
    NF_CMD(CMD_RDI);
    // Set Address to access SECC1 in Spare area
    NF_ADDR((NewSpareAddr+NAND_SECC1_OFFSET)&0xff);
    NF_ADDR(((NewSpareAddr+NAND_SECC1_OFFSET)>>8)&0xff);

    // Write SECC1
    NF_WRDATA_WORD(SECCBuf1);

    //  Issue the write complete command
    NF_CMD(CMD_WRITE2);

    //  Check ready bit
    NF_DETECT_RB();     // Wait tR(max 12us)

    if ( NF_RDSTAT & STATUS_ILLACC )
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page (Illegal Access) %d!\n"), sectorAddr));
        g_pNFConReg->NFSTAT =  STATUS_ILLACC;    // Write 1 to clear.
           bRet = FALSE;
    }
    else
    {
        //  Check the status of program
        NF_CMD(CMD_STATUS);

        if( NF_RDDATA_BYTE() & STATUS_ERROR) {
            RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page %d!\n"), sectorAddr));
            bRet = FALSE;
        }
    }

    NF_nFCE_H();

    return bRet;
}

BOOL FMD_LB_EraseBlock(BLOCK_ID blockID)
{
    BOOL    bRet = TRUE;
    DWORD   dwPageID = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;

    RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("FMD_LB_EraseBlock 0x%x \r\n"), blockID));

    //  Enable the chip
    NF_nFCE_L();        // Select the flash chip.

    NF_CLEAR_RB();

    //  Issue command
    NF_CMD(CMD_ERASE);

    //  Set up address
    NF_ADDR((dwPageID) & 0xff);
    NF_ADDR((dwPageID >> 8) & 0xff);
    if(g_bNeedExtAddr)
    {
        NF_ADDR((dwPageID >> 16) & 0xff);
    }

    //  Complete erase operation
    NF_CMD(CMD_ERASE2);

    //  Wait for ready bit
    NF_DETECT_RB();     // Wait tR(max 12us)

    if ( NF_RDSTAT & STATUS_ILLACC )
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("LB######## Error Erasing block (Illegal Access) %d!\n"), blockID));
        g_pNFConReg->NFSTAT =  STATUS_ILLACC;    // Write 1 to clear.
        bRet = FALSE;
    }
    else
    {
        //  Check the status
        NF_CMD(CMD_STATUS);

        if( NF_RDDATA_BYTE() & STATUS_ERROR)
        {
            RETAILMSG(FMD_ZONE_ERROR, (TEXT("LB######## Error Erasing block %d!\n"), blockID));
            bRet = FALSE;
        }
    }

    NF_nFCE_H();                        // Select the flash chip.

    return bRet;
}


DWORD FMD_LB_GetBlockStatus(BLOCK_ID blockID)
{
    SECTOR_ADDR sectorAddr = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
    SectorInfo SI;
    DWORD dwResult = 0;

    RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("FMD_LB_GetBlockStatus (0x%x)0x%x \r\n"), blockID, sectorAddr));

    if(!FMD_LB_ReadSector(sectorAddr, NULL, &SI, 1))
    {
        if(NAND_LB_IsBlockBad(blockID))
        {
            return BLOCK_STATUS_BAD;
        }
        else
        {
            return BLOCK_STATUS_UNKNOWN;
        }
    }
    if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
    {
        dwResult |= BLOCK_STATUS_READONLY;
    }

    if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
    {
        dwResult |= BLOCK_STATUS_RESERVED;
    }

    if(SI.bBadBlock != 0xFF)
    {
        dwResult |= BLOCK_STATUS_BAD;
    }

    return dwResult;
}

BOOL FMD_LB_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    BYTE bStatus = 0;

    if(dwStatus & BLOCK_STATUS_BAD)
    {
        if(!NAND_LB_MarkBlockBad (blockID))
        {
            return FALSE;
        }
    }

    // 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(dwStatus & BLOCK_STATUS_READONLY)
    {
        if(!(FMD_LB_GetBlockStatus(blockID) & BLOCK_STATUS_READONLY))
        {
            return FALSE;
        }
    }

    return TRUE;
}

BOOL NAND_LB_MarkBlockBad(BLOCK_ID blockID)
{
    DWORD   dwStartPage = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
    BOOL    bRet = TRUE;

    RETAILMSG(FMD_ZONE_FUNCTION, (TEXT("NAND_LB_MarkBlockBad 0x%x \r\n"), dwStartPage));

    //  Enable chip
    NF_nFCE_L();
    NF_CLEAR_RB();

    //  Issue command
    //  We are dealing with spare area
    NF_CMD(CMD_WRITE);

    //  Set up address
    NF_ADDR((NAND_PAGE_SIZE+LB_POS_BADBLOCK)&0xff);
    NF_ADDR(((NAND_PAGE_SIZE+LB_POS_BADBLOCK)>>8)&0xff);
    NF_ADDR((dwStartPage) & 0xff);
    NF_ADDR((dwStartPage >> 8) & 0xff);
    if(g_bNeedExtAddr)
    {
        NF_ADDR((dwStartPage >> 16) & 0xff);
    }

    NF_WRDATA_BYTE(BADBLOCKMARK);

    //  Copmlete the write
    NF_CMD(CMD_WRITE2);

    //  Wait for RB
    NF_DETECT_RB();     // Wait tR(max 12us)

    if ( NF_RDSTAT & STATUS_ILLACC )
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page (Illegal Access) %d!\n")));
        g_pNFConReg->NFSTAT =  STATUS_ILLACC;    // Write 1 to clear.
        bRet = FALSE;
    }
    else
    {
        //  Check the status of program
        NF_CMD(CMD_STATUS);

        if( NF_RDDATA_BYTE() & STATUS_ERROR)
        {
            RETAILMSG(FMD_ZONE_ERROR, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page %d!\n")));
            bRet = FALSE;
        }
    }

    //  Disable chip select
    NF_nFCE_H();

    return bRet;
}

BOOL NAND_LB_IsBlockBad(BLOCK_ID blockID)
{
    DWORD   dwPageID = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
    BOOL    bRet = FALSE;
    BYTE    bFlag;

    //  Enable the chip
    NF_nFCE_L();
    NF_CLEAR_RB();

    //  Issue the command
    NF_CMD(CMD_READ);

    //  Set up address
    NF_ADDR((NAND_PAGE_SIZE+LB_POS_BADBLOCK)&0xff);
    NF_ADDR(((NAND_PAGE_SIZE+LB_POS_BADBLOCK)>>8)&0xff);
    NF_ADDR((dwPageID) & 0xff);
    NF_ADDR((dwPageID >> 8) & 0xff);
    if(g_bNeedExtAddr)
    {
        NF_ADDR((dwPageID >> 16) & 0xff);
    }

    NF_CMD(CMD_READ3);

    //  Wait for Ready bit
    NF_DETECT_RB();     // Wait tR(max 12us)

    //  Now get the byte we want
    bFlag = (BYTE)NF_RDDATA_BYTE();

    if(bFlag != 0xff)
    {
        RETAILMSG(FMD_ZONE_STATUS, (TEXT("FMDLB: IsBlockBad - Page #: 0x%x \r\n"), dwPageID));
        bRet = TRUE;
    }

    //  Disable the chip
    NF_nFCE_H();

    return bRet;
}

#ifdef _IROMBOOT_
BOOL FMD_LB_WriteSector_Steploader(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    DWORD   i;
    UINT16 nSectorLoop;
    int NewDataAddr = 0;
    int NewSectorAddr = startSectorAddr;
    MECC8 t8MECC[4];

    //Check Parameters.
    if (!pSectorBuff && !pSectorInfoBuff)
    {
        return(FALSE);
    }
    if ( dwNumSectors > 1 )
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("######## FATAL ERROR => FMD::FMD_WriteSector->dwNumsectors is bigger than 1. \r\n")));
        return FALSE;
    }

    g_pNFConReg->NFCONF = (g_pNFConReg->NFCONF & ~(1<<30)) | (1<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
    g_pNFConReg->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9); 
    g_pNFConReg->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));

    //  Enable Chip
    NF_nFCE_L();

    //  Issue command
    NF_CMD(CMD_WRITE);    //0x80

    //  Setup address to write Main data
    NF_ADDR((NewDataAddr)&0xff);    // 2bytes for column address
    NF_ADDR((NewDataAddr>>8)&0xff);
    NF_ADDR((NewSectorAddr)&0xff);    // 3bytes for row address
    NF_ADDR((NewSectorAddr>>8)&0xff);
//    if(g_bNeedExtAddr)
    {
        NF_ADDR((NewSectorAddr>>16)&0xff);
    }

    // initialize variable.
    for(i = 0; i < 4; i++) {
        t8MECC[i].n8MECC0 = 0x0;
        t8MECC[i].n8MECC1 = 0x0;
        t8MECC[i].n8MECC2 = 0x0;
        t8MECC[i].n8MECC3 = 0x0;
    }

    // Write each Sector in the Page. (4 Sector per Page, Loop 4 times.)
    for (nSectorLoop = 0; nSectorLoop < SECTORS_PER_PAGE; nSectorLoop++)
    {
        //  Initialize ECC register
        NF_MECC_UnLock();
        NF_RSTECC();        

        // Special case to handle un-aligned buffer pointer.
        if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3) 
        {
            //  Write the data        
            WrPage512Unalign(pSectorBuff+nSectorLoop*SECTOR_SIZE);
        }
        else
        {
            WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
        }

        NF_MECC_Lock();

        while(!(g_pNFConReg->NFSTAT&(1<<7)));
        g_pNFConReg->NFSTAT|=(1<<7);

        //  Read out the ECC value generated by HW
        t8MECC[nSectorLoop].n8MECC0 = NF_8MECC0();
        t8MECC[nSectorLoop].n8MECC1 = NF_8MECC1();
        t8MECC[nSectorLoop].n8MECC2 = NF_8MECC2();
        t8MECC[nSectorLoop].n8MECC3 = (NF_8MECC3() & 0xff);

    }

    for(nSectorLoop = 0; nSectorLoop < 4; nSectorLoop++)
    {
        NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC0); // 4 byte n8MECC0
        NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC1); // 4 byte n8MECC1
        NF_WRDATA_WORD(t8MECC[nSectorLoop].n8MECC2); // 4 byte n8MECC2
        NF_WRDATA_BYTE((t8MECC[nSectorLoop].n8MECC3) & 0xff); // 1 byte n8MECC3
    }

    g_pNFConReg->NFSTAT |=  (1<<4); //NF_CLEAR_RB

    //  Finish up the write operation
    NF_CMD(CMD_WRITE2);    // 0x10

    NF_DETECT_RB();     // Wait tR(max 12us)

    NF_CMD(CMD_STATUS);   // Read status command       

    for(i=0;i<3;i++);  //twhr=60ns

    if(NF_RDDATA_BYTE() & STATUS_ERROR)
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
        //  Disable the chip
        NF_nFCE_H();
        g_pNFConReg->NFCONF = (0<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
        return FALSE;
    }
    else
    {
        NF_nFCE_H();
        g_pNFConReg->NFCONF = (0<<23) | (NAND_TACLS <<12) | (NAND_TWRPH0 <<8) | (NAND_TWRPH1 <<4);
        return TRUE;
    }
}
#endif

BOOL RAW_LB_ReadSector(UINT32 startSectorAddr, LPBYTE pSectorBuff, LPBYTE pSectorInfoBuff)
{
    UINT32 nPageAddr = startSectorAddr;
    DWORD  i;
    UINT32 nRetEcc = 0;
    UINT32 nSectorLoop;
    UINT32 nColAddr = 0;

    if (!pSectorBuff && !pSectorInfoBuff)
        return(FALSE);

    NF_nFCE_L();

    NF_CLEAR_RB();

    NF_CMD(CMD_READ);                            // Send read command.

    NF_ADDR((nColAddr)&0xff);
    NF_ADDR((nColAddr>>8)&0xff);
    NF_ADDR((nPageAddr)&0xff);
    NF_ADDR((nPageAddr>>8)&0xff);
    if (g_bNeedExtAddr)
    {
        NF_ADDR((nPageAddr>>16)&0xff);  
    }

    NF_CMD(CMD_READ3);    // 2nd command
    NF_DETECT_RB();                                // Wait for command to complete.

    for (nSectorLoop = 0; nSectorLoop < 4; nSectorLoop++)
    {
        if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3)
        {
            RdPage512Unalign(pSectorBuff+nSectorLoop*SECTOR_SIZE);
        }
        else
        {
            RdPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);                    // Read page/sector data.
        }
    }

    for(i=0; i<64; i++)
    {
        *pSectorInfoBuff = NF_RDDATA_BYTE();        // read and trash the data
        pSectorInfoBuff+=1;
    }

    NF_nFCE_H();

    return(TRUE);
}

⌨️ 快捷键说明

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