Chinaunix首页 | 论坛 | 博客
  • 博客访问: 683045
  • 博文数量: 516
  • 博客积分: 4119
  • 博客等级: 上校
  • 技术积分: 4288
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-30 17:29
文章分类

全部博文(516)

文章存档

2014年(4)

2013年(160)

2012年(352)

分类:

2012-11-01 12:03:30

原文地址:norflash驱动写法 作者:dingzerong


 

点击(此处)折叠或打开

  1. //**************************************************************************************************
  2. //***    linux-2.6内核中等待的使用例子 : norflash擦除时等待
  3. static int erase_one_block(struct map_info *map, struct flchip *chip,
  4.              unsigned long addr, unsigned long size)
  5. {
  6.     schedule_timeout(HZ);

  7.     while (flash_is_busy(map, chip->start))
  8.     {
  9.         unsigned long timeout = jiffies + HZ;
  10.         
  11.         /* OK Still waiting */
  12.         if (time_after(jiffies, timeout))
  13.         {
  14.             // 在规定时间没有等到的出错处理
  15.             chip->state = FL_READY;
  16.             spin_unlock_bh(chip->mutex);
  17.             printk(KERN_WARNING "%s: waiting for erase to complete "
  18.                 "timed out.\n", map->name);

  19.             return -EIO;
  20.         }
  21.     }

  22. }


  23. //**************************************************************************************************
  24. //***
  25. (1)对norflash的认识:
  26. 1.norflash有生产ID(用于区分某个厂商的flash)和设备ID(用于区分一个厂商的某种型号的flash)之分
  27. 2.norflash的block分为两类:parameter block 和main block
  28. 一般parameter block的总的size为一个main block的size
  29. 3.
  30. 块:是norflash擦除的单位(有32KB和128KB两种)
  31. 分区:属于同一个分区的共享同一个状态寄存器

  32. //**************************************************************************************************
  33. //***    norflash操作原理:假设现在讨论的norflash连接在cpu的地址空间的0x0C000000位置的intel L18F256 32MB norflash(块大小为128KB)
  34. /*
  35. intel E28F128J3A150 16MB 16bit norflash 和bf561相连的接法为 :
  36. bf561        <=>    E28F128J3A150

  37. A[23:1]     =>     A[23:1]        //bf561给norflash的地址信号
  38. D[15:0]        =>    D[15:0]        //bf561给norflash的数据信号
  39. /AMS0        =>    /CE        //bf561给norflash的片选信号
  40. /AOE        =>    /OE        //bf561给norflash的读信号
  41. /AWE        =>    /WE        //bf561给norflash的写信号

  42.             /BYTE        //上拉为高            
  43.             VPEN        //上拉为高
  44.             /RP        //上拉为高
  45.                     
  46. */

  47. 1.norflash读取生产ID和设备ID的步骤:
  48.     1)执行相应的命令序列:=>向norflash的基地址发送命
  49.     *(0x0C000000 + 0x5555) = 0x00AA;
  50.     *(0x0C000000 + 0x2AAA) = 0x0055;
  51.     *(0x0C000000 + 0x5555) = 0x0090;
  52.     2)开始读取生产ID:
  53.       (u16)mnfID=*(0x0C000000+0x0);
  54.       3)开始读取设备ID:
  55.       (u16)devID=*(0x0C000000+0x2);
  56.     
  57.     
  58. 2.以块为单位擦除norflash的步骤:(假设擦除uboot所在分区:0x0C100000)
  59.     1)禁止flash的写保护:     //设置EMIFS_CONFIG寄存器的最低位为1(即让wp引脚输出为高)
  60.     2)Block unlock
  61.     *((short*)0x0C100000) = 0x0060;             //块对齐地址
  62.     *((short*)0x0C100000) = 0x00D0;             //块对齐地址
  63.     while(!(*((short*)0x0C100000) & 0x0080));    //块对齐地址
  64.     *((short*)0x0C100000) = 0x00FF;             //设置norflash为read array模式
  65.     3)执行擦除命令序列:=>向要操作的块地址发送命令
  66.     *((short*)0x0C100000) = 0x0020;             //块对齐地址,INTEL_ERASE_CMD0
  67.     *((short*)0x0C100000) = 0x00D0;             //块对齐地址,INTEL_ERASE_CMD1
  68.     while (!(*((short*)0x0C100000) & 0x0080));    //块对齐地址,等待直到擦除结束    
  69.     5)设置norflash为read array模式
  70.     *((short*)0x0C100000) = 0x00FF;             //让norflash重新进入read array模式
  71.     6)使能flash的写保护: //设置EMIFS_CONFIG寄存器的最低位为0(即让wp引脚输出为低)

  72.     
  73. 3.以块为单位写norflash的步骤:(假设写uboot所在分区:0x0C100000)
  74. /*
  75. 发送写命令(0xE8)->发送数据->发送确认写命令(0xD0)->确认状态寄存器命令(0x70)->清掉状态寄存器命令(0x50)
  76. 块对齐         字对齐 块对齐         字对齐             字对齐
  77. */
  78.     1)禁止flash的写保护://设置EMIFS_CONFIG寄存器的最低位为1(即让wp引脚输出为高)
  79.     2)发送写命令:            //块对齐地址
  80.     *((short*)0x0C100000)=0x00E8;    //块对齐地址,program setup command
  81.     while(!(*0x0C100000 & 0x0080)); //块对齐地址
  82.     3)开始发送要写到flash的数据 =>(这些数据会在norflash芯片内部的buffer中锁存起来) =>每次2个字节,因为数据总线宽度为16位
  83.     (short *)ulData = 0x10010000        =>SDRAM的地址
  84.     (long *)psAddress = 0x0C000000        =>Norflash的地址
  85.     for(i=0; i<15; i++)
  86.      {
  87.          *psAddress = ulData[i];
  88.         psAddress++;
  89.      }
  90.     4)通知norflash将存在自己buffer中的数据写到norflash的介质上:
  91.     *((short*)0x0C100000)=0x00D0;    //块对齐地址
  92.     5)读状态寄存器,确保步骤4)已经完成
  93.     *0x0C100000 = 0x0070;          //Check Status Register ,这里是字对齐的地址
  94.     while(!(*0x0C100000 & BIT7));    //字对齐地址
  95.     6)// Check program status.
  96.     if ( *0x0C100000 & 0x0010 )    //字对齐地址
  97.     {    
  98.         *0x0C100000 = 0x0050;    //字对齐地址, Clear Status         
  99.         *((short*)0x0C100000) = 0x00FF;    //块对齐地址 Put chip back into read array mode.
  100.         return 1;
  101.     }
  102.     7)使能flash的写保护://设置EMIFS_CONFIG寄存器的最低位为0(即让wp引脚输出为低)        

  103.     
  104.     
  105.     
  106.     
  107.     
  108.     
  109.     
  110.     
  111. //**************************************************************************************************
  112. //***    norflash操作原理:假设现在讨论的norflash连接在cpu的地址空间的0x0C000000位置的st stm29w640d 8MB norflash(块大小为64KB,16位宽度)    
  113. //=> 注意ST和intel norflash是有区别的 :
  114. // ST的norflash A0可用, 故对16bit的接法为A1接A0,后面引脚类推        
  115. //intel的norflash A0不可用,故对16bit的接法为A1接A1,后面引脚类推
  116. //
  117. /*
  118. 1).st stm29w640d 8MB 16bit norflash 和bf561相连的接法为 :
  119. bf561        <=>    stm29w640d

  120. /ABE3        =>    A0        //注意ABE[3]在这里被当成A1来使用:
  121. A[22:2]     =>     A[21:1]        //bf561给norflash的地址信号
  122. D[15:0]        =>    D[15:0]        //bf561给norflash的数据信号
  123. /AMS0        =>    /CE        //bf561给norflash的片选信号
  124. /AOE        =>    /OE        //bf561给norflash的读信号
  125. /AWE        =>    /WE        //bf561给norflash的写信号

  126.             RDY        //上拉为高
  127.             /BYTE        //上拉为高
  128.             WP_/VPP        //上拉为高
  129.             /RP        //上拉为高
  130. 2).注意ABE[3]在这里被当成A1来使用:
  131. The ABE[3] pin of bf561 has two different functions. When the AMC is configured
  132. to do 16-bit data packing via the Asynchronous Memory Global Control
  133. Register,the ABE[3] pin of bf561 functions as the least significant bit of the address bus (ABE[3] = A1).            
  134. */
  135. 1.norflash读取生产ID和设备ID的步骤:
  136.     1)执行相应的命令序列:=>向norflash的基地址发送命
  137.     *(0x0C000000 + 0x5555) = 0x00AA;
  138.     *(0x0C000000 + 0x2AAA) = 0x0055;
  139.     *(0x0C000000 + 0x5555) = 0x0090;
  140.     
  141.     2)开始读取生产ID:
  142.       (u16)mnfID=*(0x0C000000+0x0);
  143.           
  144.       3)开始读取设备ID:
  145.       (u16)devID=*(0x0C000000+0x2);
  146.            
  147. 2.以块为单位擦除norflash的步骤:(假设擦除uboot所在分区:0x0C100000)
  148.     1)禁止flash的写保护:    //设置EMIFS_CONFIG寄存器的最低位为1(即让wp引脚输出为高)
  149.     2)Block unlock          //
  150.     3)执行擦除命令序列:=>向要操作的块地址发送命令
  151.     *((short*)0x0C100000 + 0x555) = 0x00AA;
  152.     *((short*)0x0C100000 + 0x2AA) = 0x0055;
  153.     *((short*)0x0C100000 + 0x555) = 0x0080;
  154.     *((short*)0x0C100000 + 0x555) = 0x00AA;
  155.     *((short*)0x0C100000 + 0x2AA) = 0x0055;
  156.     *((short*)0x0C100000) = 0x0030;             //块对齐地址
  157.     while (!(*((short*)0x0C100000) & 0x0080));    //块对齐地址,等待直到擦除结束    
  158.     
  159.     5)设置norflash为read array模式
  160.     *((short*)0x0C100000) = 0x00FF;            //让norflash重新进入read array模式
  161.     6)使能flash的写保护://设置EMIFS_CONFIG寄存器的最低位为0(即让wp引脚输出为低)
  162.     
  163. 3.以块为单位写norflash的步骤:(假设写uboot所在分区:0x0C100000)
  164. /*
  165. */
  166.     1)禁止flash的写保护:        //设置EMIFS_CONFIG寄存器的最低位为1(即让wp引脚输出为高)
  167.     2)发送写命令:            //块对齐地址
  168.     *((short*)0x0C100000 + 0x555) = 0x00AA;
  169.     *((short*)0x0C100000 + 0x2AA) = 0x0055;
  170.     *((short*)0x0C100000 + 0x555) = 0x00A0;
  171.         
  172.     3)开始发送要写到flash的数据 =>(这些数据会在norflash芯片内部的buffer中锁存起来) =>每次2个字节,因为数据总线宽度为16位
  173.     *(volatile U16 *)0x0C100000 = j;
  174.     
  175.     4)通知norflash将存在自己buffer中的数据写到norflash的介质上:
  176.     
  177.     5)读状态寄存器,确保步骤4)已经完成
  178.     while(!(*0x0C100000 & 0x80));    //字对齐地址
  179.     
  180.     6)// Check program status.

  181.     7)使能flash的写保护://设置EMIFS_CONFIG寄存器的最低位为0(即让wp引脚输出为低)        
  182.     
  183. 4.读norflash的步骤:(假设写uboot所在分区:0x0C100000)    
  184.     1)方法一:
  185.     *((short*)0x0C100000 + 0x555) = 0x00AA;
  186.     *((short*)0x0C100000 + 0x2AA) = 0x0055;    
  187.     
  188.     (short)data = *((short *)0x0C100000+);

  189.     2)方法二:直接读
  190.     (short)data = *((short *)0x0C100000+);


 

阅读(264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~