个人对nandflash驱动的总结(ok6410版)

           

1,首先说明要用nandflash的原因,当你从nand启动时,6410中的硬件会自动将nand中的8k内容拷贝到开发板中内存空间的iRAM中,然后iRAM再将这8k内容拷贝到内从中进行运行,一旦nand中的内容大于8k则多余的那些将无法被拷贝机运行,因此需要一个驱动程序来将多余的代码移到内存中那就是nandflash驱动程序

其次说说使用了nandflash之后的代码搬移过程;第一步,硬件会自动将nand中的8k内容拷贝到开发板中内存空间的iRAM中,然后iRAM再将这8k内容拷贝到内从中进行运行,  第二步,将nand中剩余的代码直接拷贝到内存中接着运行

3现在到了代码编写时间,其他的不多说因为已经总结完了,就说自己被卡的地方

  就在页读这里出错了结果导致整个程序有问题,之后参考了正确的代码,运行出来了

代码如下;

 #define NFCONF             (*((volatile unsigned long*)0x70200000))

#define NFCONT             (*((volatile unsigned long*)0x70200004))

#define NFCMMD             (*((volatile unsigned char*)0x70200008))

#define NFSTAT             (*((volatile unsigned char*)0x70200028))

#define NFADDR             (*((volatile unsigned char*)0x7020000c))

#define NFDATA             (*((volatile unsigned char*)0x70200010))

 

void select_ship(void)

{

    NFCONT &= ~(1<<1);

}

 

void delselect_ship(void)

{

    NFCONT |= (1<<1);

}

 

void clean_RnB()

{

    NFSTAT |= (1<<4);

void nand_cmd(unsigned char cmd)

{

    NFCMMD = cmd;   

}

 

void wait_RnB(void)

{

    while(!(NFSTAT & 0x1));

}

 

void nand_addr(unsigned char addr)

{

    NFADDR = addr;

}

 

void nand_reset(void)

{

    /* 选中 */

    select_ship();

    

    /* 清除RnB */

    clean_RnB();

    

    /* 发出复位信号 */

    nand_cmd(0xff);

    

    /* 等待就绪 */

    wait_RnB();

    

    /* 取消选中 */

    delselect_ship();

}

 

void nand_init(void)

/*

HCLK的频率为100MHZ,周期就为10ns

TACLS > 0 ns

TWRPH0 > 15ns

TWRPH1 > 5ns

 

TACLS的值 = HCLK x TACLS > 0ns

TWRPH0的值 = HCLK x (TWRPH0 + 1) > 15ns

TWRPH1的值 = HCLK x (TWRPH1 +1) > 5ns 

*/

    /* 设置时间参数 */

#define TACLS  1

#define TWRPH0 2

#define TWRPH1 1

    

    NFCONF &= ~((7<<12)|(7<<8)|(7<<4));

    NFCONF |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

    

    /* 使能 nandflash controller*/

    NFCONT = 1 | (1<<1);

    

    /* 复位 */

    nand_reset();

}

 

 

void NF_PageRead(unsigned long addr,unsigned char* buff)

{

    int i;

    

    

    /* 选中芯片 */

    select_ship();

    

    /* 清除RnB */

    clean_RnB();

    

    

    

    

    /* 发出命令0x00 */

     nand_cmd(0x00);

        

     /* 发出列地址 */

    nand_addr(0x00);

    nand_addr(0x00);

    /* 发出行地址 */

    nand_addr(addr&0xff);

    nand_addr((addr >>8 ) & (0xff));

    nand_addr((addr >>16 ) & (0xff));

        

    /* 发出命令0x30 */

     nand_cmd(0x30);

        

    /* 等待就绪 */

     wait_RnB();

        

    /* 读数据 */

     for(i = 0; i<1024*4; i++)

    {

     buff[i] = NFDATA;

    }

      

      

     

      

     /* 取消片选 */

     

     delselect_ship();

     

}

 

 

 

 

void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)

{

/* i为页号、sdram_addr为内存中的位置、size拷贝数据的大小 */

int i;

unsigned int page_shift = 12;

/* 页的起始地址给ii为页号),这个start_addr包含列地址和行地址,我们只需要页地址(行地址) */

/*for(i=(start_addr >> 12);size>0;)

{

NF_PageRead(i,sdram_addr);  //读一页的数据

     size -= 1024*4;   //ok6410页的大小是4K

     start_addr += 1024*4;

     i++;

}

*/

/* Read pages */

        for (i = 0; i < 4; i++, sdram_addr+=(1<<(page_shift-1))) 

        {

            NF_PageRead(i,sdram_addr);

        }

 

        /* Read pages */

        for (i = 4; i < (0x3c000>>page_shift); i++, sdram_addr+=(1<<page_shift))

        {

            NF_PageRead(i,sdram_addr);

        }

   

}

 

 

int NF_Erase(unsigned long addr)

{

int ret;

//选中flash芯片

select_ship();

//清除RnB

clean_RnB();

//发送命令60

nand_cmd(0x60);

//发送行地址(3个周期)

nand_addr(addr&0xff);

     nand_addr((addr >>8 ) & (0xff));

     nand_addr((addr >>16 ) & (0xff));

//发送命令D0

nand_cmd(0xD0);

//等待RnB

wait_RnB();

//发送命令70

nand_cmd(0x70);

//读取擦除结果

ret = NFDATA;

//取消选中flash芯片

delselect_ship();

return ret;

}

 

int NF_WritePage(unsigned long addr,unsigned char* buff)

{

int ret,i;

//选中flash芯片

select_ship();

//清除RnB

clean_RnB();

//发送命令80

nand_cmd(0x80);

//发送列地址(2个周期)

nand_addr(0x00);

     nand_addr(0x00);

//发送行地址(3个周期)

nand_addr(addr&0xff);

     nand_addr((addr >>8 ) & (0xff));

     nand_addr((addr >>16 ) & (0xff));

//写入数据

for(i=0;i<1024*4;i++)

{

NFDATA = buff[i];

}

//发送命令10

nand_cmd(0x10);

//等待RnB

wait_RnB();

//发送命令70

nand_cmd(0x70);

//读取写入结果

ret = NFDATA;

//取消选中flash芯片

delselect_ship();

return ret;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值