PDL for FM0+  Version1.0
Peripheral Driverl Library for FM0+
C:/pdl_v10/library/driver/flash/flash.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2013 Spansion LLC. All Rights Reserved. 
00003 *
00004 * This software is owned and published by: 
00005 * Spansion LLC, 915 DeGuigne Dr. Sunnyvale, CA  94088-3453 ("Spansion").
00006 *
00007 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND 
00008 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
00009 *
00010 * This software contains source code for use with Spansion 
00011 * components. This software is licensed by Spansion to be adapted only 
00012 * for use in systems utilizing Spansion components. Spansion shall not be 
00013 * responsible for misuse or illegal use of this software for devices not 
00014 * supported herein.  Spansion is providing this software "AS IS" and will 
00015 * not be responsible for issues arising from incorrect user implementation 
00016 * of the software.  
00017 *
00018 * SPANSION MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
00019 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS), 
00020 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING, 
00021 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED 
00022 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED 
00023 * WARRANTY OF NONINFRINGEMENT.  
00024 * SPANSION SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT, 
00025 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT 
00026 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, 
00027 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR 
00028 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT, 
00029 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA, 
00030 * SAVINGS OR PROFITS, 
00031 * EVEN IF SPANSION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
00032 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
00033 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED 
00034 * FROM, THE SOFTWARE.  
00035 *
00036 * This software may be replicated in part or whole for the licensed use, 
00037 * with the restriction that this Disclaimer and Copyright notice must be 
00038 * included with each copy of this software, whether used in part or whole, 
00039 * at all times.  
00040 */
00041 
00042 /******************************************************************************/
00052 /*---------------------------------------------------------------------------*/
00053 /* include files                                                             */
00054 /*---------------------------------------------------------------------------*/
00055 #include "flash.h"
00056 
00057 #if defined(PDL_PERIPHERAL_FLASH_ACTIVE) 
00058 
00065 #define Flash_Read(addr)        *(volatile uint16_t*)((uint32_t)(addr))
00066 
00074 #define Flash_Write(addr, data) *(volatile uint16_t*)((uint32_t)(addr)) = ( uint16_t)(data)
00075 
00076 /******************************************************************************/
00077 /* Local function prototypes ('static')                                       */
00078 /******************************************************************************/   
00079 #if defined ( __ICCARM__ )
00080 __ramfunc 
00081 #endif
00082 static uint8_t MFlash_CheckToggle( uint16_t* pAddr );
00083 
00084 #if defined ( __ICCARM__ )
00085 __ramfunc 
00086 #endif 
00087 static void MFlash_ReadResetCmd(uint16_t* pResetSecAddr);
00088 
00099 #if defined ( __ICCARM__ )
00100 __ramfunc 
00101 #endif 
00102 static void MFlash_ReadResetCmd(uint16_t* pu16ResetSecAddr)
00103 {
00104     uint8_t  u8Dummy;
00105 
00106     /*  issue read/reset command    */
00107     Flash_Write(0x0000, 0xF0U) ;
00108     u8Dummy = Flash_Read(pu16ResetSecAddr) ;
00109     if(u8Dummy)  /* avoid warning */  
00110         ;
00111     return ;
00112 }
00113 
00126 #if defined ( __ICCARM__ )
00127 __ramfunc 
00128 #endif 
00129 en_result_t MFlash_ChipErase(boolean_t bCrRemain)
00130 {
00131     uint8_t  u8Cnt;
00132     uint32_t u32CrData, u32CrAddr;
00133     uint16_t u16WriteData;
00134     en_result_t enRetValue = Ok;
00135     if(bCrRemain > 1)
00136     {
00137         enRetValue = ErrorInvalidParameter;
00138     }
00139     else
00140     {
00141         __disable_irq(); 
00142         /* Save CR value */
00143         if (bCrRemain == TRUE)
00144         {
00145             u32CrData = *(uint32_t*)CR_DATA_ADDR;
00146         }
00147 
00148         Flash_Write(MFLASH_CODE1, 0x00AA);
00149         Flash_Write(MFLASH_CODE2, 0x0055);
00150         Flash_Write(MFLASH_CODE1, 0x0080);
00151         Flash_Write(MFLASH_CODE1, 0x00AA);
00152         Flash_Write(MFLASH_CODE2, 0x0055);
00153         Flash_Write(MFLASH_CODE1, 0x0010);
00154 
00155          /*  if execution result of the automatic algorithm of flash memory is abnormally completed  */
00156         if( MFlash_CheckToggle((uint16_t*)0) == MFLASH_CHK_TOGG_ABNORMAL)
00157         {
00158             /*  sending the read/reset command to the reset sector  */
00159             MFlash_ReadResetCmd((uint16_t*)0) ;
00160 
00161             /*  return flash operation abnormally   */
00162             enRetValue  = Error ;
00163         }
00164 
00165         /* restore CR data in Flash */
00166         if (bCrRemain == TRUE)
00167         {
00168             for(u8Cnt=2,u16WriteData=(uint16_t)u32CrData, u32CrAddr = CR_DATA_ADDR;u8Cnt;u8Cnt--)
00169             {
00170                 /*  issue write command   */
00171                 Flash_Write(MFLASH_CODE1, 0x00AA) ;
00172                 Flash_Write(MFLASH_CODE2, 0x0055) ;
00173                 Flash_Write(MFLASH_CODE1, 0x00A0) ;
00174                 Flash_Write((uint16_t*)u32CrAddr, u16WriteData);
00175                 
00176                 /*  execution result of the automatic algorithm of flash memory is abnormally complete or verify error  */
00177                 if(( MFlash_CheckToggle((uint16_t*)u32CrAddr) == MFLASH_CHK_TOGG_ABNORMAL) ||
00178                   ( Flash_Read((uint16_t*)u32CrAddr) != u16WriteData))
00179                 {
00180                     /*  issue read/reset command to reset sector    */
00181                     MFlash_ReadResetCmd((uint16_t*)u32CrAddr) ;
00182         
00183                     /*  return flash operation abnormally   */
00184                     enRetValue  = Error ;
00185                     break;
00186                 }      
00187                 u16WriteData = (uint16_t)(u32CrData>>16);
00188                 u32CrAddr += 2;
00189             }
00190         }
00191                
00192         /* Recover IRQ  */
00193         __enable_irq();
00194     }
00195     return enRetValue;
00196 }
00197 
00209 #if defined ( __ICCARM__ )
00210 __ramfunc 
00211 #endif 
00212 en_result_t MFlash_SectorErase(uint16_t* pu16SecAddr)
00213 {
00214     en_result_t enRet = Ok;
00215 
00216     __disable_irq(); 
00217     Flash_Write(MFLASH_CODE1, 0x00AA);
00218     Flash_Write(MFLASH_CODE2, 0x0055);
00219     Flash_Write(MFLASH_CODE1, 0x0080);
00220     Flash_Write(MFLASH_CODE1, 0x00AA);
00221     Flash_Write(MFLASH_CODE2, 0x0055);
00222     Flash_Write(pu16SecAddr, 0x0030);
00223 
00224      /*  if execution result of the automatic algorithm of flash memory is abnormally completed  */
00225     if( MFlash_CheckToggle(pu16SecAddr) == MFLASH_CHK_TOGG_ABNORMAL)
00226     {
00227         /*  sending the read/reset command to the reset sector  */
00228         MFlash_ReadResetCmd(pu16SecAddr) ;
00229 
00230         /*  return flash operation abnormally   */
00231         enRet  = Error ;
00232     }
00233 
00234     /* Recover IRQ  */
00235     __enable_irq();
00236         
00237     return enRet;
00238 }
00239 
00253 #if defined ( __ICCARM__ )
00254 __ramfunc 
00255 #endif 
00256 en_result_t MFlash_Write(uint16_t*  pu16WriteAddr, 
00257                          uint16_t* pu16WriteData, 
00258                          uint32_t u32Size)
00259 {
00260     en_result_t  enRetValue  = Ok ;
00261     uint32_t   u32Cnt;
00262     
00263     __disable_irq(); 
00264   
00265     for(u32Cnt=u32Size;u32Cnt;u32Cnt--)
00266     {
00267         /*  issue write command   */
00268         Flash_Write(MFLASH_CODE1, 0x00AA) ;
00269         Flash_Write(MFLASH_CODE2, 0x0055) ;
00270         Flash_Write(MFLASH_CODE1, 0x00A0) ;
00271         Flash_Write(pu16WriteAddr, (uint16_t)*pu16WriteData);
00272         
00273         /*  execution result of the automatic algorithm of flash memory is abnormally complete or verify error  */
00274         if(( MFlash_CheckToggle(pu16WriteAddr) == MFLASH_CHK_TOGG_ABNORMAL) ||
00275           ( Flash_Read(pu16WriteAddr) != *pu16WriteData))
00276         {
00277             /*  issue read/reset command to reset sector    */
00278             MFlash_ReadResetCmd(pu16WriteAddr) ;
00279 
00280             /*  return flash operation abnormally   */
00281             enRetValue  = Error ;
00282         }      
00283         /* Prepare next h-word write */
00284         pu16WriteAddr++;
00285         pu16WriteData++; 
00286     }
00287     
00288     /* Recover IRQ  */
00289     __enable_irq();
00290 
00291 
00292     return enRetValue ;
00293 }
00294 
00307 #if defined ( __ICCARM__ )
00308 __ramfunc 
00309 #endif 
00310 static uint8_t MFlash_CheckToggle( uint16_t* pu16Addr )
00311 {
00312     uint16_t   u16SequenceFlag1, u16SequenceFlag2 ;  /*  hardware sequence flag */
00313     uint8_t   u8RetValue  = MFLASH_CHK_TOGG_NORMAL ;
00314 
00315     /* set hardware sequence flag */
00316     u16SequenceFlag1 = Flash_Read(pu16Addr) ;
00317     u16SequenceFlag2 = Flash_Read(pu16Addr) ;
00318     /*  if automatic algorithm is executing */
00319     while((( u16SequenceFlag1 ^ u16SequenceFlag2) & MFLASH_CHK_TOGG_MASK) == MFLASH_CHK_TOGG_MASK)
00320     {
00321         /*  if exceeds the timing limit */
00322         if(( u16SequenceFlag1 & MFLASH_CHK_TLOV_MASK) == MFLASH_CHK_TLOV_MASK)
00323         {
00324             /* set hardware sequence flag */
00325             u16SequenceFlag1 = Flash_Read(pu16Addr) ;
00326             u16SequenceFlag2 = Flash_Read(pu16Addr) ;
00327 
00328             /*  if automatic algorithm is executing */
00329             if((( u16SequenceFlag1 ^ u16SequenceFlag2) & MFLASH_CHK_TOGG_MASK) == MFLASH_CHK_TOGG_MASK)
00330             {
00331                 /*  abnormally complete */
00332                 u8RetValue  = MFLASH_CHK_TOGG_ABNORMAL ;
00333 
00334                 break;
00335             }
00336         }
00337 
00338         /* set hardware sequence flag */
00339         u16SequenceFlag1 = Flash_Read(pu16Addr) ;
00340         u16SequenceFlag2 = Flash_Read(pu16Addr) ;
00341     }
00342 
00343     return u8RetValue ;
00344 }
00345 
00346 #endif