⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash_mtd.intel.c

📁 本软件实现了FLASH底层驱动包括NOR FLASH与NAND FLASH
💻 C
📖 第 1 页 / 共 2 页
字号:

               for(i = 0; i < PAGE_BUFFER_SIZE; i++)
               {
                  fp[k*PAGE_BUFFER_SIZE+i] = dp[k*PAGE_BUFFER_SIZE+i];  // fill data to device buffer
               }

               fp[k*PAGE_BUFFER_SIZE] = INTEL_CMD_BUF_PGM_CNF; // set confirm command to flush buffer to flash

#ifdef _LOW_COST_SINGLE_BANK_FLASH_      
               WaitReady_INTEL((kal_uint32)&fp[k*PAGE_BUFFER_SIZE], INTEL_WAIT_PROGRAM);
               RestoreIRQMask(savedMask);               
#else
               RestoreIRQMask(savedMask);
               WaitReady_INTEL((kal_uint32)&fp[k*PAGE_BUFFER_SIZE], INTEL_WAIT_PROGRAM);
#endif               
            }
#endif

         }
      }
      break;

      default:
      {
         kal_uint32 i, j;
         volatile FLASH_CELL *fp;

         fp = (volatile FLASH_CELL *)Address;
         if((((kal_uint32)Data) % sizeof(FLASH_CELL)))  // Data address is not word-aligned
         {
            kal_uint8 *bdp =  (kal_uint8*)Data;
            FLASH_CELL Cell;
            kal_uint8 *b = (kal_uint8*)&Cell;

            j = 0;
            for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
            {
               b[0] = bdp[j++];
               b[1] = bdp[j++];
               savedMask = SaveAndSetIRQMask();
               fp[i] = INTEL_CMD_PGM_WORD;
               fp[i] = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_      
               WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
               RestoreIRQMask(savedMask);               
#else               
               RestoreIRQMask(savedMask);
               WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
#endif               
            }
         }
         else  // Data address is word-aligned
         {
            FLASH_CELL *dp = (FLASH_CELL*)Data;

            for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
            {
               savedMask = SaveAndSetIRQMask();
               fp[i] = INTEL_CMD_PGM_WORD;
               fp[i] = dp[i];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_      
               WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);             
               RestoreIRQMask(savedMask);               
#else
               RestoreIRQMask(savedMask);
               WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
#endif               
            }
         }
      }
      break;

   }
   return FS_NO_ERROR;
}

#else //__INTEL_SIBLEY__

static int ProgramData_SIB(void * DriveData, void * Address, void * Data, kal_uint32 Length){
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL* fp = (volatile FLASH_CELL*)Address;
   FLASH_CELL *dp = (FLASH_CELL*)Data;
   kal_uint8 *Bdp = (kal_uint8 *)Data;
   kal_uint32 savedMask,i;
   
   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));

   // object mode program, data address is word-aligned
   if ((kal_uint32)Address%1024 ==0 && Length == 1024 && ((kal_uint32)Data&0x1)==0) 
   {
      savedMask = SaveAndSetIRQMask(); 
      fp[0] = INTEL_CMD_CLR_SR;        //clear status register first			
      fp[0] = SIB_CMD_PGM_BUF_C1;    			 
      fp[0] = 511;                   
      for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
      {
         fp[i] = dp[i];   
      }
      fp[0] = SIB_CMD_PGM_BUF_C2;    
      RestoreIRQMask(savedMask);
      WaitReady_INTEL((kal_uint32)&fp[0], INTEL_WAIT_PROGRAM);
   }
   // object mode program, data address is not word-aligned
   else if((kal_uint32)Address%1024 ==0 && Length == 1024 ) 
   {                                                   
      FLASH_CELL Cell;
      kal_uint8 *b = (kal_uint8*) &Cell;
      
      //buffered program      	
      savedMask = SaveAndSetIRQMask();			 
      fp[0] = INTEL_CMD_CLR_SR;          //clear status register first			
      fp[0] = SIB_CMD_PGM_BUF_C1;      		 
      fp[0] = 511;			
      for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
      {
         b[0] = Bdp[0];
         b[1] = Bdp[1];
         fp[i] = Cell;	
         Bdp+=2;
      }
      fp[0] = SIB_CMD_PGM_BUF_C2;		
      RestoreIRQMask(savedMask);
      WaitReady_INTEL((kal_uint32)&fp[0], INTEL_WAIT_PROGRAM);
      
   }
   //control mode program
   else if(Length <= 16)  
   {
      kal_uint32 AddrPtr = (kal_uint32)Address;
      kal_uint32 DataPtr = (kal_uint32)Data;
      kal_uint32 ofs;
      FLASH_CELL Cell;
      kal_uint8 *b = (kal_uint8*) &Cell;
      
      // A3 must equal to zero
      ASSERT(((kal_uint32)Address&0x10)==0 &&(((kal_uint32)Address+Length-1)&0x10)==0); 

      while(Length >0)
      {
         if ((AddrPtr % sizeof(FLASH_CELL) !=0) || (Length < sizeof(FLASH_CELL)))
         {
            ofs = (AddrPtr) & (sizeof(FLASH_CELL)-1);
            fp = (FLASH_CELL*) (AddrPtr & ~(sizeof(FLASH_CELL)-1)); // round it down
            Cell = fp[0];
            b[ofs] = ((kal_uint8*)DataPtr)[0];
            Length=Length-1;
            AddrPtr=AddrPtr+1;
            DataPtr=DataPtr+1;
         }
         else
         {
            fp = (FLASH_CELL*) (AddrPtr);
            b[0] = ((kal_uint8*)DataPtr)[0];
            b[1] = ((kal_uint8*)DataPtr)[1];
            Length=Length-2;
            AddrPtr=AddrPtr+2;
            DataPtr=DataPtr+2;
         }
         savedMask = SaveAndSetIRQMask();
         fp[0] = SIB_CMD_PGM_WORD;
         fp[0] = Cell;
         RestoreIRQMask(savedMask);
         WaitReady_INTEL((kal_uint32)fp, INTEL_WAIT_PROGRAM);
      }
   }
   else
   {
      ASSERT(0);
   }
   return FS_NO_ERROR;
}
#endif //__INTEL_SIBLEY__

