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

📄 nand.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));
    
    while (dwNumBlocks--)
    {
        // If the block is marked bad, skip to next block.  Note that the assumption in our error checking
        // is that any truely bad block will be marked either by the factory during production or will be marked
        // during the erase and write verification phases.  If anything other than a bad block fails ECC correction
        // in this routine, it's fatal.

        OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
        OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
        OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));


        if (g_ImageType == IMAGE_TYPE_LOADER)
        {
            FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);

            // Stepldr & Eboot image in nand flash
            // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
            if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 ))
            {
                ++dwBlock;
                ++dwNumBlocks;        // Compensate for fact that we didn't write any blocks.
                continue;
            }
            if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) 
            {
                OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
                return(FALSE);
            }
        }

        if (!FMD_EraseBlock(dwBlock)) 
        {
            OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
            return FALSE;
        }

        if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf,g_ImageType)) 
        {
            OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
            return(FALSE);
        }

        ++dwBlock;
        pbBuffer += g_FlashInfo.dwBytesPerBlock;
    }

    if (g_ImageType == IMAGE_TYPE_LOADER)
    {
    	g_pTOC->id[0].dwLoadAddress = dwImageStart;
    	g_pTOC->id[0].dwJumpAddress = 0;
    	g_pTOC->id[0].dwTtlSectors  = FILE_TO_SECTOR_SIZE(dwImageLength);
    	g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
    	g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
    }

    OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n")));
    return TRUE;
}





/*
int CorrectECC8Data(unsigned char *pEncodingBaseAddr)
{
    unsigned int i,uErrorByte[9];
    unsigned char uErrorBit[9];
    unsigned int uErrorType;


    uErrorType = (s2450NAND->NF8ECCERR0>>25)&0xf;// Searching Error Type //How many Error bits does exist?	
    uErrorByte[1] = s2450NAND->NF8ECCERR0&0x3ff;// Searching Error Byte //Where is the error byte?
    uErrorByte[2] = (s2450NAND->NF8ECCERR0>>15)&0x3ff;	
    uErrorByte[3] = (s2450NAND->NF8ECCERR1)&0x3ff;
    uErrorByte[4] = (s2450NAND->NF8ECCERR1>>11)&0x3ff;	
    uErrorByte[5] = (s2450NAND->NF8ECCERR1>>22)&0x3ff;	
    uErrorByte[6] = (s2450NAND->NF8ECCERR2)&0x3ff;
    uErrorByte[7] = (s2450NAND->NF8ECCERR2>>11)&0x3ff;
    uErrorByte[8] = (s2450NAND->NF8ECCERR2>>22)&0x3ff;

    uErrorBit[1] = s2450NAND->NFMLC8BITPT0&0xff;// Searching Error Bit //Where is the error bit?
    uErrorBit[2] = (s2450NAND->NFMLC8BITPT0>>8)&0xff;
    uErrorBit[3] = (s2450NAND->NFMLC8BITPT0>>16)&0xff;
    uErrorBit[4] = (s2450NAND->NFMLC8BITPT0>>24)&0xff;	
    uErrorBit[5] = s2450NAND->NFMLC8BITPT1&0xff;
    uErrorBit[6] = (s2450NAND->NFMLC8BITPT1>>8)&0xff;
    uErrorBit[7] = (s2450NAND->NFMLC8BITPT1>>16)&0xff;
    uErrorBit[8] = (s2450NAND->NFMLC8BITPT1>>24)&0xff;

    if(uErrorType == 0x0)
    {
        RETAILMSG(1, (TEXT("++++++++++ ECC No ERROR +++++++++++\r\n")));
        return 0;
    }

    if(uErrorType == 0x9)
    {
        RETAILMSG(1, (TEXT("++++++++++ ECC Uncorrectable ERROR +++++++++++\r\n")));
        return 1;
    }
    for(i=1;i<=uErrorType ;i++)
    {
        if(uErrorByte[i] < 512)
            pEncodingBaseAddr[uErrorByte[i]]^=uErrorBit[i];
        else
        {;}
    }
    RETAILMSG(1, (TEXT("++++++++++ ECC correctable ERROR +++++++++++\r\n")));
    return 0;
}

*/


BOOL FMD_LB_WriteSector_Steploader(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors, int mode)
{
    DWORD   i;
    UINT16 nSectorLoop;
    volatile DWORD	wrdata;
    int NewSpareAddr = 0x0;
    int NewDataAddr = 0;
    int NewSectorAddr = startSectorAddr;
    MECC8 t8MECC[4];

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

    BOOL bLastMode = SetKMode(TRUE);	// dummy function.

    s2450NAND->NFCONF = (s2450NAND->NFCONF & ~(1<<30)) | (1<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
    s2450NAND->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9); 
    s2450NAND->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));

    //  Enable Chip
    NF_nFCE_L();	// NFCONT狼 [1]甫 0栏肺 努府绢 ... Force nFCE to low

    //  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);
    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
            for(i=0; i<SECTOR_SIZE/sizeof(DWORD); i++)
            {
                wrdata = (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+0];
                wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+1]<<8;
                wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+2]<<16;
                wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+3]<<24;
                NF_WRDATA_WORD(wrdata);
            }
        }
        else
        {
            WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
        }

        NF_MECC_Lock();

        while(!(s2450NAND->NFSTAT&(1<<7))) ;
        s2450NAND->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);

        /*  //Debug Code :: Print Write Data
        RETAILMSG(1, (TEXT("\r\n===================WRITE DATA=====================")));
        for(i=0;i<512;i++)
        {
            if(i%16 == 0) 
                RETAILMSG(1, (TEXT("\r\n")));
            RETAILMSG(1, (TEXT(" 0x%x "),*(pSectorBuff+(nSectorLoop*SECTOR_SIZE) + i)));
        }
        RETAILMSG(1, (TEXT("\r\n===================================================\r\n")));

        RETAILMSG(1, (TEXT("FMD_LB_WriteSector_Steploader() : Sdata : 0x%x, 0x%x, 0x%x, 0x%x\r\n")
                , t8MECC[nSectorLoop].n8MECC0
                , t8MECC[nSectorLoop].n8MECC1
                , t8MECC[nSectorLoop].n8MECC2
                , t8MECC[nSectorLoop].n8MECC3));
        */
    }

    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
    }

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

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

    //  Wait for RB. 促 结龙 锭 鳖瘤 扁促赴促. 
    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(1, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
        //  Disable the chip
        NF_nFCE_H();
        s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
        SetKMode(bLastMode);	// Dummy function.
        return FALSE;
    }
    else
    {
        NF_nFCE_H();
        s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
        SetKMode(bLastMode);	// Dummy function.
        return TRUE;
    }

