首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

如何编写Linux下Nand Flash驱动 - 06

如何编写Linux下Nand Flash驱动 - 06

对于上述中步骤㈠的函数cmdfunc,一般来说可以不用自己的驱动中实现,而直接使用MTD层提供的已有的函数,nand_command_lp,其细节如下:
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
……
/ * Command latch cycle */
/* 此处就是就是发送读命令的第一个周期1st Cycle的命令,即0x00,对应着上述步骤中的① */
chip- >cmd_ctrl(mtd, command & 0xff, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
if (column ! = - 1 | | page_addr ! = - 1) {
int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
/ * Serially input address */
if (column ! = - 1) {
/ * Adjust columns for 16 bit buswidth */
if (chip- >options & NAND_BUSWIDTH_16)
column 》= 1;
/* 接下来是发送两个column,列地址,对应着上述步骤中的② */
chip- >cmd_ctrl(mtd, column, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
chip- >cmd_ctrl(mtd, column 》 8, ctrl);
}
if (page_addr ! = - 1) {
/* 然后发送三个row行地址,对应着上述步骤中的③ */
chip- >cmd_ctrl(mtd, page_addr, ctrl);
chip- >cmd_ctrl(mtd, page_addr 》 8, NAND_NCE | NAND_ALE);
/ * One more address cycle for devices > 128MiB */
if (chip- >chipsize > (128 《 20))
chip- >cmd_ctrl(mtd, page_addr 》 16, NAND_NCE | NAND_ALE);
}
} ? end if column! =- 1| | page_addr… ?
chip- >cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
/ *
* program and erase have their own busy handlers
* status, sequential in, and deplete1 need no delay
*/
switch (command) {
……
case NAND_CMD_READ0:
/* 接下来发送读命令的第二个周期2nd Cycle的命令,即0x30,对应着上述步骤中的④ */
chip- >cmd_ctrl(mtd, NAND_CMD_READSTART,
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
chip- >cmd_ctrl(mtd, NAND_CMD_NONE,
NAND_NCE | NAND_CTRL_CHANGE);
/ * This applies to read commands */
default:
……
} ? end switch command ?
/ * Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
/* 此处是对应着④中的tWB的等待时间*/
ndelay(100);
/* 接下来就是要等待一定的时间,使得Nand Flash硬件上准备好数据,以供你之后读取,即对应着步骤⑤ */
nand_wait_ready(mtd);
} ? end nand_command_lp ?
对于之前的步骤㈡的函数read_page,一般来说也可以不用自己的驱动中实现,而直接使用MTD层提供的已有的函数,nand_read_page_hwecc,该函数所要实现的功能,正是上面余下没介绍的步骤⑥,即一点点的读出我们要的数据:
static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int page)
{
……
for (i = 0; eccsteps; eccsteps- - , i += eccbytes, p += eccsize) {
chip- >ecc.hwctl(mtd, NAND_ECC_READ);
/* 真正的数据读取,就是下面这个read_buf函数了 */
chip- >read_buf(mtd, p, eccsize);
chip- >ecc.calculate(mtd, p, &ecc_calc[i]);
}
……
} ? end nand_read_page_hwecc ?
上面的read_buf,就是真正的去读取数据的函数了,由于不同的Nand Flash controller控制器所实现的方式不同,所以这个函数必须在你的Nand Flash驱动中实现,即MTD层,能帮我们实现的都实现了,不能实现的,那肯定要你的驱动自己实现。
对于我们这里的s3c2410的例子来说,就是s3c2410_nand_read_buf:
文件位置:\drivers\mtd\nand\s3c2410.c
static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int  len)
{
struct nand_chip *this = mtd->priv;
/* 到真正的地址去读取数据 */
readsb(this->IO_ADDR_R, buf, len);
}
返回列表