lescy 发表于 2010-8-9 07:09:26

【分享】飞凌S3C6410 NAND Flash驱动程序 WindowsCE版

这段时间一直在研究S3C6410 NAND驱动,把找到的一些源码发出来,希望对正在做这部分的朋友有所帮助。

    由于内容比较长,受字数和篇幅限制,详细代码可以在附件中下载。

本文转引自 飞凌嵌入式 ARM11 OK6410讨论区 www.witech.com.cn


// Copyright (c) Microsoft Corporation.All rights reserved.
//
#include <fmd.h>
#include <nkintr.h>
#include <oal.h>

// 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 <ethdbg.h>
#include "Cfnand.h"
//#include <kitl.h>

//#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_Init() ****\r\n")));



       

    if (pRegIn && pRegIn->MemBase.Num && pRegIn->MemBase.Reg)
    {
      g_pNFConReg = (S3C6410_NAND_REG *)(pRegIn->MemBase.Reg);
    }
    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_Init() : Unknown ID = 0x%08x\n"), nNandID));
      return NULL;
    }

    NUM_OF_BLOCKS = astNandSpec.nNumOfBlks;
    PAGES_PER_BLOCK = astNandSpec.nPgsPerBlk;
    SECTORS_PER_PAGE = astNandSpec.nSctsPerPg;

    RETAILMSG(1, (TEXT(" --FMD_Init()\n")));

    return((PVOID)g_pNFConReg);
}


BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    BOOL bRet;

    //RETAILMSG(1, (TEXT(" \n"), startSectorAddr));
#if (NAND_DEBUG)
    RETAILMSG(1, (TEXT(" ++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_ReadSector()\n")));
#endif

    return bRet;
}


BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
    BOOL    bRet = TRUE;

#if (NAND_DEBUG)
    RETAILMSG(1, (TEXT(" ++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_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_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_WriteSector()\n")));
#endif

    return bRet;
}


VOID FMD_PowerUp(VOID)
{
#if (NAND_DEBUG)
    RETAILMSG(1, (TEXT(" 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)

完整代码请参照附件内容。


点击此处下载 ourdev_573844.txt(文件大小:46K) (原文件名:【附件】OK6410NAND驱动源码.txt)

Ayuflyhigh 发表于 2010-8-12 09:57:41

沙发自己坐了,呵呵

erichcn 发表于 2010-8-12 10:20:05

顶一下

Ayuflyhigh 发表于 2010-8-16 07:56:55

楼主有程序注释吗?

prococo 发表于 2010-8-23 11:43:42

mark

Ayuflyhigh 发表于 2010-8-30 08:22:41

楼主有程序注释吗?

prococo 发表于 2010-8-30 08:25:47

说实话,没有注释还真看不太明白,我是菜鸟....

goooogleman 发表于 2010-8-30 08:29:31

楼主你············
只贴个代码,啥特色,改进也不说
这不是害我们嘛
哈哈哈

赶紧注释吧
不然看的费劲。

Ayuflyhigh 发表于 2010-9-10 12:16:34

说的是,呵呵。我也加紧搞一下,再分享给大家O(∩_∩)O

prococo 发表于 2010-9-17 11:54:55

pro

liouravr 发表于 2010-9-19 15:21:15

6410的,很强悍啊

yulri 发表于 2010-9-20 09:37:03

mark

Ayuflyhigh 发表于 2010-9-26 08:17:59

看看先
页: [1]
查看完整版本: 【分享】飞凌S3C6410 NAND Flash驱动程序 WindowsCE版