ison

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  19 随笔 :: 0 文章 :: 0 评论 :: 0 Trackbacks

1.2.1. 涉及文件

Lib_arm/board.c

Board/smdk2410/smdk2410.c

Board/smdk2410/smdk2410.h

Driver/Nand_legacy/ Nand_legacy.c

Include/configs/smdk2410.h

1.2.2. 具体分析

Lib_arm/board.c

u-boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果定义了这个宏,系统调用drivers/nnd/nand.c中的nand_init();否则调用自己在board/smdk2410/smdk2410.c中的nand_init()函数。这里我们选择第二种方式。

Board/smdk2410/smdk2410.h

这个头文件中实现了对nand flash各个寄存器的设置工作。把原程序列出来更直观些。

static inline void NF_Conf(u16 conf)   /* 控制寄存器设置 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       nand->NFCONF = conf;

}

static inline void NF_Cmd(u8 cmd)   /* 命令寄存器传递命令 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       nand->NFCMD = cmd;

}

static inline void NF_CmdW(u8 cmd)   /* 命令寄存器写操作 */

{

       NF_Cmd(cmd);

       udelay(1);

}

static inline void NF_Addr(u8 addr)    /* 地址寄存器设置 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       nand->NFADDR = addr;

}

static inline void NF_SetCE(NFCE_STATE s)   /* 设置nand flash的片选信号 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       switch (s) {

              case NFCE_LOW:

                     nand->NFCONF &= ~(1<<11);

                     break;

              case NFCE_HIGH:

                     nand->NFCONF |= (1<<11);

                     break;

       }

}

static inline void NF_WaitRB(void)     /* 等待 nand flash处于 Ready状态 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       while (!(nand->NFSTAT & (1<<0)));

}

static inline void NF_Write(u8 data)    /* 写数据操作 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       nand->NFDATA = data;

}

static inline u8 NF_Read(void)   /* 读数据操作 */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       return(nand->NFDATA);

}

static inline void NF_Init_ECC(void) /* 初始化ECC */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       nand->NFCONF |= (1<<12);

}

static inline u32 NF_Read_ECC(void) /* 读取ECC */

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       return(nand->NFECC);

}

Board/smdk2410/smdk2410.c

前面提到了nand_init()函数的实现就是在smdk2410.c中,下面我们就来看看nand flash 是怎么初始化的。

void

nand_init(void)

{

       S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

       NF_Init();      

#ifdef DEBUG

       printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);

#endif

       printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);

}

static inline void NF_Init(void)

{

#if 0 /* a little bit too optimistic */

#define TACLS   0

#define TWRPH0 3

#define TWRPH1 0

#else

#define TACLS   0

#define TWRPH0 4

#define TWRPH1 2

#endif

    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));

    /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */

    /* 1 1    1     1,   1      xxx, r xxx,   r xxx */

    /* En 512B 4step ECCR nFCE="H" tACLS   tWRPH0   tWRPH1 */

    NF_Reset();

}

static inline void NF_Reset(void)

{

    int i;

    NF_SetCE(NFCE_LOW);

    NF_Cmd(0xFF);           /* reset command */

    for(i = 0; i < 10; i++);    /* tWB = 100ns. */

    NF_WaitRB();        /* wait 200~500us; */

    NF_SetCE(NFCE_HIGH);

}

可以看到nand_init()调用 NF_Init()函数,使能nand flash控制器和nand flash;调用NF_Reset()函数置位,NF_WaitRB()查询nand flash的状态,最后在调用nand_probe((ulong)nand)函数探测nand flash.

Driver/Nand_legacy/ Nand_legacy.c

这个文件中的函数由u-boot 中对nand flash 操作的命令函数调用。

Include/configs/smdk2410.h

此文件中主要是对nand flash相关的一些参数进行设置。贴出来看下,有些感性的认识。

/*-----------------------------------------------------------------------

* NAND flash settings

*/

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

#define CFG_NAND_LEGACY

#define CFG_MAX_NAND_DEVICE   1     /* Max number of NAND devices        */

#define SECTORSIZE 512

#define ADDR_COLUMN 1

#define ADDR_PAGE 2

#define ADDR_COLUMN_PAGE 3

#define NAND_ChipID_UNKNOWN 0x00

#define NAND_MAX_FLOORS 1

#define NAND_MAX_CHIPS 1

#define NAND_WAIT_READY(nand)   NF_WaitRB()

#define NAND_DISABLE_CE(nand)    NF_SetCE(NFCE_HIGH)

#define NAND_ENABLE_CE(nand)     NF_SetCE(NFCE_LOW)

#define WRITE_NAND_COMMAND(d, adr)      NF_Cmd(d)

#define WRITE_NAND_COMMANDW(d, adr)   NF_CmdW(d)

#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)

#define WRITE_NAND(d, adr)            NF_Write(d)

#define READ_NAND(adr)                 NF_Read()

/* the following functions are NOP's because S3C24X0 handles this in hardware */

#define NAND_CTL_CLRALE(nandptr)

#define NAND_CTL_SETALE(nandptr)

#define NAND_CTL_CLRCLE(nandptr)

#define NAND_CTL_SETCLE(nandptr)

#define CONFIG_MTD_NAND_VERIFY_WRITE     1

#define CONFIG_MTD_NAND_ECC_JFFS2      1

#endif     /* CONFIG_COMMANDS & CFG_CMD_NAND */

http://blog.ednchina.com/icexiong/126067/message.aspx
posted on 2008-09-20 22:18 ison 阅读(470) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。