s3c2440 nand flash 的操作

发布者:梦中的额吉最新更新时间:2016-04-20 来源: eefocus关键字:nand  flash  s3c2440 手机看文章 扫描二维码
随时随地手机看文章
@******************************************************************************

@ File:head.s
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@******************************************************************************      
 
.text
.global _start
_start:
                                            @函数disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定义
            ldr     sp, =4096               @设置堆栈
            bl      disable_watch_dog       @关WATCH DOG
            bl      memsetup                @初始化SDRAM
            bl      nand_init               @初始化NAND Flash

                                            @将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中
                                            @nand_read_ll函数需要3个参数:
            ldr     r0,     =0x30000000     @1. 目标地址=0x30000000,这是SDRAM的起始地址
            mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处
            mov     r2,     #1024           @3.  复制长度= 1024(bytes),对于本实验的main.c,这是足够了
            bl      nand_read               @调用C函数nand_read

            ldr     sp, =0x34000000         @设置栈
            ldr     lr, =halt_loop          @设置返回地址
            ldr     pc, =main               @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
halt_loop:
                 halt_loop

 

 

 

 

 


#define  WTCON    (*(volatile unsigned long *)0x53000000)


#define  MEM_CTL_BASE  0x48000000
 
void disable_watch_dog();
void memsetup();


void disable_watch_dog()
{
 WTCON = 0;
}


void memsetup()
{
 int  i = 0;
 unsigned long *p = (unsigned long *)MEM_CTL_BASE;

   
    unsigned long  const    mem_cfg_val[]={ 0x22011110,     //BWSCON
                                            0x00000700,     //BANKCON0
                                            0x00000700,     //BANKCON1
                                            0x00000700,     //BANKCON2
                                            0x00000700,     //BANKCON3 
                                            0x00000700,     //BANKCON4
                                            0x00000700,     //BANKCON5
                                            0x00018005,     //BANKCON6
                                            0x00018005,     //BANKCON7
                                            0x008C07A3,     //REFRESH
                                            0x000000B1,     //BANKSIZE
                                            0x00000030,     //MRSRB6
                                            0x00000030,     //MRSRB7
                                    };

 for(; i < 13; i++)
  p[i] = mem_cfg_val[i];
}

nand.c

#define GSTATUS1        (*(volatile unsigned int *)0x560000B0)
#define BUSY            1

typedef unsigned int S3C24X0_REG32;



typedef struct {
    S3C24X0_REG32   NFCONF;
    S3C24X0_REG32   NFCMD;
    S3C24X0_REG32   NFADDR;
    S3C24X0_REG32   NFDATA;
    S3C24X0_REG32   NFSTAT;
    S3C24X0_REG32   NFECC;
} S3C2410_NAND;


typedef struct {
    S3C24X0_REG32   NFCONF;
    S3C24X0_REG32   NFCONT;
    S3C24X0_REG32   NFCMD;
    S3C24X0_REG32   NFADDR;
    S3C24X0_REG32   NFDATA;
    S3C24X0_REG32   NFMECCD0;
    S3C24X0_REG32   NFMECCD1;
    S3C24X0_REG32   NFSECCD;
    S3C24X0_REG32   NFSTAT;
    S3C24X0_REG32   NFESTAT0;
    S3C24X0_REG32   NFESTAT1;
    S3C24X0_REG32   NFMECC0;
    S3C24X0_REG32   NFMECC1;
    S3C24X0_REG32   NFSECC;
    S3C24X0_REG32   NFSBLK;
    S3C24X0_REG32   NFEBLK;
} S3C2440_NAND;


typedef struct {
    void (*nand_reset)(void);
    void (*wait_idle)(void);
    void (*nand_select_chip)(void);
    void (*nand_deselect_chip)(void);
    void (*write_cmd)(int cmd);
    void (*write_addr)(unsigned int addr);
    unsigned char (*read_data)(void);
}t_nand_chip;

static S3C2410_NAND * s3c2410nand = (S3C2410_NAND *)0x4e000000;
static S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;

static t_nand_chip nand_chip;


