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

📄 flash_mtd.amd.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 4 页
字号:
   {
      data_test1 = *(volatile kal_uint16*)addr;
      data_test2 = *(volatile kal_uint16*)addr;
           
      if((data_test1 ^ data_test2) & TOGGLE_BUSY)
      {
         status = OTP_ERR_WAIT;
      }
   }
   else
   {
      status = OTP_ERR_BUSY;
   }
   INT_RestoreDataCache(data_cache_id);
   return status;
}

/*************************************************************************
* FUNCTION
*    OTPRead
*
* DESCRIPTION
*    This function implements the OTP read function, first it enter 
*    secured silicon sector, and read data from "Offset", totally read 
*    "Length" bytes, then exit secured silicon sector mode
*
* PARAMETERS
*    D: driver structure
*    Offset: the start position want to read (unit:bytes)
*    BufferPtr: the buffer address want to read to
*    Length: total length want to read (unit: bytes)
*
* RETURNS
*   FS_NO_ERROR: no error
*   FS_FLASH_OTP_OVERSCOPE: reading range is out of OTP range
*
*************************************************************************/

/* While the Secured Silicon Sector access is enabled, simultaneous 
 * operations are not allow fro bank A. 
 */

kal_int32 
OTPRead_AMD(void * DriveData,
            kal_uint32 Offset, 
            void * BufferPtr,
            kal_uint32 Length)
{
   NOR_Flash_MTD_Data * MTDData = DriveData;
   kal_uint32 savedMask,i;
   volatile FLASH_CELL *BaseAddr;
   kal_uint8 *src,*dest;
   kal_uint32 data_cache_id;

   /* drvier initialization test */
   ASSERT((~MTDData->Signature == (kal_uint32)MTDData->RegionInfo));
   
   BaseAddr = (volatile FLASH_CELL *)INT_RetrieveFlashBaseAddr();
   src = (kal_uint8 *)((kal_uint32)BaseAddr + NOR_OTPOffset + Offset);
   dest =(kal_uint8 *)BufferPtr;
   
   /* Base Addr check */
   ASSERT(!(((kal_uint32)BaseAddr) % sizeof(FLASH_CELL)));
   
   /* check if read scope is out of range */ 
   if( (Offset > NOR_OTPLength) ||
       (Offset+ Length)> NOR_OTPLength )
   {
      return FS_FLASH_OTP_OVERSCOPE;   
   }
   
   /* Disable Interrupt */
   savedMask = SaveAndSetIRQMask();
   data_cache_id = INT_DisableDataCache();
   
   /* Enter Secured Silicon Sector Mode */
   BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
   BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
   BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_ENTRY; 
      
   /* Read Secured Silicon Sector Data */
   for(i=0; i< Length; i++)
      dest[i] = src[i];
   
   /* Exit Secured Silicon Sector Mode */
   BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
   BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
   BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_EXIT;
   BaseAddr[0] =  CMD_OTP_ZERO;
   
   /* Enable Interrupt */    
   INT_RestoreDataCache(data_cache_id);
   RestoreIRQMask(savedMask);
   
   return FS_NO_ERROR;
}

/*************************************************************************
* FUNCTION
*    OTPWrite
*
* DESCRIPTION
*    This function implements the OTP write function, first it enter 
*    secured silicon sector, and write data from "Offset", totally write 
*    "Length" bytes, then exit secured silicon sector mode.
*    Be carefully, do not set bit to one if it is zero
*
* PARAMETERS
*    D: driver structure
*    Offset: the start position want to write (unit:bytes)
*    BufferPtr: the buffer address want to write from
*    Length: total length want to write (unit: bytes)
*
* RETURNS
*   FS_NO_ERROR: no error
*   FS_FLASH_OTP_OVERSCOPE: writing range is out of OTP range
*   FS_FLASH_OTP_LOCK_ALREADY: OTP area is already locked
*
*************************************************************************/