/*
    //============ Start of READ TEST CODE ============//
    DWORD SpareDataDummy0;
    DWORD SpareDataDummy1;
    DWORD SpareDataDummy2;
    DWORD SpareDataDummy3;

    DWORD dwOffset;
    DWORD dwCnt;
    DWORD dwSpareAddress = 2048;        //include Bad block
    UINT8 tempdata[2048];

    unsigned char uSctCnt = 4;
    BOOL bRet = TRUE;

    s2450NAND->NFCONF = ( s2450NAND->NFCONF&~(0x3<<23) ) |(2<<30)|(1<<23)|(0x7<<12)|(0x7<<8)|(0x7<<4);
    s2450NAND->NFCONT = ( s2450NAND->NFCONT&~(0x1<<18) ) |(0<<18)|(0<<11)|(0<<10)|(0<<9)|(1<<6)|(1<<0); // Init NFCONT
    s2450NAND->NFSTAT|= ((1<<6)|(1<<5)|(1<<4));

    // NAND RESET
    NF_nFCE_L();
    NF_CMD(0xff);
    NF_nFCE_H();

    NF_MECC_Lock(); // Main ECC Lock
    NF_nFCE_L();
    s2450NAND->NFSTAT |= (1<<4); // RnB Clear

    NF_CMD(CMD_READ);
    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);
    NF_ADDR((NewSectorAddr>>16)&0xff);
    NF_CMD(CMD_READ3);
    NF_DETECT_RB();
    s2450NAND->NFSTAT |= (1<<4); // RnB Clear

    //READ Spare ECC Data
    for(dwCnt = 0; dwCnt < uSctCnt; dwCnt++)
    {
        NF_MECC_Lock(); // Main ECC Lock
        s2450NAND->NFSTAT |= (1<<4); // RnB Clear

        if(!dwCnt)
        {
            NF_CMD(CMD_READ);
            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);
            NF_ADDR((NewSectorAddr>>16)&0xff);
            NF_CMD(CMD_READ3);

            NF_DETECT_RB();
            s2450NAND->NFSTAT |= (1<<4); // RnB Clear
        }
        else
        {
            dwOffset = dwCnt * 512;
            NF_CMD(0x05);
            NF_ADDR(dwOffset&0xFF);
            NF_ADDR((dwOffset>>8)&0xFF);
            NF_CMD(0xE0);
        }

        NF_MECC_UnLock();   // Main ECC Unlock
        NF_RSTECC();        // Initialize ECC

        //read 512byte
        RdPage512(tempdata + 512*dwCnt);

        dwOffset = 2048 + (dwCnt * 13);
        NF_CMD(0x05);
        NF_ADDR(dwOffset&0xFF);
        NF_ADDR((dwOffset>>8)&0xFF);
        NF_CMD(0xE0);

        //read Spare ECC Data
        SpareDataDummy0 = NF_RDDATA_WORD();
        SpareDataDummy1 = NF_RDDATA_WORD();
        SpareDataDummy2 = NF_RDDATA_WORD();
        SpareDataDummy3 = NF_RDDATA_BYTE();

        NF_MECC_Lock(); // Main ECC Lock

        while(!(s2450NAND->NFSTAT&(1<<6)));     // Check decoding done 
        s2450NAND->NFSTAT = s2450NAND->NFSTAT | (1<<6);   // Decoding done Clear

        while( s2450NAND->NF8ECCERR0 & (unsigned int)(1<<31) ) ; // 8bit ECC Decoding Busy Check.

        if(CorrectECC8Data((tempdata + 512*dwCnt)))
        {
            return FALSE;
        }

        // Debug Code : Print Read Data
        RETAILMSG(1, (TEXT("\r\n===================READ DATA=====================")));
        for(i=0;i<512;i++)
        {
            if(i%16 == 0) 
                RETAILMSG(1, (TEXT("\r\n")));
            RETAILMSG(1, (TEXT(" 0x%x "),*(tempdata+(dwCnt*SECTOR_SIZE) + i)));
        }
        RETAILMSG(1, (TEXT("\r\n===================================================\r\n")));

        RETAILMSG(1, (TEXT("FMD_LB_WriteSector_Steploader() : Sdata : 0x%x, 0x%x, 0x%x, 0x%x\r\n")
                , SpareDataDummy0
                , SpareDataDummy1
                , SpareDataDummy2
                , SpareDataDummy3));
    }

    NF_nFCE_H();
    s2450NAND->NFCONF = (0<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
    SetKMode(bLastMode);        // Dummy function.
    return TRUE;
    //============ End of READ TEST CODE ============//
*/
}

⌨️ 快捷键说明

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