void nand_init(void);
void nand_read(unsigned char *buf, unsigned long start_addr, int size);


static void nand_reset(void);
static void wait_idle(void);
static void nand_select_chip(void);
static void nand_deselect_chip(void);
static void write_cmd(int cmd);
static void write_addr(unsigned int addr);
static unsigned char read_data(void);


static void s3c2410_nand_reset(void);
static void s3c2410_wait_idle(void);
static void s3c2410_nand_select_chip(void);
static void s3c2410_nand_deselect_chip(void);
static void s3c2410_write_cmd(int cmd);
static void s3c2410_write_addr(unsigned int addr);
static unsigned char s3c2410_read_data();


static void s3c2440_nand_reset(void);
static void s3c2440_wait_idle(void);
static void s3c2440_nand_select_chip(void);
static void s3c2440_nand_deselect_chip(void);
static void s3c2440_write_cmd(int cmd);
static void s3c2440_write_addr(unsigned int addr);
static unsigned char s3c2440_read_data(void);

 


static void s3c2410_nand_reset(void)
{
    s3c2410_nand_select_chip();
    s3c2410_write_cmd(0xff);  // 复位命令
    s3c2410_wait_idle();
    s3c2410_nand_deselect_chip();
}


static void s3c2410_wait_idle(void)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFSTAT;
    while(!(*p & BUSY))
        for(i=0; i<10; i++);
}


static void s3c2410_nand_select_chip(void)
{
    int i;
    s3c2410nand->NFCONF &= ~(1<<11);
    for(i=0; i<10; i++);   
}


static void s3c2410_nand_deselect_chip(void)
{
    s3c2410nand->NFCONF |= (1<<11);
}


static void s3c2410_write_cmd(int cmd)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFCMD;
    *p = cmd;
}


static void s3c2410_write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFADDR;
   
    *p = addr & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 9) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 17) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 25) & 0xff;
    for(i=0; i<10; i++);
}


static unsigned char s3c2410_read_data(void)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFDATA;
    return *p;
}

 


static void s3c2440_nand_reset(void)
{
    s3c2440_nand_select_chip();
    s3c2440_write_cmd(0xff);  // 复位命令
    s3c2440_wait_idle();
    s3c2440_nand_deselect_chip();
}


static void s3c2440_wait_idle(void)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
    while(!(*p & BUSY))
        for(i=0; i<10; i++);
}


static void s3c2440_nand_select_chip(void)
{
    int i;
    s3c2440nand->NFCONT &= ~(1<<1);
    for(i=0; i<10; i++);   
}


static void s3c2440_nand_deselect_chip(void)
{
    s3c2440nand->NFCONT |= (1<<1);
}


static void s3c2440_write_cmd(int cmd)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
    *p = cmd;
}


static void s3c2440_write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
   
    *p = addr & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 9) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 17) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 25) & 0xff;
    for(i=0; i<10; i++);
}


static unsigned char s3c2440_read_data(void)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
    return *p;
}



static void nand_reset(void)
{
    nand_chip.nand_reset();
}

static void wait_idle(void)
{
    nand_chip.wait_idle();
}

static void nand_select_chip(void)
{
    int i;
    nand_chip.nand_select_chip();
    for(i=0; i<10; i++);
}

static void nand_deselect_chip(void)
{
    nand_chip.nand_deselect_chip();
}

static void write_cmd(int cmd)
{
    nand_chip.write_cmd(cmd);
}
static void write_addr(unsigned int addr)
{
    nand_chip.write_addr(addr);
}

static unsigned char read_data(void)
{
    return nand_chip.read_data();
}