kal_int32 
OTPWrite_AMD(void * DriveData,
             kal_uint32 Offset, 
             void * BufferPtr,
             kal_uint32 Length)
{
   NOR_Flash_MTD_Data * MTDData = DriveData;
   kal_uint32 savedMask,DoneLength=0;
   volatile FLASH_CELL *BaseAddr;
   FLASH_CELL IndicatorBit;
   kal_int32 status;
   
   kal_uint8 *src,*dest;
   kal_uint16 *dest16;
   FLASH_CELL CELL;
   kal_uint8 *CELLPtr = (kal_uint8 *)&CELL;

   /* drvier initialization test */
   ASSERT((~MTDData->Signature == (kal_uint32)MTDData->RegionInfo));
   
   BaseAddr = (volatile FLASH_CELL*)INT_RetrieveFlashBaseAddr();
   dest = (kal_uint8 *)((kal_uint32)BaseAddr + NOR_OTPOffset + Offset);
   src =(kal_uint8 *)BufferPtr;
   
   /* Base Addr check */
   ASSERT(!(((kal_uint32)BaseAddr) % sizeof(FLASH_CELL)));
   
   /* check if read scope is out of range */ 
   if( (Offset > NOR_OTPLength) ||
       (Offset+ Length)> NOR_OTPLength )
   {
      return FS_FLASH_OTP_OVERSCOPE;   
   }
   
   /* Disable Interrupt */
   savedMask = SaveAndSetIRQMask();
   
   /* Enter Auto Select Mode */
   BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
   BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
   BaseAddr[ADDR_UNLOCK_1] = CMD_AUTOSELECT_ENTRY;
   
   IndicatorBit = BaseAddr[3];
   
   /* Exit Auto Select Mode */
   BaseAddr[0] = CMD_AUTOSELECT_EXIT;
   
   /* Enable Interrupt */    
   RestoreIRQMask(savedMask); 
      
   if ((IndicatorBit & 0x40))
   {
      return FS_FLASH_OTP_LOCK_ALREADY;
   } 
   
   while ( DoneLength < Length )
   {
      /* Disable Interrupt */
      savedMask = SaveAndSetIRQMask();
   
      /* Enter Secured Silicon Sector Mode */
      BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
      BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
      BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_ENTRY; 
      
      //enter write command to flash 
      if ( ((kal_uint32)dest&(sizeof(FLASH_CELL)-1)) || ((Length-DoneLength)==1) ) //not word align
      {
         kal_uint32 ofs = ((kal_uint32) dest) & (sizeof(FLASH_CELL)-1);
         kal_uint8 *b = (kal_uint8 *)&CELL; 
         
         dest16 = (kal_uint16 *)(((kal_uint32)dest) & ~(sizeof(FLASH_CELL)-1));
         CELL = dest16[0];
         b[ofs] = src[0];
         
      }
      else //word align
      {
         dest16 = (kal_uint16 *)dest;
         CELLPtr[0] = src[0];
         CELLPtr[1] = src[1];
      }
      /*check write content:attempt to set bits in flash (0->1) */
      if((~(dest16[0])) & CELL)
      {
         /* exit secured Silicon Sector Mode */
         BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
         BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
         BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_EXIT;
         BaseAddr[0] =  CMD_OTP_ZERO; 
         /* Enable Interrupt */    
         RestoreIRQMask(savedMask);
         ASSERT(0);   
      }
      
      //write one word to flash
      BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
      BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
      BaseAddr[ADDR_UNLOCK_1] = CMD_PROG;
      dest16[0] = CELL;
      
      /* check till ready */
      while(1)
      {
         
         status = OTPCheckWriteReady_AMD((kal_uint32)dest16 ,(kal_uint16) CELL);
         if(status == OTP_ERR_NONE)
         {
            break;
         }else if(status == OTP_ERR_WAIT)
         {
            /* exit secured Silicon Sector Mode */
            BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
            BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
            BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_EXIT;
            BaseAddr[0] =  CMD_OTP_ZERO; 
            /* Enable Interrupt */    
            RestoreIRQMask(savedMask);
            ASSERT(0);  
         }         
      }
      /* Exit Secured Silicon Sector Mode */
      BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
      BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
      BaseAddr[ADDR_UNLOCK_1] = CMD_OTP_EXIT;
      BaseAddr[0] =  CMD_OTP_ZERO;
      /* Enable Interrupt */    
      RestoreIRQMask(savedMask);
      
      /* addr offset */
      if ( ((kal_uint32)dest&(sizeof(FLASH_CELL)-1)) || ((Length-DoneLength)==1) ) //not word align
      {
         dest+=1;
         src+=1;
         DoneLength+=1;    
      }
      else
      {
         dest+=2;
         src+=2;
         DoneLength+=2; 
      }
   }
   return FS_NO_ERROR;
}

