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

📄 flash_mtd.amd.c

📁 本软件实现了FLASH底层驱动包括NOR FLASH与NAND FLASH
💻 C
📖 第 1 页 / 共 3 页
字号:
         savedMask = SaveAndSetIRQMask();
         bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
         bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
         bp[ADDR_UNLOCK_1] = CMD_PROG;
         ((volatile FLASH_CELL*)Address)[0] = ((FLASH_CELL*)Data)[0];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
         WaitReady_AMD((kal_uint32)Address, *(kal_uint16*)Data);
         RestoreIRQMask(savedMask);         
#else
         RestoreIRQMask(savedMask);
         WaitReady_AMD((kal_uint32)Address, *(kal_uint16*)Data);
#endif
         break;

      case 1:
      {
         volatile FLASH_CELL *fp;
         kal_uint32 ofs = ((kal_uint32) Address) & (sizeof(FLASH_CELL)-1);
         FLASH_CELL Cell;
         kal_uint8 *b = (kal_uint8*) &Cell;

         fp   = (void*) (((kal_uint32) Address) & ~(sizeof(FLASH_CELL)-1)); // round it down
         Cell = fp[0];

         b[ofs] = ((kal_uint8*)Data)[0];

         #ifdef DEBUG
         //Attempt to set bits in flash!
         ASSERT(!((~fp[0]) & Cell))
         #endif

         savedMask = SaveAndSetIRQMask();
         bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
         bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
         bp[ADDR_UNLOCK_1] = CMD_PROG;
         fp[0]     = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
         WaitReady_AMD((kal_uint32)fp, (kal_uint16)Cell);
         RestoreIRQMask(savedMask);
#else         
         RestoreIRQMask(savedMask);
         WaitReady_AMD((kal_uint32)fp, (kal_uint16)Cell);
#endif
      }
      break;
   default:
      #ifdef DEBUG
         //Misaligned write into flash
         ASSERT(!(((kal_uint32)Address) % sizeof(FLASH_CELL)));
         //Misaligned length write into flash
         ASSERT(!(Length % sizeof(FLASH_CELL)));
      #endif
      #ifdef DEBUG
      {
         kal_uint32 i;
         volatile FLASH_CELL *fp = (void*) Address;
         FLASH_CELL * V = Data;

         for (i=0; i<Length/sizeof(FLASH_CELL); i++)
            ASSERT(!((~fp[i]) & V[i]));//Attempt to set bits in flash!
      }
      #endif

      {
         kal_uint32 i, j;
#ifdef __PAGE_BUFFER_PROGRAM__
         kal_uint32 Words;
         kal_uint32 ProgramWords;
#endif
         volatile FLASH_CELL *fp;

         fp = (volatile FLASH_CELL *)Address;
         if((((kal_uint32)Data) % sizeof(FLASH_CELL)))
         {
            kal_uint8 *bdp =  (kal_uint8*)Data;
            FLASH_CELL Cell;
            kal_uint8 *b = (kal_uint8*)&Cell;
#ifndef __PAGE_BUFFER_PROGRAM__
            j = 0;
            for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
            {
               b[0] = bdp[j++];
               b[1] = bdp[j++];
               savedMask = SaveAndSetIRQMask();
               bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
               bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
               bp[ADDR_UNLOCK_1] = CMD_PROG;
               fp[i] = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
               WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)Cell);
               RestoreIRQMask(savedMask);
#else               
               RestoreIRQMask(savedMask);
               WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)Cell);
#endif
            }
#else
            j = 0;
            Words = (Length/sizeof(FLASH_CELL));
            while(Words>0)
            {
               ProgramWords = Words > PAGE_BUFFER_SIZE ?  PAGE_BUFFER_SIZE : Words ;
               savedMask = SaveAndSetIRQMask();
               bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
               bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
               fp[0] = CMD_WRITETOBUFFER;
               fp[0] = ProgramWords -1;// set data count
               
               for(i = 0; i < ProgramWords; i++)
               {
                  b[0] = bdp[j++];
                  b[1] = bdp[j++];
                  fp[i] = Cell;
               }
               fp[0] = CMD_BUFFERTOFLASH;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
               WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)Cell);
               RestoreIRQMask(savedMask);
#else               
               RestoreIRQMask(savedMask);
#ifdef __SPANSION_PL_N__
               DelayAWhile_AMD();
#endif //__SPANSION_PL_N__
               WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)Cell);               
#endif
               Words -= ProgramWords;
               fp += ProgramWords;
            }
#endif
         }
         else
         {
            FLASH_CELL *dp = (FLASH_CELL*)Data;
#ifndef __PAGE_BUFFER_PROGRAM__
            for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
            {
               savedMask = SaveAndSetIRQMask();
               bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
               bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
               bp[ADDR_UNLOCK_1] = CMD_PROG;
               fp[i] = dp[i];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
               WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)dp[i]);
               RestoreIRQMask(savedMask);
#else
               RestoreIRQMask(savedMask);
               WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)dp[i]);               
