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

📄 nand.cpp

📁 smdk2450 ce6 bsp,需要的朋友可以参考以下.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to open existing partition.\r\n")));
        return(FALSE);
    }

    // Set the partition file pointer to the correct offset for the kernel region.
    //
    if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) )
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"),
            g_pTOC->id[g_dwTocEntry].dwStoreOffset));
        return(FALSE);
    }

    // Read the kernel region from the Boot Media into RAM.
    //
    if ( !BP_ReadData( hPart,
                       (LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress),
                       SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) )
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to read kernel region from partition.\r\n")));
        return(FALSE);
    }

    if (!g_pTOC->chainInfo.dwLoadAddress)
    {
        chainaddr = g_pTOC->chainInfo.dwLoadAddress;
        flashaddr = g_pTOC->chainInfo.dwFlashAddress;
        for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
        {
            OALMSG(TRUE, (TEXT("chainaddr=0x%x, flashaddr=0x%x\r\n"), chainaddr, flashaddr+i));

            if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) )
            {
                OALMSG(OAL_ERROR, (TEXT("TOC ERROR: Unable to read/verify TOC\r\n")));
                return FALSE;
            }
            chainaddr += 512;
        }
    }
    OALMSG(OAL_FUNC, (TEXT("_ReadOSImageFromBootMedia\r\n")));
    return(TRUE);
}


BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
    for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
        if (!FMD_ReadSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1))
            return FALSE;
        if (pbBlock)
            pbBlock += g_FlashInfo.wDataBytesPerSector;
        if (pSectorInfoTable)
            pSectorInfoTable++;        
    }
    return TRUE;
}

BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable, DWORD dwImageType)
{
    for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
        if(dwImageType == IMAGE_TYPE_LOADER)
        {
            if (!FMD_WriteSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1))
            return FALSE;
        }
        else if(dwImageType == IMAGE_TYPE_STEPLDR)
        {
            if(IS_LB)
            {
                if (!FMD_LB_WriteSector_Steploader(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1, USE_NFCE))
                return FALSE;
        }
            else
            {
                if(!FMD_SB_WriteSector_Steploader(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1, USE_NFCE))
                    return FALSE;
            }
        }
        if (pbBlock)
            pbBlock += g_FlashInfo.wDataBytesPerSector;
        if (pSectorInfoTable)        
            pSectorInfoTable++;        
    }
    return TRUE;
}

BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
    DWORD dwBlock,dwNumBlocks;
    LPBYTE pbBuffer;
    SectorInfo si;

    OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n")));

    if ( !g_bBootMediaExist ) 
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n")));
        return(FALSE);
    }

    if (g_ImageType == IMAGE_TYPE_LOADER)
    {
        dwBlock = EBOOT_BLOCK;
        if ( !VALID_TOC(g_pTOC) ) 
        {
            OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: INVALID_TOC\r\n")));
            if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) 
            {
                OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n")));
                return(FALSE);
        	}
    	}
    }
    else if (g_ImageType == IMAGE_TYPE_STEPLDR)
    {
        dwBlock = NBOOT_BLOCK;
        dwImageStart += dwLaunchAddr;
        dwImageLength = 0x1000; //step loader can support 4k bytes only.
    }

    pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);
 
    // Compute number of blocks.
    //dwNumBlocks = (dwImageLength / 0x4000) + 1;
    dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);
    OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength));
    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))) ;

⌨️ 快捷键说明

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