/*************************************************************************
* FUNCTION
*    OTPLock
*
* DESCRIPTION
*    This function implements the OTP lock function. 
* PARAMETERS
*    D: driver structure
*
* RETURNS
*   FS_NO_ERROR: no error
*   FS_FLASH_OTP_LOCK_ALREADY: OTP area is already locked
*
*************************************************************************/


kal_int32 
OTPLock_AMD(void * DriveData)
{
   NOR_Flash_MTD_Data * MTDData = DriveData;
   kal_uint32 savedMask;
   volatile FLASH_CELL *BaseAddr = (volatile FLASH_CELL*)INT_RetrieveFlashBaseAddr();
   FLASH_CELL IndicatorBit,CELL;
   kal_int32 status;


   /* drvier initialization test */
   ASSERT((~MTDData->Signature == (kal_uint32)MTDData->RegionInfo));
   
  
   /* Disable Interrupt */
   savedMask = SaveAndSetIRQMask();
   
   /* Enter Auto Select Mode */
   BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
   BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
   BaseAddr[ADDR_UNLOCK_1] = CMD_AUTOSELECT_ENTRY;
   
   IndicatorBit = BaseAddr[3];
      
   /* Exit Auto Select Mode */
   BaseAddr[0] = CMD_AUTOSELECT_EXIT; 
      
   if ((IndicatorBit & 0x40))
   {
      /* Enable Interrupt */    
      RestoreIRQMask(savedMask);
      return FS_FLASH_OTP_LOCK_ALREADY;
   }
   
   /* Enter Lock Register Mode */
   BaseAddr[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
   BaseAddr[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
   BaseAddr[ADDR_UNLOCK_1] = CMD_LOCKREG_ENTRY;
   CELL = BaseAddr[0];
   CELL &= 0xFFFE;
   BaseAddr[0] = CMD_LOCKREG_PROG;
   BaseAddr[0] = CELL;
   DelayAWhile_AMD();    
   
   /* check till ready */
   while( (status = OTPCheckWriteReady_AMD((kal_uint32)BaseAddr ,(kal_uint16) CELL)) != OTP_ERR_NONE)
   {
      if (status == OTP_ERR_WAIT)
      {
         BaseAddr[0] = CMD_RESET;
         /* Enable Interrupt */    
         RestoreIRQMask(savedMask);
         ASSERT(0);
      }
   }
   
   BaseAddr[0] = CMD_LOCKREG_EXIT1;
   BaseAddr[0] = CMD_LOCKREG_EXIT2;
      
   /* Enable Interrupt */    
   RestoreIRQMask(savedMask);
         
   return FS_NO_ERROR;
}

kal_int32 
OTPAccess_AMD(void * DriveData, kal_int32 accesstype, kal_uint32 Offset, void * BufferPtr, kal_uint32 Length)
{
   if (accesstype==FS_OTP_READ)
   {
      return OTPRead_AMD(DriveData, Offset, BufferPtr,Length);
   }
   else if (accesstype==FS_OTP_WRITE)
   {
      return OTPWrite_AMD(DriveData,Offset,BufferPtr,Length);
   }
   else if (accesstype==FS_OTP_LOCK)
   {
      return OTPLock_AMD(DriveData);
   }
   else
   {
      ASSERT(0);
   }
}

kal_int32   
OTPQueryLength_AMD(void * DriveData, UINT *LengthPtr)
{
   *LengthPtr = NOR_OTPLength;
   return FS_NO_ERROR;
}

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

# endif /*__SECURITY_OTP__*/

/*-----------------------------------*/
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,
   NULL,
#ifdef __SECURITY_OTP__
   OTPAccess_AMD,
   OTPQueryLength_AMD
#else
   NULL,
   NULL
#endif
};

#endif //__AMD_SERIES_NOR__

⌨️ 快捷键说明

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