/*-----------------------------------*/
static int NonBlockEraseBlock_INTEL(void * DriveData, kal_uint32  BlockIndex) /* Added by Eric */
{
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
   kal_uint32 savedMask;

   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));

   savedMask = SaveAndSetIRQMask();
   //Erase command
   fp[0] = INTEL_CMD_ERASE_SETUP;
   fp[0] = INTEL_CMD_ERASE_CONFIRM;
   RestoreIRQMask(savedMask);

   return FS_NO_ERROR;
}

/*-----------------------------------*/
static int CheckDeviceReady_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
   kal_uint16 stat_data;
   kal_uint32 data_cache_id;
   kal_uint32 savedMask;

   data_cache_id = INT_DisableDataCache();

   savedMask = SaveAndSetIRQMask();
   fp[0] = INTEL_CMD_RD_SR;
   stat_data = fp[0];
   fp[0] = INTEL_CMD_RD_ARRAY;
   RestoreIRQMask(savedMask);

   INT_RestoreDataCache(data_cache_id);
   
   if(stat_data & INTEL_READY_FLAG)
      return FS_NO_ERROR;
   else
      return FS_FLASH_ERASE_BUSY;
}

/*-----------------------------------*/
static int SuspendErase_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
   FLASH_CELL s = 0;
   kal_uint32 data_cache_id;
   
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
   kal_uint32 savedMask;
   savedMask = SaveAndSetIRQMask();
#endif   

   data_cache_id = INT_DisableDataCache();

   fp[0] = INTEL_CMD_SUSPEND;
   fp[0] = INTEL_CMD_RD_SR;
   s = fp[0];
   while(!(s&INTEL_READY_FLAG))
   {
      fp[0] = INTEL_CMD_RD_SR;
      s = fp[0];
   }
   fp[0] = INTEL_CMD_RD_ARRAY;
   
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
   RestoreIRQMask(savedMask);
#endif    

   INT_RestoreDataCache(data_cache_id);
   return FS_NO_ERROR;
}

/*-----------------------------------*/
static int ResumeErase_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;

   fp[0] = INTEL_CMD_RESUME;

   return FS_NO_ERROR;
}

/*-----------------------------------*/
#ifdef __INTEL_SIBLEY__
static int BlankCheck_SIB(void * DriveData, kal_uint32 BlockIndex) //Especially for Sibley
{
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *) D->CurrAddr;
   kal_uint32 savedMask;
   kal_uint16 stat_data;

   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
   
   savedMask = SaveAndSetIRQMask();
   //Blank Check Command
   fp[0] = SIB_CMD_BLANK_CK_C1;
   fp[0] = SIB_CMD_BLANK_CK_C2;
   RestoreIRQMask(savedMask);

   WaitReady_INTEL((kal_uint32)fp, SIB_WAIT_BLANK_CHECK); 
   //Read Status Command
   fp[0] = INTEL_CMD_RD_SR;
   stat_data = fp[0];
   fp[0] = INTEL_CMD_CLR_SR;
   fp[0] = INTEL_CMD_RD_ARRAY;
   return (stat_data & SIB_NOT_ALL_ERASED_FLAG)?0:1; // SR[5]=1 means not all erased
}
#endif

/*-----------------------------------*/
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif

#if  (defined(_LOW_COST_SINGLE_BANK_FLASH_) && defined(__MTK_TARGET__))
   #pragma arm section code
#endif 

/*-----------------------------------*/
NOR_MTD_Driver DriverName =
{
   MountDevice_INTEL,
   ShutDown_INTEL,
   MapWindow,
   EraseBlock_INTEL,
#ifndef __INTEL_SIBLEY__
   ProgramData_INTEL,
#else
   ProgramData_SIB,
#endif
   NonBlockEraseBlock_INTEL,
   CheckDeviceReady_INTEL,
   SuspendErase_INTEL,
   ResumeErase_INTEL,
#ifndef __INTEL_SIBLEY__
   NULL
#else
   BlankCheck_SIB
#endif   
};


#endif //__INTEL_SERIES_NOR__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -