3240|9

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教2440 nand flash驱动的一些问题 [复制链接]

  1. //今天看了一下flash驱动的一些代码,发现有些不解。
  2. //平台描述2440+64M nand  flash
  3. --------------------------------------------


  4. /* 写扇区函数
  5.     @func   BOOL | FMD_WriteSector | Writes the specified data to the specified NAND flash sector/page.
  6.     @rdesc  TRUE = Success, FALSE = Failure.
  7.     @comm   
  8.     @xref   
  9. */
  10. BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
  11. {
  12.     BYTE Status;
  13.     ULONG SectorAddr = (ULONG)startSectorAddr+START_PAGE;
  14.         ULONG MECC;

  15.     if (!pSectorBuff && !pSectorInfoBuff)
  16.         return(FALSE);
  17.         
  18.     BOOL bLastMode = SetKMode(TRUE);

  19.     NF_nFCE_L();                        // Select the flash chip.
  20.     NF_WAITRB();                                    // Wait for flash to complete command.

  21.     NF_CMD(CMD_RESET);                                // Send reset command.
  22.     NF_WAITRB();                                    // Wait for flash to complete command.

  23.     while (dwNumSectors--)
  24.     {
  25.         ULONG blockPage = (((SectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (SectorAddr % NAND_PAGE_CNT));

  26.         if (!pSectorBuff)
  27.         {
  28.             // If we are asked just to write the SectorInfo, we will do that separately
  29.             NF_CMD(CMD_READ2);                                     // Send read command.
  30.                     NF_WAITRB();                                    // Wait for flash to complete command.

  31.             NF_CMD(CMD_WRITE);                                    // Send write command.
  32.             NF_ADDR(0);                                            // Column = 0.
  33.             NF_ADDR(blockPage         & 0xff);                    // Page address.
  34.             NF_ADDR((blockPage >>  8) & 0xff);
  35.                         if (NEED_EXT_ADDR)
  36.                     NF_ADDR((blockPage >> 16) & 0xff);  
  37.                     NF_WAITRB();                                    // Wait for flash to complete command.

  38.             WrPageInfo((PBYTE)pSectorInfoBuff);                 //写带外数据到spare area

  39.                 NF_CMD(CMD_WRITE2);                                    // Send write confirm command.
  40.                     NF_WAITRB();                                    // Wait for flash to complete command.

  41.                         do
  42.                         {
  43.                         NF_CMD(CMD_STATUS);
  44.                             Status = NF_RDDATA();                                    // Read command status.
  45.                     }while(!(Status & STATUS_READY));

  46.                 if (Status & STATUS_ERROR)
  47.                 {
  48.                             NF_nFCE_H();                            // Deselect the flash chip.
  49.                     SetKMode (bLastMode);
  50.                     return(FALSE);
  51.                 }
  52.             pSectorInfoBuff++;
  53.         }
  54.         else
  55.         {
  56.             NF_CMD(CMD_READ);                                     // Send read command.
  57.                     NF_WAITRB();                                    // Wait for flash to complete command.

  58.             NF_CMD(CMD_WRITE);                                    // Send write command.
  59.             NF_ADDR(0);                                            // Column = 0.
  60.             NF_ADDR(blockPage         & 0xff);                    // Page address.
  61.             NF_ADDR((blockPage >>  8) & 0xff);
  62.                         if (NEED_EXT_ADDR)
  63.                     NF_ADDR((blockPage >> 16) & 0xff);  
  64.                     NF_WAITRB();                                    // Wait for flash to complete command.

  65.             //  Special case to handle un-aligned buffer pointer.
  66.                 NF_RSTECC();
  67.                 NF_MECC_UnLock();
  68.             [color=#FF0000]if( ((DWORD) pSectorBuff) & 0x3) //这个所谓的非对齐是什么意思?[/color]
  69.             {
  70.                 [color=#FF0000]WrPage512Unalign [/color](pSectorBuff);//这个函数用汇编实现。汇编里面已经包含了循环
  71.             }
  72.             else
  73.             {
  74.                 WrPage512(pSectorBuff);                        // Write page/sector data.
  75.             }
  76.                         NF_MECC_Lock();//generate ecc
  77.                        
  78.             // Write the SectorInfo data to the media.
  79.             //
  80.             if(pSectorInfoBuff)
  81.             {
  82.                 WrPageInfo((PBYTE)pSectorInfoBuff);
  83.                 pSectorInfoBuff++;
  84.             }
  85.             else    // Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
  86.             {
  87.                 BYTE TempInfo[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  88.                 WrPageInfo(TempInfo);
  89.             }
  90.                         //read ECC ECC是如何实现的?512byte不是产生3byte吗?怎么会是4byte?
  91.                         MECC = NF_RDMECC0();
  92.                         NF_WRDATA((UCHAR)((MECC      ) & 0xff));
  93.                         NF_WRDATA((UCHAR)((MECC >>  8) & 0xff));
  94.                         NF_WRDATA((UCHAR)((MECC >> 16) & 0xff));
  95.                         NF_WRDATA((UCHAR)((MECC >> 24) & 0xff));
  96.                         //write ecc to spare area
  97.                 NF_CMD(CMD_WRITE2);                                    // Send write confirm command.
  98.                     NF_WAITRB();                                    // Wait for flash to complete command.

  99.                         do
  100.                         {
  101.                                 NF_CMD(CMD_STATUS);
  102.                             Status = NF_RDDATA();                                    // Read command status.
  103.                     }while(!(Status & STATUS_READY));

  104.                 if (Status & STATUS_ERROR)
  105.                 {
  106.                             NF_nFCE_H();                            // Deselect the flash chip.
  107.                     SetKMode (bLastMode);
  108.                     return(FALSE);
  109.                 }
  110.             pSectorBuff += NAND_PAGE_SIZE;
  111.         }
  112.         ++SectorAddr;
  113.     }
  114.     NF_nFCE_H();                                                    // Deselect the flash chip.

  115.     SetKMode (bLastMode);
  116.    
  117.     return(TRUE);
  118. }
复制代码

最新回复

明白,结贴。  详情 回复 发表于 2008-12-22 08:39
点赞 关注

回复
举报

59

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
//read ECC ECC是如何实现的?512byte不是产生3byte吗?怎么会是4byte?
            MECC = NF_RDMECC0();
            NF_WRDATA((UCHAR)((MECC      ) & 0xff));
            NF_WRDATA((UCHAR)((MECC >>  8) & 0xff));
            NF_WRDATA((UCHAR)((MECC >> 16) & 0xff));
            NF_WRDATA((UCHAR)((MECC >> 24) & 0xff));
-------------------------------------------------------------

还有
  if( ((DWORD) pSectorBuff) & 0x3) //这个所谓的非对齐是什么意思?
            {
                WrPage512Unalign (pSectorBuff);//汇编里面已经包含了循环
            }
----------------在汇编nand.s中实现了WrPage512Unalign 函数
LEAF_ENTRY    WrPage512Unalign
        stmfd    sp!,{r1 - r11}

        ldr    r1, =0xb0e00010  ;NFDATA
        mov    r2, #480

        ; Calculate number of unaligned bytes to read (r12 = 4 - (r0 & 3))
        and    r12, r0, #3
        rsb    r12, r12, #4
        mov    r3, r12
        
wr_unalign1
        ; Write unaligned bytes
        ldrb    r4, [r0]
        strb    r4, [r1]
        add    r0, r0, #1
        subs    r3, r3, #1
        bne    wr_unalign1

wr_main   
        ; Write 480 bytes (32 x 15)
        ldmia   r0!, {r4 - r11}

                str                r4, [r1]
                str                r5, [r1]
                str                r6, [r1]
                str                r7, [r1]
                str                r8, [r1]
                str                r9, [r1]
                str                r10,[r1]
                str                r11,[r1]
               
        subs    r2, r2, #32
        bne    wr_main

        ; Write 28 bytes
        ldmia   r0!, {r4 - r10}
        str r4, [r1]这个flash是八位的,怎么使用32位的str指令呢?应该是strb才对啊
                str                r5, [r1]
                str                r6, [r1]
                str                r7, [r1]
                str                r8, [r1]
                str                r9, [r1]
                str                r10,[r1]

        ; Write trailing unaligned bytes
        rsbs    r12, r12, #4
        beq    wr_exit
        
wr_unalign2
        ldrb    r4, [r0]
        strb    r4, [r1]
        add    r0, r0, #1
        subs    r12, r12, #1
        bne    wr_unalign2      

wr_exit
        ldmfd    sp!, {r1 - r11}

        IF Interworking :LOR: Thumbing
          bx  lr
        ELSE
          mov  pc, lr          ; return
        ENDIF
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
//read ECC ECC是如何实现的?512byte不是产生3byte吗?怎么会是4byte?
            MECC = NF_RDMECC0();
            NF_WRDATA((UCHAR)((MECC      ) & 0xff));
            NF_WRDATA((UCHAR)((MECC >>  8) & 0xff));
            NF_WRDATA((UCHAR)((MECC >> 16) & 0xff));
            NF_WRDATA((UCHAR)((MECC >> 24) & 0xff));
-------------------------------------------------------------
——这个是4byte的,是我受网上的文章影响了。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

4
 
2440的ECC支持2048大页,所以4byte

DATA寄存器很特殊,8位,16位和32位访问都可以,我猜测芯片是把32位访问拆成4个byte分别写4次

非对齐的时候就不能32位访问了,只好strb
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

5
 
if( ((DWORD) pSectorBuff) & 0x3) //这个所谓的非对齐是什么意思?
            {
                WrPage512Unalign (pSectorBuff);//这个函数用汇编实现。汇编里面已经包含了循环
            }
——日,在这里也要考虑地址对齐问题。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 3 楼 hhyh612 的回复:
2440的ECC支持2048大页,所以4byte

DATA寄存器很特殊,8位,16位和32位访问都可以,我猜测芯片是把32位访问拆成4个byte分别写4次

非对齐的时候就不能32位访问了,只好strb


谢谢。刚开始我都没有反映过来。也只能“我猜测芯片是把32位访问拆成4个byte分别写4次”这么解释了。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 4 楼 gooogleman 的回复:
if( ((DWORD) pSectorBuff) & 0x3) //这个所谓的非对齐是什么意思?
            {
                WrPage512Unalign (pSectorBuff);//这个函数用汇编实现。汇编里面已经包含了循环
            }
——日,在这里也要考虑地址对齐问题。


地址对齐是ARM驱动工程师最应该注意的问题。这个真的要小心谨慎。
也欢迎大家来发表意见。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

8
 
哈哈,还没想通啊。从硬件的角度去想想。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

9
 
学习了
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

10
 
明白,结贴。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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