void nand_init(void)
{
#define TACLS   0
#define TWRPH0  3
#define TWRPH1  0

   
    if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
    {
        nand_chip.nand_reset         = s3c2410_nand_reset;
        nand_chip.wait_idle          = s3c2410_wait_idle;
        nand_chip.nand_select_chip   = s3c2410_nand_select_chip;
        nand_chip.nand_deselect_chip = s3c2410_nand_deselect_chip;
        nand_chip.write_cmd          = s3c2410_write_cmd;
        nand_chip.write_addr         = s3c2410_write_addr;
        nand_chip.read_data          = s3c2410_read_data;

  
        s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
    }
    else
    {
        nand_chip.nand_reset         = s3c2440_nand_reset;
        nand_chip.wait_idle          = s3c2440_wait_idle;
        nand_chip.nand_select_chip   = s3c2440_nand_select_chip;
        nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip;
        nand_chip.write_cmd          = s3c2440_write_cmd;
        nand_chip.write_addr         = s3c2440_write_addr;
        nand_chip.read_data          = s3c2440_read_data;

  
        s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
       
        s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);
    }
   
   
    nand_reset();
}


#define NAND_SECTOR_SIZE    512
#define NAND_BLOCK_MASK     (NAND_SECTOR_SIZE - 1)


void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
    int i, j;
   
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
        return ;   
    }

   
    nand_select_chip();

    for(i=start_addr; i < (start_addr + size);) {
     
      write_cmd(0);

     
      write_addr(i);
      wait_idle();

      for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
          *buf = read_data();
          buf++;
      }
    }

   
    nand_deselect_chip();
   
    return ;
}

 

 

main 函数
#define GPBCON  (*(volatile unsigned long *)0x56000010)
#define GPBDAT  (*(volatile unsigned long *)0x56000014)

#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))

void  wait(unsigned long dly)
{
 for(; dly > 0; dly--);
}

int main(void)
{
 unsigned long i = 0;
 
 GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;  // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出

 while(1){
  wait(30000);
  GPBDAT = (~(i<<5));   // 根据i的值,点亮LED1-4
  if(++i == 16)
   i = 0;
 }

 return 0;
}

 

关键字:nand  flash  s3c2440 引用地址:s3c2440 nand flash 的操作

上一篇:s3c24xx中断的操作
下一篇:存储器的操作

推荐阅读最新更新时间:2024-03-16 14:51

大容量串行e-Flash的FPGA配置方案
引 言 现场可编程门阵列FPGA(Field Programmable Gate Array)是一种集通用性强、设计灵活、集成度高和编程方便等诸多优点于一身的现场可编程ASIC。自1985年美国的Xilinx公司推出FPGA产品并取得成功以后,FPGA发展迅猛,门数不断提升,达到数百万门的规模;产品种类日益丰富,性能不断完善,在军事、通信、医疗、消费类电子等各领域发挥了巨大的作用。 Xilinx公司的FPGA具有很高的性价比,其集成开发环境ISE和Webpack效率高、界面友好,因此在业界有着广泛的应用。通常对Xilinx公司的FPGA配置采用专用的配置芯片,速度较快,其价格也正逐步降低。笔者为配合某电力测量仪表的开发,对X
[半导体设计/制造]
变电所遥视监控系统研究
  1 引言   随着我国电网调度管理水平的不断提高, 许多地区电力通信网的建设取得了很大的进展,基本上实现了数字化通信。采用光纤、数字微波或无线扩频等通信方式,信道带宽和信道质量明显提高。而要全面直观地了解变电站的真实情况,远程视觉监控是必备的监控管理手段,它可在几十公里及更远之外的调度中心及时准确地掌握变电站的情况, 并对各种情况进行操作控制,做到真正的无人值守。   2 无人值班变电所运行现状   近年来, 随着电网规模的迅速扩大, 电力系统科技水平不断提高, 无人值守变电所的数量日益增加, 尤其随着变电所自动化程度的不断提高,非电气因素造成的事故比例越来越高。如何降低或避免这类事故的发生,已是实现无人值班变电所要解决
