這段時間一直在研究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; i<10; i++) { Mfg = NF_RDDATA_BYTE(); if (Mfg == 0xEC || Mfg == 0x98) break; } Dev = NF_RDDATA_BYTE(); NF_nFCE_H(); return ((DWORD)(Mfg<<8)+Dev); } PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut) { volatile DWORD nNandID; UINT8 nMID, nDID; UINT32 nCnt; BOOL bNandExt = FALSE; RETAILMSG(1, (TEXT("[FMD] ++FMD_Init() ****\r\n"))); if (pRegIn && pRegIn->MemBase.Num && pRegIn->MemBase.Reg[0]) { g_pNFConReg = (S3C6410_NAND_REG *)(pRegIn->MemBase.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<<12) | (TWRPH0<<8) | (TWRPH1<<4); g_pNFConReg->NFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)| (1<<4)|(0x3<<1)|(1<<0); g_pNFConReg->NFSTAT = (1<<4); } VOID FMD_PowerDown(VOID) |