亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

實驗四--nand flash的使用

2024-06-28 13:23:19
字體:
來源:轉載
供稿:網友
實驗四--nand Flash的使用

一。環境和編譯器

  開發板:jz2440

系統:Ubuntu12.04

編譯器:gcc

二。驗證代碼

1.head.S

 1 @****************************************************************************** 2 @ File:head.s 3 @ 功能:設置SDRAM,將程序復制到SDRAM,然后跳到SDRAM繼續執行 4 @auther: 5 @******************************************************************************        6    7 .text 8 .global _start 9 _start:10             @函數disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定義11             ldr     sp, =4096               @設置堆棧 12             bl      disable_watch_dog       @關WATCH DOG13             bl      memsetup                @初始化SDRAM14             bl      nand_init               @初始化NAND Flash15 16             @將NAND Flash中地址4096開始的1024字節代碼(main.c編譯得到)復制到SDRAM中17                                             @nand_read_ll函數需要3個參數:18             ldr     r0,     =0x30000000     @1. 目標地址=0x30000000,這是SDRAM的起始地址19             mov     r1,     #4096           @2.  源地址   = 4096處20             mov     r2,     #2048           @3.  復制長度= 2048(bytes)21             bl      nand_read               @調用C函數nand_read22 23             ldr     sp, =0x34000000         @設置棧24             ldr     lr, =halt_loop          @設置返回地址25             ldr     pc, =main               @b指令和bl指令只跳轉32M的范圍,所以這里使用向pc賦值的方法進行跳轉26 halt_loop:27             b       halt_loop

2.init.c

 1 #define     WTCON    (*(volatile unsigned long *)0x53000000) 2 #define     MEM_CTL_BASE        0x48000000 3   4 void disable_watch_dog(); 5 void memsetup(); 6  7 /*關掉看門狗 */ 8 void disable_watch_dog() 9 {10     WTCON    = 0;11 }12 13 /* 設置SDRAM */14 void memsetup()15 {16     int     i = 0;17     unsigned long *p = (unsigned long *)MEM_CTL_BASE;18 19     /* SDRAM 13個寄存器的值 */20     unsigned long  const    mem_cfg_val[]={ 0x22011110,     //BWSCON21                                             0x00000700,     //BANKCON022                                             0x00000700,     //BANKCON123                                             0x00000700,     //BANKCON224                                             0x00000700,     //BANKCON3  25                                             0x00000700,     //BANKCON426                                             0x00000700,     //BANKCON527                                             0x00018005,     //BANKCON628                                             0x00018005,     //BANKCON729                                             0x008C07A3,     //REFRESH30                                             0x000000B1,     //BANKSIZE31                                             0x00000030,     //MRSRB632                                             0x00000030,     //MRSRB733                                     };34 35     for(; i < 13; i++)36         p[i] = mem_cfg_val[i];37 }