[单片机]
变电所遥视监控系统研究
S3C2440 测试程序(一)PWM控制蜂鸣器测试
while(1) { U8 idx; Uart_Printf( \nPlease select function : \n ); for(i=0; CmdTip .fun!=0; i++) Uart_Printf( %d : %s\n , i, CmdTip .tip); idx = Uart_GetIntNum_GJ() ; if(idx i) { (*CmdTip .fun)(); Delay(20); Uart_Init( 0,115200 ); } } struct {
[单片机]
STM32读写内部Flash
工作中使用STM32F407ZGT6这块芯片开发项目,内部Flash有1M之多,出于数据存储需要,而外部没有拓展EEPROM,就想着将数据存入Flash中。因此研究了一下STM32F4读写内部Flash的一些操作。 以下是关于Flash介绍,部分来自互联网: 【STM32F4 内部Flash的一些信息】 STM32F407ZGTx的内部Flash的地址是:0x08000000,大小是0x00100000。 写Flash的时候,如果发现写入地址的Flash没有被擦出,数据将不会写入。Flash的擦除操作,只能按Sector进行。不能单独擦除一个地址上的数据。因此在写数据之前需要将地址所在Sector的所有数据擦除。
[单片机]
STM32读写内部<font color='red'>Flash</font>
苹果向中国消费者道歉:手机产品售后服务升级NAND
    昨晚,苹果公司CEO蒂姆·库克(TimCook)通过官网发布公开信,向中国消费者表示歉意,同时宣布升级部分产品的售后维修服务,并对整个售后服务政策进行改进。这是央视3·15晚会曝光苹果售后存在“中外有别”之后,苹果公司首度公开道歉并出台实质性的改进措施。   媒体集中炮轰半月   3月15日,央视在“3·15晚会”上曝光了苹果公司在华售后服务存在“中外双重标准”的问题。随后,央视继续在《新闻联播》《焦点访谈》等节目中质疑苹果公司在华售后服务问题。根据央视的报道,苹果在华售后服务问题包括:“整机交换”维修方式名不副实,更换iPhone时并不更换后盖;更换维修产品后,保修期并不顺延,违反《移动电话商品修理退还责任规定》;多款产品
[手机便携]
linux 2.6.32 在arm9(s3c2440)平台的移植 - LCD背光驱动
LCD背光是通过 CPU的 LCD_PWR引脚来控制的, 当LCD_PWR输出1, 亮 , 输出0则灭. 以下的代码均参考mini2440的移植手册 (1)新建/drivers/video/mini2440_backlight.c #include linux/errno.h #include linux/kernel.h #include linux/module.h #include linux/slab.h #include linux/input.h #include linux/init.h #include linux/serio.h #include linux/delay.h #include
[单片机]
SAM4E单片机之旅——16、NAND Flash读写
这次大概介绍了一下NAND Flash,以及在ASF中使用它的方法。 一、 接线 这个开发板搭载了一个256 MB,8位的NAND Flash(MT29F2G08ABAEA)。引脚接线如下: 偷个懒,直接上引脚复用的图。其中PC14表明该NAND FLASH需要作为SMC的外设0使用。通过使用NANDOE和NANDWE引脚说明需要使用芯片的NAND Flash控制逻辑。另外,PC18复用为输入引脚,用以查询芯片的状态。 二、 NAND Flash 组织结构与寻址 NAND Flash的容量较大。整片Flash分为若干个块(Block),每个Block分为若干个页(Page)。在每个页中,除了数据区域,也包含若干
[单片机]
SAM4E单片机之旅——16、<font color='red'>NAND</font> <font color='red'>Flash</font>读写
S3C2440裸机------从零实现用于裸机调试的printf函数
我们的C语言中有标准的printf,可以很方便的打印一些变量的值用于调试,在嵌入式开发中,我们通过串口实现我们自己的printf函数,将一些变量值通过串口打印出来。 1.printf函数介绍 首先看一下C语言中的printf函数中的格式字符,我们就是要实现下表中的几个格式字符。 然后看一下printf函数的声明,int printf(const char * format, ...); format: 表示固定参数, ...: 表示可变参数 2.手动确定可变参数 要实现printf函数,首先我们要知道怎么取到format和...所接受到的参数,我们取参数的依据就是:x86平台,函数调用时参数传递是使用堆栈来实
[单片机]
<font color='red'>S3C2440</font>裸机------从零实现用于裸机调试的printf函数
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved