久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4039|回復: 0
打印 上一主題 下一主題
收起左側

NOR FLASH 編程詳解

[復制鏈接]
跳轉到指定樓層
樓主
ID:98924 發表于 2015-12-9 02:53 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
Nor Flash與Nand flash的不同之處在于Nor Flash的地址和數據線是不共用的,所以Nor Flash比較象ROM,是可以按地址自由讀的,這樣就非常適合存儲代碼,在開機時從Nor Flash中取代碼來執行。在我的板子上有16M的Intel的Nor Flash E28F128J3A150,以此為例來研究一下Nor Flash的一些常用操作。E28F128J3A150每個sector是128k,擦除是按扇區操作了。
  首先來看下E28F128J3A150與s3c2410的接口吧。
  一般情況下ROM與s3c2410的接口我們可以在s3c2410的手冊上看到,如下圖所示
  
  仔細看下16位和8位數據接口在地址線連接上的區別吧,16位的地址線是要移位的,A1接到A0上,這當然是比較容易理解的,位寬大了一倍,地址就少了一條。對于E28F128J3A150其實也是這樣,不過又有點不一樣,仔細看看E28F128J3A150的手冊吧。下面給出接線圖。
   
  
  不同之處E28F128J3A150貌似并沒有移位,其實只是因為E28F128J3A150的A1就相對于別的16位ROM的A0,其A0就相當于他們的A(-1)是用來指示8位地址的,所以還是一樣的。
  來看看Flash操作的命令集吧
  
  以幾個比較重要的操作來說明比較容易懂
  首先就是Read Identifier Codes
  先給定我們的flash開始的地址吧,flash_addr=ioremap(0x0,0x1000000);
  物理地址從0x0開始的0x1000000(16M)地址空間,這樣得到了可訪問的虛擬地址flash_addr
  很簡單,看命令表,先寫一個命令      writew(0x90,flash_addr);
  然后把Manufacture Code讀回來              readw(flash_addr);
  接著再讀Device Code                      readw(flash_addr+2);
  細節部分還是參考手冊吧
  其實內核已經MTD驅動完全支持Nor Flash的操作,所以不必要自己再寫了。
  不過在JTAG燒寫flash的程序中可以加入對我們自己的flash的支持。
  來看看其中對E28F128J3A150的燒寫代碼,分析一下。
  int Strata_CheckID(int targetAddr)             //返回Manufacture Code
  {
      _WR(targetAddr, 0x0090);   
      return _RD(targetAddr);                      //_WR和_RD都是半字操作
  }
  int Strata_CheckDevice(int targetAddr)       //返回Device Code
  {
      _WR(targetAddr, 0x0090);
      return _RD(targetAddr+0x2);
  }
  看著Block Erase Flowchart再對照著Block Erase的函數看就比較能完全看懂了
  
  void Strata_EraseSector(int targetAddress)
  {
      unsigned long ReadStatus;
      unsigned long bSR5;
      unsigned long bSR7;
      _WR(targetAddress, 0x0020);      //擦除命令first cycle
      _WR(targetAddress, 0x00d0);    //擦除命令second cycle
      _WR(targetAddress, 0x0070);      //讀狀態寄存器命令
      ReadStatus=_RD(targetAddress);  //讀狀態寄存器
  bSR7=ReadStatus & (1<<7);
  while(!bSR7 )       //需要判斷狀態寄存器的第7位
      {
          _WR(targetAddress, 0x0070);
          ReadStatus=_RD(targetAddress);
          bSR7=ReadStatus & (1<<7);
      }
      _WR(targetAddress, 0x0070);
      ReadStatus=_RD(targetAddress);
  bSR5=ReadStatus & (1<<5);           
  if (bSR5==0)
      {
          printf("Block @%xh Erase O.K. "n",targetAddress);
      }
      else
      {
          _WR(targetAddress, 0x0050);      //// Clear Status Register
          error_erase=1;   
      }
  _RESET(); //就相當于_WR(targetAddress, 0x00ff),回到Read Array的狀態。
  }
  很清晰的流程吧。
  Byte/Word Program Flowchart
  
   
  共兩種Program方式可以把數據寫到Flash中,一般也只用到這種就可以了
  int Strata_ProgFlash(U32 realAddr,U16 data)
  {
      unsigned long ReadStatus;
      unsigned long bSR4;
      unsigned long bSR7;   
      _WR(realAddr, 0x0040);
      _WR(realAddr, data);
      _WR(realAddr, 0x0070);
      ReadStatus=_RD(realAddr);
      bSR7=ReadStatus & (1<<7);
      while(!bSR7)
      {
          _WR(realAddr, 0x0070);
          ReadStatus=_RD(realAddr);
          bSR7=ReadStatus & (1<<7);
      }
      _WR(realAddr, 0x0070);
      ReadStatus=_RD(realAddr);
      bSR4=ReadStatus & (1<<4);
      if (bSR4==0)
      {
          //printf("Successful Program!!"n");
      }
      else
      {
          _WR(realAddr, 0x0050);      // Clear Status Register
          error_program=1;         
      }
      _RESET();
      return 0;
  }
  以上這種寫會很慢,以致于JTAG燒寫相當得慢。
  
   
  int Strata_unprotect_sector(int targetAddr)         //去除sector的寫保護
{
   int SR7,SR3,SR4,SR5,ReadStatus;
   int res=0;
   _WR(targetAddr,0x0050); //Clear Status Register
   _WR(targetAddr,0x0060); //First bus cycle
   _WR(targetAddr,0x00D0); //Second bus cycle
   _WR(targetAddr,0x0070);
   ReadStatus=_RD(targetAddr);
   SR7=ReadStatus & (1<<7);
   while(!SR7)
   {
     _WR(targetAddr,0x0070);
     ReadStatus=_RD(targetAddr);
     SR7=ReadStatus & (1<<7);
   }                                                                       
     _WR(targetAddr,0x0070);
     ReadStatus=_RD(targetAddr);
     SR3=ReadStatus & (1<<3);
     SR4=ReadStatus & (1<<4);
     SR5=ReadStatus & (1<<5);
     if(SR3) {printf("Voltage Range Error"); res=-1;}
     if(SR4 && SR5) {printf("Command Sequence Error"); res=-2;}
     if(SR5) {printf("Clear Block Lock-Bits Error"); res=-3;}
     _RESET();
     return res;
}
  另外按照write to buffer的流程自己寫了一個函數,沒有test,不想再去燒寫了,太煩了,就這樣好了。
  void Strata_buffer_program(int blockAddress,int tagetAddress,U16* buf)
  {
      unsigned long ReadStatus;
      unsigned long bSR4;     
      unsigned long bSR7;
      int i;
         do {
                _WR(blockAddress, 0x00E8);
          _WR(blockAddress, 0x0070);
          ReadStatus=_RD(blockAddress);
          bSR7=ReadStatus & (1<<7);
         } while(!bSR7);
      _WR(blockAddress, 0x001F);
         for(i=0;i<=0x1F;i++)
                _WR(targetAddress+2*i, *(buf+i));
         _WR(blockAddress, 0x00D0);
         do {
          _WR(blockAddress, 0x0070);
          ReadStatus=_RD(blockAddress);
          bSR7=ReadStatus & (1<<7);
         } while(!bSR7);
      _WR(blockAddress, 0x0070);
      ReadStatus=_RD(blockAddress);
      bSR4=ReadStatus & (1<<4);
      if (bSR4==0)
      {
          //printf("Successful Program!!"n");
      }
      else
      {
          _WR(blockAddress, 0x0050);
          error_program=1;
      }
      _RESET();
  }

        
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本天堂一区二区 | 精品国产乱码久久久久久丨区2区 | 欧美一级特黄aaa大片在线观看 | 黄色a级一级片 | 日韩激情网 | 日韩欧美在线视频播放 | 国精日本亚洲欧州国产中文久久 | 国产精品久久久久久久毛片 | 人人干人人爽 | 涩涩视频在线观看 | 91久久精品国产91久久性色tv | 日本a∨精品中文字幕在线 亚洲91视频 | 日本三级全黄三级三级三级口周 | 一区二区三区av | 久久国产成人 | 精品国产乱码久久久久久久久 | 国内精品久久精品 | 一级做a爰片性色毛片 | 国产精品久久一区 | 精品中文字幕一区二区三区 | 成人黄色a | 日韩欧美日韩在线 | 国产在线观看不卡一区二区三区 | 亚洲日本乱码在线观看 | 亚洲综合在线视频 | 欧美性受| 国产黄视频在线播放 | 在线91 | 日韩理论电影在线观看 | 免费观看一级特黄欧美大片 | gav成人免费播放视频 | 在线观看免费av网 | 激情91 | 一二三四av| 国产在线精品一区二区三区 | 无码日韩精品一区二区免费 | 爱爱综合网 | 久久久久se| 久久久久免费 | 91porn国产成人福利 | 久久久精品国产 |