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

📄 flash_mtd.intel.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 2 页
字号:

               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__

extern volatile kal_uint32 processing_irqCnt;
void CompareData(void * Address, void * Data, kal_uint32 Length)
{
    kal_uint32 i;

    if((kal_uint32)Address&0x11==0 && (kal_uint32)Address&0x11==0)
    {
       kal_uint32* Source = (kal_uint32*)Address;
       kal_uint32* Dest = (kal_uint32*)Address;
       if ((Length&0x11) != 0 )
          ASSERT(0);
       for(i=0;i<(Length>>2);i++)
       {
          if(Source[i] != Dest[i])
             ASSERT(0); 
       }
    }
    else if((kal_uint32)Address&0x1==0 && (kal_uint32)Address&0x1==0)
    {
       kal_uint16* Source = (kal_uint16*)Address;
       kal_uint16* Dest = (kal_uint16*)Address;
       if ((Length&0x1) != 0 )
          ASSERT(0);
       for(i=0;i<(Length>>1);i++)
       {
          if(Source[i] != Dest[i])
             ASSERT(0); 
       }
    }
    else
    {
       kal_uint8* Source = (kal_uint8*)Address;
       kal_uint8* Dest = (kal_uint8*)Address;

       for(i=0;i<Length;i++)
       {
          if(Source[i] != Dest[i])
             ASSERT(0); 
       }
    }
}

static int ProgramData_SIB(void * DriveData, void * Address, void * Data, kal_uint32 Length){

   volatile FLASH_CELL* fp = (volatile FLASH_CELL*)Address;
   FLASH_CELL *dp = (FLASH_CELL*)Data;
   kal_uint8 *Bdp = (kal_uint8 *)Data;
   kal_uint32 savedMask,i;
   kal_uint32 ISRCountBefore,ISRCountAfter;
   
#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else
   NOR_MTD_DATA *D= DriveData;
   ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif

   
   ISRCountBefore = processing_irqCnt;
   // buffer program, data address is word-aligned
   if(Length > 16)
   {
      ASSERT((Length&1)==0);  
      if (((kal_uint32)Data&0x1)==0) 
      {
         fp[0] = INTEL_CMD_CLR_SR;        //clear status register first			
         fp[0] = SIB_CMD_PGM_BUF_C1;    			 
         fp[0] = (Length>>1)-1;                   
         for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
         {
            fp[i] = dp[i];   
         }
         fp[0] = SIB_CMD_PGM_BUF_C2;
      }
      // buffer program, data address is not word-aligned
      else 
      {                                                   
         FLASH_CELL Cell;
         kal_uint8 *b = (kal_uint8*) &Cell;
         
         //buffered program      	
         fp[0] = INTEL_CMD_CLR_SR;          //clear status register first			
         fp[0] = SIB_CMD_PGM_BUF_C1;      		 
         fp[0] = (Length>>1)-1;			
         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;		
      }
      ISRCountAfter = processing_irqCnt;    

      WaitReady_SIB((kal_uint32)&fp[0], INTEL_WAIT_PROGRAM, Length >> 5 );

      if(ISRCountBefore != ISRCountAfter)
      {
         CompareData(Address,Data,Length);
      }
   }
   //word 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_SIB((kal_uint32)fp, INTEL_WAIT_PROGRAM,0);
      }
   }
   else
   {
      ASSERT(0);
   }
   return FS_NO_ERROR;
}
#endif //__INTEL_SIBLEY__

/*-----------------------------------*/
static int NonBlockEraseBlock_INTEL(void * DriveData, kal_uint32  BlockIndex) /* Added by Eric */
{
   kal_uint32 savedMask;
#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else 
   NOR_MTD_DATA *D= DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);;
   ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif

   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 */
{
   kal_uint16 stat_data;
   kal_uint32 data_cache_id;
   kal_uint32 savedMask;

#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *) D->CurrAddr;
   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));   
#else
   NOR_MTD_DATA *D= DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
   ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo)); 
#endif

   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 */
{

#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#else 
   NOR_MTD_DATA *D= DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
#endif

   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 */
{

#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#else 
   NOR_MTD_DATA *D= DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
#endif

   fp[0] = INTEL_CMD_RESUME;

   return FS_NO_ERROR;
}

/*-----------------------------------*/
#ifdef __INTEL_SIBLEY__
static int BlankCheck_SIB(void * DriveData, kal_uint32 BlockIndex) //Especially for Sibley
{
   kal_uint32 savedMask;
   kal_uint16 stat_data;

#ifndef __NOR_FDM5__
   NOR_Flash_MTD_Data * D = DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *) D->CurrAddr;
   ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else 
   NOR_MTD_DATA *D= DriveData;
   volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
   ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif
   
   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
/********************************************/
/*                                                                            */
/*                        FDM5.0 MTD SUPPORT                      */
/*                                                                            */
/********************************************/
#ifdef __NOR_FDM5__

static int MountDevice_INTEL(void * DriveData, void * Info)
{
   NOR_MTD_DATA * D = DriveData;
   NORLayoutInfo * Layout = D->LayoutInfo;
   kal_uint32 TotalPhysicalPages;
   kal_uint32 TblEntryShift=0,j=1;
   kal_uint32 block;
   volatile FLASH_CELL * fp;
   kal_uint32 savedMask;
   kal_uint32 data_cache_id;



   // check and assign D->LayoutInfo
   TotalPhysicalPages = (Layout->BlkSize)/(Layout->PageSize)*(Layout->TotalBlks);

   while(j<TotalPhysicalPages)
   {
      j = j << 1;
      TblEntryShift++;
   }
   TblEntryShift = TblEntryShift>>1;
   if((TblEntryShift) >8)
	   TblEntryShift=8;
   Layout->TblEntrys = 1<<TblEntryShift;

   if ( (Layout->TblEntrys * Layout->TotalLSMT) < TotalPhysicalPages)
      ASSERT(0);

   /* unlock all blocks */
   for(block=0; block< Layout->TotalBlks; block++)
   {
      
      fp = (volatile FLASH_CELL *) BlockAddress(D, block);

      savedMask = SaveAndSetIRQMask();
      data_cache_id = INT_DisableDataCache();
      UNLOCK_COMMAND(0)
      fp[0] = INTEL_CMD_RD_ID;
      if( fp[2] & INTEL_BLOCK_LOCK_FLAG)
         ASSERT(0);
      fp[0] = INTEL_CMD_RD_ARRAY;
      INT_RestoreDataCache(data_cache_id);
      RestoreIRQMask(savedMask);
   }
   return FS_NO_ERROR;
}

static int ShutDown_INTEL(void * DriveData)
{
   NOR_MTD_DATA * D = DriveData;
   NORBankInfo * BankInfo = D->LayoutInfo->BankInfo;
   kal_uint32 fp = (kal_uint32)D->BaseAddr; 
   
   kal_uint32 i=0,j=0;

   for(i=0;BankInfo[i].Banks !=0;i++)
      for(j=0;j<BankInfo[i].Banks;j++)
      {
         WaitReady_INTEL((kal_uint32)fp, INTEL_WAIT_ERASE);
         fp+=(kal_uint32)BankInfo[i].BankSize;
      }
   return FS_NO_ERROR;
}
#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 + -