3.nand.c 以下代碼不支持2410 也不支持小頁讀寫,是裁剪源碼的結果。

  1 #define GSTATUS1        (*(volatile unsigned int *)0x560000B0)  2 #define BUSY            1  3   4 #define NAND_SECTOR_SIZE_LP    2048  5 #define NAND_BLOCK_MASK_LP     (NAND_SECTOR_SIZE_LP - 1)  6   7 typedef unsigned int S3C24X0_REG32;  8   9  10 typedef struct { 11     S3C24X0_REG32   NFCONF; 12     S3C24X0_REG32   NFCONT; 13     S3C24X0_REG32   NFCMD; 14     S3C24X0_REG32   NFADDR; 15     S3C24X0_REG32   NFDATA; 16     S3C24X0_REG32   NFMECCD0; 17     S3C24X0_REG32   NFMECCD1; 18     S3C24X0_REG32   NFSECCD; 19     S3C24X0_REG32   NFSTAT; 20     S3C24X0_REG32   NFESTAT0; 21     S3C24X0_REG32   NFESTAT1; 22     S3C24X0_REG32   NFMECC0; 23     S3C24X0_REG32   NFMECC1; 24     S3C24X0_REG32   NFSECC; 25     S3C24X0_REG32   NFSBLK; 26     S3C24X0_REG32   NFEBLK; 27 } S3C2440_NAND; 28  29 static S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000; 30  31  32  33 /* 供外部調用的函數 */ 34 void nand_init(void); 35 void nand_read(unsigned char *buf, unsigned long start_addr, int size); 36  37  38 /* S3C2440的NAND Flash處理函數 */ 39 static void s3c2440_nand_reset(void); 40 static void s3c2440_wait_idle(void); 41 static void s3c2440_nand_select_chip(void); 42 static void s3c2440_nand_deselect_chip(void); 43 static void s3c2440_write_cmd(int cmd); 44 static void s3c2440_write_addr_lp(unsigned int addr); 45 static unsigned char s3c2440_read_data(void); 46  47  48  49 /* 復位 */ 50 static void s3c2440_nand_reset(void) 51 { 52     s3c2440_nand_select_chip(); 53     s3c2440_write_cmd(0xff);  // 復位命令 54     s3c2440_wait_idle(); 55     s3c2440_nand_deselect_chip(); 56 } 57  58 /* 等待NAND Flash就緒 */ 59 static void s3c2440_wait_idle(void) 60 { 61     int i; 62     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT; 63     while(!(*p & BUSY)) 64         for(i=0; i<10; i++); 65 } 66  67 /* 發出片選信號 */ 68 static void s3c2440_nand_select_chip(void) 69 { 70     int i; 71     s3c2440nand->NFCONT &= ~(1<<1); 72     for(i=0; i<10; i++);     73 } 74  75 /* 取消片選信號 */ 76 static void s3c2440_nand_deselect_chip(void) 77 { 78     s3c2440nand->NFCONT |= (1<<1); 79 } 80  81 /* 發出命令 */ 82 static void s3c2440_write_cmd(int cmd) 83 { 84     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD; 85     *p = cmd; 86 } 87  88  89  90  91 static void s3c2440_write_addr_lp(unsigned int addr) 92 { 93     int i; 94     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR; 95     int col, page; 96  97     col = addr & NAND_BLOCK_MASK_LP; 98     page = addr / NAND_SECTOR_SIZE_LP; 99     100     *p = col & 0xff;            /* Column Address A0~A7 */101     for(i=0; i<10; i++);        102     *p = (col >> 8) & 0x0f;     /* Column Address A8~A11 */103     for(i=0; i<10; i++);104     *p = page & 0xff;            /* Row Address A12~A19 */105     for(i=0; i<10; i++);106     *p = (page >> 8) & 0xff;    /* Row Address A20~A27 */107     for(i=0; i<10; i++);108     *p = (page >> 16) & 0x03;    /* Row Address A28~A29 */109     for(i=0; i<10; i++);110 }111 112 113 /* 讀取數據 */114 static unsigned char s3c2440_read_data(void)115 {116     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;117     return *p;118 }119 120 121 /* 初始化NAND Flash */122 void nand_init(void)123 {124 #define TACLS   0125 #define TWRPH0  3126 #define TWRPH1  0127 128 129         /* 設置時序 */130         s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);131         /* 使能NAND Flash控制器, 初始化ECC, 禁止片選 */132         s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);133    134     135     /* 復位NAND Flash */136     s3c2440_nand_reset();137 }138 139 140 /* 讀函數 */141 void nand_read(unsigned char *buf, unsigned long start_addr, int size)142 {143     int i, j;144 145 146     if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP)) {147         return ;    /* 地址或長度不對齊 */148     }   //NAND_BLOCK_MASK_LP=2047  111_1111_1111 SIZE與之相與,若等于0,說明SIZE低11都是0,那么地址對齊;否則不對齊149     150 151     /* 選中芯片 */152     s3c2440_nand_select_chip();153 154     for(i=start_addr; i < (start_addr + size);) {155       /* 發出READ0命令 */156       s3c2440_write_cmd(0);157 158       /* Write Address */159       s3c2440_write_addr_lp(i);160 161       s3c2440_write_cmd(0x30);        162 163       s3c2440_wait_idle();164 165 166       for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) {167 168           *buf = s3c2440_read_data();169           buf++;170       }  //i的值等于0,512,1024,1536這四個值,也就可以讀寫0到2047這2k之內連續的地址的值171     }172 173     /* 取消片選信號 */174     s3c2440_nand_deselect_chip();175     176     return ;177 }

4.led.c

就是led閃爍之類的,免了。

5.Makefile

  

 1 objs := head.o init.o nand.o led.o 2  3 nand.bin : $(objs) 4     arm-linux-ld -Tnand.lds    -o nand_elf $^ 5     arm-linux-objcopy -O binary -S nand_elf $@ 6     arm-linux-objdump -D -m arm  nand_elf > nand.dis 7  8 %.o:%.c 9     arm-linux-gcc -Wall -c -O2 -o $@ $<10 11 %.o:%.S12     arm-linux-gcc -Wall -c -O2 -o $@ $<13 14 clean:15     rm -f  nand.dis nand.bin nand_elf  *.o

以上makefile與之前不同,下面是編譯細節,請用心比較

6.鏈接腳本

1 SECTIONS { 2   firtst      0x00000000 : { head.o init.o nand.o}3   second     0x30000000 : AT(4096) { led.o }4 } 5  

三。實驗結果

  經驗證,可實現。

  本代碼參考韋東山先生的源碼,作來相應的裁剪。

  源碼上支持2410和2440,以及大頁,小頁的讀寫,這里都分別作了裁剪到只支持2440和大頁讀。

  nand flash理論性的東西改天附上。

四。根據

  我們這里選用芯片的存儲結構,這里選用大頁讀寫,單位是2k,小頁是512字節。其中64BYTES是OBB,這里沒有用到。

  而大頁的寫地址定義如下:

  

  需要連續5次,正如代碼中:

  

 1 static void s3c2440_write_addr_lp(unsigned int addr) 2 { 3     int i; 4     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR; 5     int col, page; 6  7     col = addr & NAND_BLOCK_MASK_LP; 8     page = addr / NAND_SECTOR_SIZE_LP; 9     10     *p = col & 0xff;            /* Column Address A0~A7 */11     for(i=0; i<10; i++);        12     *p = (col >> 8) & 0x0f;     /* Column Address A8~A11 */13     for(i=0; i<10; i++);14     *p = page & 0xff;            /* Row Address A12~A19 */15     for(i=0; i<10; i++);16     *p = (page >> 8) & 0xff;    /* Row Address A20~A27 */17     for(i=0; i<10; i++);18     *p = (page >> 16) & 0x03;    /* Row Address A28~A29 */19     for(i=0; i<10; i++);20 }

明顯區別與小頁的,可以參看原理圖中小頁的寫地址定義。

此外,讀寫命令如下:

  復位命令是ff,代碼是

1 /* 復位 */2 static void s3c2440_nand_reset(void)3 {4     s3c2440_nand_select_chip();5     s3c2440_write_cmd(0xff);  // 復位命令6     s3c2440_wait_idle();7     s3c2440_nand_deselect_chip();8 }

而2440中相關控制寄存器如下截圖:

使能信號是NFCONT的最低位 置1 ;

片選是NFCONT【1】位 寫0;

NFCONT[4]是ECC功能用的。

片選代碼:

 1 /* 發出片選信號 */ 2 static void s3c2440_nand_select_chip(void) 3 { 4     int i; 5     s3c2440nand->NFCONT &= ~(1<<1); 6     for(i=0; i<10; i++);     7 } 8  9 /* 取消片選信號 */10 static void s3c2440_nand_deselect_chip(void)11 {12     s3c2440nand->NFCONT |= (1<<1);13 }

此外等待信號由NFSTAT決定:

代碼是:

1 /* 等待NAND Flash就緒 */2 static void s3c2440_wait_idle(void)3 {4     int i;5     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;6     while(!(*p & BUSY))7         for(i=0; i<10; i++);8 }

發出命令即直接向NFCMD寫地址就好:

1 /* 發出命令 */2 static void s3c2440_write_cmd(int cmd)3 {4     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;5     *p = cmd;6 }

讀數據:

1 /* 讀取數據 */2 static unsigned char s3c2440_read_data(void)3 {4     volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;5     return *p;6 }

連續讀寫一頁的數據:

 1 /* 讀函數 */ 2 void nand_read(unsigned char *buf, unsigned long start_addr, int size) 3 { 4     int i, j; 5  6  7     if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP)) { 8         return ;    /* 地址或長度不對齊 */ 9     }10     11 12     /* 選中芯片 */13     s3c2440_nand_select_chip();14 15     for(i=start_addr; i < (start_addr + size);) {16       /* 發出READ0命令 */17       s3c2440_write_cmd(0);18 19       /* Write Address */20       s3c2440_write_addr_lp(i);21 22       s3c2440_write_cmd(0x30);        23 24       s3c2440_wait_idle();25 26 27       for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) {28 29           *buf = s3c2440_read_data();30           buf++;31       }32     }33 34     /* 取消片選信號 */35     s3c2440_nand_deselect_chip();36     37     return ;38 }

首先判斷地址對齊,如不對齊,讀數據取消,因為結果是未知的。 上面解釋就是SIZE與上2047(111_1111_1111),若SIZE的低11位都是0,那么相與后,結果是0,則說明地址對齊;否則不對齊。

i的值是0、2048這個值,可以在0到2047這2k區間連續讀。

/* 發出READ0命令 */

s3c2440_write_cmd(0); /* Write Address */ s3c2440_write_addr_lp(i); s3c2440_write_cmd(0x30);  s3c2440_wait_idle();

先發出命令00,表示從開始讀,也就是順序讀寫。

然后寫如地址。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲第一网站男人都懂| 亚洲xxxx18| 亚洲二区在线播放视频| 成人午夜在线视频一区| 孩xxxx性bbbb欧美| 国内精品久久久久久| 97久久久久久| 一本大道香蕉久在线播放29| 97视频在线播放| 久久的精品视频| 亚洲美女又黄又爽在线观看| 久久久久久久91| 亚洲欧美激情另类校园| 91精品久久久久久久久久| 国产精品中文久久久久久久| 日韩视频免费在线观看| 亚洲伊人一本大道中文字幕| 欧美一级淫片丝袜脚交| 国产日产欧美a一级在线| 国产一区二区黑人欧美xxxx| 国产精品极品美女在线观看免费| 97热在线精品视频在线观看| 欧美成人免费全部| 久久久在线免费观看| 久久躁狠狠躁夜夜爽| 91在线中文字幕| 尤物九九久久国产精品的特点| 亚洲精品国精品久久99热| 久热精品在线视频| 久久99青青精品免费观看| 国产精品久久久亚洲| 日韩高清欧美高清| 中文字幕亚洲图片| 久久91精品国产91久久久| 欧美性猛交xxxx富婆弯腰| 亚洲精品videossex少妇| 国自在线精品视频| 欧美在线一区二区三区四| 亚洲跨种族黑人xxx| 国内揄拍国内精品少妇国语| 亚洲精品国产精品自产a区红杏吧| 欧美乱大交做爰xxxⅹ性3| 亚洲片国产一区一级在线观看| 欧美中文在线观看| 国产日韩欧美91| 国产亚洲精品一区二区| 国产精品私拍pans大尺度在线| 97成人在线视频| 中文字幕亚洲二区| 欧美精品一本久久男人的天堂| 久久99精品久久久久久琪琪| 国产精品高潮呻吟久久av野狼| 中文字幕亚洲欧美一区二区三区| 国产精品中文久久久久久久| 国产亚洲一区精品| 欧美成人精品激情在线观看| 一区二区中文字幕| 国产欧美日韩视频| 在线精品视频视频中文字幕| 自拍亚洲一区欧美另类| 91av福利视频| 久久久久久91香蕉国产| 欧美激情在线视频二区| 51视频国产精品一区二区| 欧美精品福利视频| 久久久久久网址| 成人免费xxxxx在线观看| 国产视频欧美视频| 在线日韩精品视频| 亚洲成人黄色在线观看| 成人免费大片黄在线播放| 亚洲精品大尺度| 欧美精品video| 国产在线播放91| 91精品国产成人www| 国产日产欧美精品| 欧美日韩国产综合视频在线观看中文| 欧美亚洲在线观看| 日韩电影中文字幕| 成人国产精品免费视频| 亚洲欧美www| 久久在精品线影院精品国产| 久热99视频在线观看| 中文字幕一区二区精品| 97成人超碰免| 欧洲亚洲妇女av| 亚洲毛片在线观看.| 另类少妇人与禽zozz0性伦| 欧美老女人www| 一道本无吗dⅴd在线播放一区| 亚洲欧美国产精品专区久久| 国产视频精品久久久| 美女久久久久久久久久久| 亚洲美女自拍视频| 2019中文字幕在线观看| 亚洲欧洲日本专区| 深夜福利一区二区| 欧美国产中文字幕| 日韩精品极品在线观看播放免费视频| 亚洲欧美变态国产另类| 久久久国产一区二区三区| 国产精品91久久久久久| 免费97视频在线精品国自产拍| 欧美巨乳美女视频| 国产精品久久97| 成人免费网站在线观看| 一夜七次郎国产精品亚洲| 国产美女精品视频| 不卡av电影院| 91老司机在线| 亚洲最大中文字幕| 久久天天躁狠狠躁夜夜躁2014| 成人激情综合网| 精品成人乱色一区二区| 日韩av日韩在线观看| 国内精品400部情侣激情| 精品国产老师黑色丝袜高跟鞋| 一个人看的www久久| 97在线视频免费| 亚洲性69xxxbbb| 91九色国产视频| 久久久亚洲欧洲日产国码aⅴ| 国产精品一区二区三区毛片淫片| 91亚洲精品久久久久久久久久久久| 国产自摸综合网| 久久久久久久久久婷婷| 一本色道久久88综合日韩精品| 欧美成人精品一区| 青青a在线精品免费观看| 97色在线视频观看| 成人黄色免费在线观看| 亚洲free性xxxx护士hd| 亚洲综合精品伊人久久| 欧美激情一区二区三区高清视频| 欧美大尺度电影在线观看| 亚洲精品小视频在线观看| 日本中文字幕久久看| 午夜精品久久久久久久99热浪潮| 欧美成人在线影院| 国产极品精品在线观看| 日韩久久精品成人| 日韩电影大片中文字幕| 亚洲成人激情在线观看| 91九色单男在线观看| 91tv亚洲精品香蕉国产一区7ujn| 成人久久18免费网站图片| 久久精品国产视频| 亚洲一区二区三区乱码aⅴ| 免费99精品国产自在在线| 欧美又大又硬又粗bbbbb| 久久久久久久国产精品视频| 国产精品丝袜久久久久久不卡| 日韩成人网免费视频| 黑人巨大精品欧美一区二区| 国语自产精品视频在免费| 欧美一级淫片aaaaaaa视频| 26uuu日韩精品一区二区| 国产亚洲精品美女久久久| 久久久在线观看| 91精品视频免费观看| 91黑丝高跟在线| 国产亚洲精品久久久| 九色精品免费永久在线| 韩国19禁主播vip福利视频|