tiny6410 nandflash驱动设计

按页的方式读,写驱动

1、读操作

创建文件nand.c

#define NFCONT (volatile unsigned long*)0x70200004
#define NFSTAT (volatile unsigned long*)0x70200028
#define NFCMMD (volatile unsigned long*)0x70200008
#define NFADDR (volatile unsigned long*)0x7020000C
#define NFCONF (volatile unsigned long*)0x70200000
#define NFDATA (volatile unsigned char*)0x70200010


void select_chip()
{
*(NFCONT) &= ~(1<<1);
}
void deselect_chip()
{
*(NFCONT) |= (1<<1);
}


void clear_RnB()
{
*(NFSTAT) |= (1<<4);
}
void send_cmd(unsigned cmd)
{
*(NFCMMD) = cmd;
}
void send_addr(unsigned addr)
{
*(NFADDR) = addr;
}
void wait_RnB()
{
    while(!(*(NFSTAT) & 0x1));
}
void nand_reset()
{
    /* 选中 */
    select_chip();
    
    /* 清除RnB */
    clear_RnB();
    
    /* 发出复位信号 */
    send_cmd(0xff);
    
    /* 等待就绪 */
    wait_RnB();
    
    /* 取消选中 */
    deselect_chip();
}
//初始化nandflash
void nand_init()




    /* 设置时间参数 */
#define TACLS  7
#define TWRPH0 7
#define TWRPH1 7
    
    *(NFCONF) &= ~((7<<12)|(7<<8)|(7<<4));
    *(NFCONF) |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);   //先初始化然后置1
    
    /* 使能 nandflash controller*/
    *(NFCONT) = 1 | (1<<1);
    
    
    
    /* 复位 */
    nand_reset();
}
//addr是页地址,buff是读出来的数据存放的位置
void NF_PageRead(unsigned long addr,unsigned char* buff)
{
int i;
//选中nandflash芯片
select_chip();

//清除rnb
clear_RnB();

//发送命令0x00
send_cmd(0x00);

//发送列地址(2个周期)
send_addr(0x0);
send_addr(0x0);
//发送行地址(3个周期)
send_addr(addr&0xff);
    send_addr((addr >>8 ) & (0xff));
    send_addr((addr >>16 ) & (0xff));

//发送命令0x30
send_cmd(0x30);

//等待rnb
wait_RnB();
//读取数据
for(i = 0; i<1024*2; i++)
    {
    *buff++ = *(NFDATA);
    }

//取消选中nandflash芯片
deselect_chip(); 
}
void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)
{
    int i;
  
for( i=(start_addr >>11); size>0;)
{
   NF_PageRead(i,sdram_addr);
   size -= 2048;
   sdram_addr += 2048;
   i++;
}

}



修改start.S跳转顺序修改为

reset:
bl set_svc
bl set_peri_port
bl disable_watchdog
bl disable_interrupt
bl disable_mmu
bl init_clock
bl mem_init
bl init_stack
bl nand_init
bl copy_to_ram
bl clean_bss

ldr pc, =gboot_main
@ bl light_led



然后修改

copy_to_ram:
mov r0,#0
ldr r1,=_start
ldr r2,=bss_end

sub r2,r2,r1
mov ip,lr
bl nand_to_ram

mov lr,ip


mov pc,lr


2、写操作

//擦除nandflash
int NF_Erase(unsigned long addr)
{
int ret;
//选中falsh芯片
select_chip();
//清除Rnb
clear_RnB();

//发送命令0x60
send_cmd(0x60);
//发送行地址
send_addr(addr&0xff);
    send_addr((addr >>8 ) & (0xff));
    send_addr((addr >>16 ) & (0xff));
//发送命令0xD0
send_cmd(0xD0);
//等待RnB
wait_RnB();
//发送命令0x70
send_cmd(0x70);
//读取擦除结果
ret = *(NFDATA);
//取消选中flash芯片
deselect_chip();
return ret;
}




int NF_PageWrite(unsigned long addr,unsigned char* buff)
{
int ret,i;
//选中falsh芯片
select_chip();
//清除Rnb
clear_RnB();
//发送命令0x80
send_cmd(0x80);
//发送列地址
send_addr(0x0);
send_addr(0x0);
//发送行地址
send_addr(addr&0xff);
    send_addr((addr >>8 ) & (0xff));
    send_addr((addr >>16 ) & (0xff));
//写入数据
for(i = 0; i<1024*2; i++)
    {
    *(NFDATA) = *buff++;
    }
//发送命令0x10
send_cmd(0x10);
//等到RnB
wait_RnB();
//发送命令0x70
send_cmd(0x70);
//读取写入结果
ret = *(NFDATA);
//取消选中flash芯片
deselect_chip();

return ret;
}


修改 main.c观察小灯的亮灭看写入跟读出的数据是否一致

int gboot_main()
{
unsigned char buf[1024*2];
#ifdef MMU_ON
    mmu_init();
#endif
   
    led_init();
 
  button_init();
    
    init_irq();
    
    led_off();
    
    NF_Erase(128*1+1);
buf[0] = 100;
NF_PageWrite(128*1+1,buf);
    
buf[0] = 10;
NF_PageRead(128*1+1,buf);
    
if( buf[0] == 100 )
led_on();
    
    while(1);

return 0;


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值