#endif
            }
#else
            Words = (Length/sizeof(FLASH_CELL));
            while(Words>0)
            {
               ProgramWords = Words > PAGE_BUFFER_SIZE ?  PAGE_BUFFER_SIZE : Words ;
               savedMask = SaveAndSetIRQMask();
               bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
               bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
               fp[0] = CMD_WRITETOBUFFER;
               fp[0] = ProgramWords -1;// set data count
               
               for(i = 0; i < ProgramWords; i++)
               {
                  fp[i] = dp[i];
               }
               fp[0] = CMD_BUFFERTOFLASH;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
               WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)dp[ProgramWords -1]);
               RestoreIRQMask(savedMask);
#else //_LOW_COST_SINGLE_BANK_FLASH_              
               RestoreIRQMask(savedMask);
#ifdef __SPANSION_PL_N__
               DelayAWhile_AMD();
#endif //__SPANSION_PL_N__
               WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)dp[ProgramWords -1]);
#endif //_LOW_COST_SINGLE_BANK_FLASH_
               Words -= ProgramWords;
               fp += ProgramWords;
               dp += ProgramWords;
            }
#endif
         }
      }
      break;
   }
   return FS_NO_ERROR;
}
#endif //__TOSHIBA_TV__

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

#ifdef DEBUG
   //EraseBlock: block not mapped
   ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
#endif

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

   EraseCommand_AMD(fp);
#ifdef __SPANSION_PL_N__
   DelayAWhile_AMD();
#endif
   return FS_NO_ERROR;
}

/*-----------------------------------*/
static int CheckDeviceReady_AMD(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 s1, s2;
   kal_uint32 data_cache_id;
#ifndef __PRODUCTION_RELEASE__
   static kal_uint32 test_times=0;
#endif

   data_cache_id = INT_DisableDataCache();

   s1 = fp[1];
   s2 = fp[1];
   if (((s1 ^ s2) & TOGGLE_ERASE_SUSPEND))
   {
      if(!((s1 ^ s2) & TOGGLE_BUSY))
      {
         /* flash is erase suspended */
         fp[0] = CMD_RESU_SEC_ERASE;
      }
      INT_RestoreDataCache(data_cache_id);
      return FS_FLASH_ERASE_BUSY;
   }
   else
   {
      s1 = fp[1];
      s2 = fp[1];
   
      if(s2 == 0xffff)
      {
         INT_RestoreDataCache(data_cache_id);
#ifndef __PRODUCTION_RELEASE__
         test_times = 0;
#endif
         return FS_NO_ERROR;
      }
      else
      {
         /* the erase operation is reset abnormally */
         if(!(s1 ^ s2))
         {
#ifndef __PRODUCTION_RELEASE__

            /* MAUI_00218339: S71PL129JB0BAW9U need another busy time before     */
            /* polling, modify to allow second erase command to solve this issue */
            test_times++;
            if (test_times > 1)  
               ASSERT(0);
#endif
            EraseCommand_AMD(fp);
         }
         INT_RestoreDataCache(data_cache_id);
         return FS_FLASH_ERASE_BUSY;
      }
   }
}

/*-----------------------------------*/
static int SuspendErase_AMD(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;
   kal_uint32 data_cache_id;
   
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
   kal_uint32 savedMask;
   savedMask = SaveAndSetIRQMask();
#endif   

   data_cache_id = INT_DisableDataCache();
   

#ifdef DEBUG
   #ifndef _LOW_COST_SINGLE_BANK_FLASH_
   //SuspendErase: block not mapped
   ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
   #endif
#endif

   fp[0]     = CMD_SUSP_SEC_ERASE;

   s = fp[0];
   while(!(s&POLL_BUSY))
      s = fp[0];

   INT_RestoreDataCache(data_cache_id);

#ifdef _LOW_COST_SINGLE_BANK_FLASH_  
   RestoreIRQMask(savedMask);
#endif    

   return FS_NO_ERROR;
}

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

#ifdef DEBUG
   //ResumeErase: block not mapped
   ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
#endif

   fp[0]     = CMD_RESU_SEC_ERASE;

   return FS_NO_ERROR;
}

#ifdef _LOW_COST_SINGLE_BANK_FLASH_
#ifdef __MTK_TARGET__
#pragma arm section code
#endif /* __MTK_TARGET__ */
#endif

/*-----------------------------------*/
NOR_MTD_Driver DriverName =
{
   MountDevice_AMD,
   ShutDown_AMD,
   MapWindow,
   EraseBlock_AMD,
#if (defined(__TOSHIBA_TV__) || defined(__TOSHIBA_TY__))
   ProgramData_TOSHIBA,
#else
   ProgramData_AMD,
#endif
   NonBlockEraseBlock_AMD,
   CheckDeviceReady_AMD,
   SuspendErase_AMD,
   ResumeErase_AMD
};

#endif //__AMD_SERIES_NOR__

⌨️ 快捷键说明

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