|
|
??? 这段时间一直在研究S3C6410 NAND驱动,把找到的一些源码发出来,希望对正在做这部分的朋友有
所帮助。
??? 由于内容比较长,受字数和篇幅限制,详细代码可以在附件中下载。
?
本文转引自 飞凌嵌入式 ARM11 OK6410讨论区 www.witech.com.cn
// Copyright (c) Microsoft Corporation.? All rights reserved.
//
#include
#include
#include
// BSP Configuration Files
#include "bsp_cfg.h"
#include "bsp_base_reg_cfg.h"
// Base Definitions
#include "s3c6410_base_regs.h"
#include "s3c6410_nand.h"
#include "s3c6410_syscon.h"
//#include
#include "Cfnand.h"
//#include
//#define SYNC_OP
#define CHECK_SPAREECC??? (1)
#define NAND_DEBUG??????? (0)
#define NAND_BASE??????? (0xB0200000)??? // PA:0x70200000
#define SYSCON_BASE??????? (0xB2A0F000)??? // PA:0x7E00F000
#ifdef??? SYNC_OP
CRITICAL_SECTION??? g_csNandFlash;
#endif
static volatile S3C6410_NAND_REG *g_pNFConReg = NULL;
static volatile S3C6410_SYSCON_REG *g_pSysConReg = NULL;
NANDDeviceInfo GetNandInfo(void) { return stDeviceInfo; }
static DWORD ReadFlashID(void)
{
??? BYTE Mfg, Dev;
??? int i;
??? NF_nFCE_L();??????????????? // Deselect the flash chip.
??? NF_CMD(CMD_READID);??????? // Send flash ID read command.
??? NF_ADDR(0);
??? for (i=0; iMemBase.Reg[0]);
??? }
??? else
??? {
??????? g_pNFConReg = (S3C6410_NAND_REG *)NAND_BASE;
??? }
??? g_pSysConReg = (S3C6410_SYSCON_REG *)SYSCON_BASE;
#ifdef??? SYNC_OP
??? InitializeCriticalSection(&g_csNandFlash);
??? EnterCriticalSection(&g_csNandFlash);
#endif
??? if (!bNandExt)
??? {
??????? RETAILMSG(1, (TEXT("[FMD:ERR] FMD_Init() : Unknown ID = 0x%08x\n"), nNandID));
??????? return NULL;
??? }
??? NUM_OF_BLOCKS = astNandSpec[nCnt].nNumOfBlks;
??? PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk;
??? SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg;
??? RETAILMSG(1, (TEXT("[FMD] --FMD_Init()\n")));
??? return((PVOID)g_pNFConReg);
}
BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo
pSectorInfoBuff, DWORD dwNumSectors)
{
??? BOOL bRet;
??? //RETAILMSG(1, (TEXT("[R:0x%08x] \n"), startSectorAddr));
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] ++FMD_ReadSector(0x%08x) \n"), startSectorAddr));
#endif
#ifdef??? SYNC_OP
??? EnterCriticalSection(&g_csNandFlash);
#endif
??? if ( IS_LB )
??? {
??????? bRet = FMD_LB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff,
dwNumSectors, USE_NFCE);
??? }
??? else
??? {
??????? bRet = FMD_SB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff,
dwNumSectors, USE_NFCE);
??? }
#ifdef??? SYNC_OP
??? LeaveCriticalSection(&g_csNandFlash);
#endif
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] --FMD_ReadSector()\n")));
#endif
??? return bRet;
}
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
??? BOOL??? bRet = TRUE;
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] ++FMD_EraseBlock(0x%08x) \n"), blockID));
#endif
#ifdef??? SYNC_OP
??? EnterCriticalSection(&g_csNandFlash);
#endif
??? if ( IS_LB )
??? {
??????? bRet = FMD_LB_EraseBlock(blockID, USE_NFCE);
??? }
??? else
??? {
??????? bRet = FMD_SB_EraseBlock(blockID, USE_NFCE);
??? }
#ifdef??? SYNC_OP
??? LeaveCriticalSection(&g_csNandFlash);
#endif
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] --FMD_EraseBlock()\n")));
#endif
??? return bRet;
}
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo
pSectorInfoBuff, DWORD dwNumSectors)
{
??? BOOL??? bRet = TRUE;
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector(0x%08x) \n"), startSectorAddr));
#endif
#ifdef??? SYNC_OP
??? EnterCriticalSection(&g_csNandFlash);
#endif
??? if ( IS_LB )
??? {
??????? bRet = FMD_LB_WriteSector(startSectorAddr, pSectorBuff, pSectorInfoBuff,
dwNumSectors, USE_NFCE);
??? }
??? else
??? {
??????? bRet = FMD_SB_WriteSector(startSectorAddr, pSectorBuff, pSectorInfoBuff,
dwNumSectors, USE_NFCE);
??? }
#ifdef??? SYNC_OP
??? LeaveCriticalSection(&g_csNandFlash);
#endif
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] --FMD_WriteSector()\n")));
#endif
??? return bRet;
}
VOID FMD_PowerUp(VOID)
{
#if (NAND_DEBUG)
??? RETAILMSG(1, (TEXT("[FMD] FMD_PowerUp() \n")));
#endif
??? // Set up initial flash controller configuration.
??? g_pNFConReg->NFCONF = (TACLS |
|