Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38087
  • 博文数量: 8
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 310
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-23 15:14
文章分类
文章存档

2009年(7)

2008年(1)

我的朋友

分类: LINUX

2009-03-23 22:08:51

 

Arm-linux东东nand4: nand_command

nand_get_flash_type()->chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);

我们一段一段来.因为不能添图片了,实在大多图了.

static void nand_command(struct mtd_info *mtd, unsigned int command,

                      int column, int page_addr)

{

       register struct nand_chip *chip = mtd->priv;

       int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;

 

       /*

        * Write out the command to the device.

        */

       if (command == NAND_CMD_SEQIN) {

              int readcmd;

 

              if (column >= mtd->writesize) {

                     /* OOB area */

                     column -= mtd->writesize;

                     readcmd = NAND_CMD_READOOB;

              } else if (column < 256) {

                     /* First 256 bytes --> READ0 */

                     readcmd = NAND_CMD_READ0;

              } else {

                     column -= 256;

                     readcmd = NAND_CMD_READ1;

              }

              chip->cmd_ctrl(mtd, readcmd, ctrl);

              ctrl &= ~NAND_CTRL_CHANGE;

       }

NAND_CTRL_CLE表示是发送命令.等下会看到如果设了NAND_CTRL_CLE S3C2440就会将数据写到命令寄存器中去. NAND_CTRL_CHANGE用的比较少.表示CHANGE.

如果命令是NAND_CMD_SEQIN就表示有数据了.还记不记得说过一页分为ABC.那总该选一下吧.如果column大于writesize假设是512的页那么就是大于512就表示C.就发送这样的命令给它NAND_CMD_READOOB    0x50,其他以此类推.就不说了.

有些人就会问了.选中了一个区.而我的数据超过了那个区的容量.那怎么办呀:

 
 

看到没有如果是A区开始It depends on how many data are inputted 也就是可以超界.谁叫我是A区呢.从图可以看到只要下面还有区就可以超过.

chip->cmd_ctrl(mtd, readcmd, ctrl);

ctrl &= ~NAND_CTRL_CHANGE;

这两句就是发送命令选择区了.ctrl就更改了值.表示chage.关于怎么样发送.后面说.

 

       ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;

       /* Serially input address */

       if (column != -1) {

              /* Adjust columns for 16 bit buswidth */

              if (chip->options & NAND_BUSWIDTH_16)

                     column >>= 1;

              chip->cmd_ctrl(mtd, column, ctrl);

              ctrl &= ~NAND_CTRL_CHANGE;

       }

       if (page_addr != -1) {

              chip->cmd_ctrl(mtd, page_addr, ctrl);

              ctrl &= ~NAND_CTRL_CHANGE;

              chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);

              /* One more address cycle for devices > 32MiB */

              if (chip->chipsize > (32 << 20))

                     chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);

       }

接下来就要发送地址了. NAND_CTRL_ALE就表示地址.column-1就表示没有地址.这里很好理解了.来看一下这个:

              /* One more address cycle for devices > 32MiB */

              if (chip->chipsize > (32 << 20))

                     chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);

如果NAND的容量超过了32M才会有第三个页地址.

…………………….

chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);

 

       /*

        * program and erase have their own busy handlers

        * status and sequential in needs no delay

        */

       switch (command) {

 

       case NAND_CMD_PAGEPROG:

       case NAND_CMD_ERASE1:

       case NAND_CMD_ERASE2:

       case NAND_CMD_SEQIN:

       case NAND_CMD_STATUS:

              return;

 

       case NAND_CMD_RESET:

              if (chip->dev_ready)

                     break;

              udelay(chip->chip_delay);

              chip->cmd_ctrl(mtd, NAND_CMD_STATUS,

                            NAND_CTRL_CLE | NAND_CTRL_CHANGE);

              chip->cmd_ctrl(mtd,

                            NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);

              while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;

              return;

 

              /* This applies to read commands */

       default:

              /*

               * If we don't have access to the busy pin, we apply the given

               * command delay

               */

              if (!chip->dev_ready) {

                     udelay(chip->chip_delay);

                     return;

              }

       }

       /* Apply this short delay always to ensure that we do wait tWB in

        * any case on any machine. */

       ndelay(100);

 

       nand_wait_ready(mtd);

}

.结合NAND的命令图这一段看懂应该没有问题

chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);这个命令来说:

ECH就是厂商ID,Device Code就设备ID.这是三星的NAND

nand_command就这样完了.完了.

还有一个就是: chip->cmd_ctrl

对于S3C2440来说就是:

static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd,

                               unsigned int ctrl)

{

       struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);

 

       if (cmd == NAND_CMD_NONE)

              return;

 

       if (ctrl & NAND_CLE)

              writeb(cmd, info->regs + S3C2440_NFCMD);

       else

              writeb(cmd, info->regs + S3C2440_NFADDR);

}

NFCMD就是命令寄存器.NFADDR就是地址寄存器.

#define NAND_CLE             0x02

/* Select the address latch by setting ALE to high */

#define NAND_ALE             0x04

 

#define NAND_CTRL_CLE          (NAND_NCE | NAND_CLE)

#define NAND_CTRL_ALE          (NAND_NCE | NAND_ALE)

 

NAND_CTRL_CLE       就是NAND_CLE | NAND_NCE

返回了.真的完了.回来再看 nand_get_flash_type 

 

阅读(1863) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~