STM32F439xx HAL User Manual
stm32f4xx_hal_nor.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_nor.c
00004   * @author  MCD Application Team
00005   * @brief   NOR HAL module driver.
00006   *          This file provides a generic firmware to drive NOR memories mounted 
00007   *          as external device.
00008   *         
00009   @verbatim
00010   ==============================================================================
00011                      ##### How to use this driver #####
00012   ==============================================================================       
00013     [..]
00014       This driver is a generic layered driver which contains a set of APIs used to 
00015       control NOR flash memories. It uses the FMC/FSMC layer functions to interface 
00016       with NOR devices. This driver is used as follows:
00017     
00018       (+) NOR flash memory configuration sequence using the function HAL_NOR_Init() 
00019           with control and timing parameters for both normal and extended mode.
00020             
00021       (+) Read NOR flash memory manufacturer code and device IDs using the function
00022           HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef 
00023           structure declared by the function caller. 
00024         
00025       (+) Access NOR flash memory by read/write data unit operations using the functions
00026           HAL_NOR_Read(), HAL_NOR_Program().
00027         
00028       (+) Perform NOR flash erase block/chip operations using the functions 
00029           HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
00030         
00031       (+) Read the NOR flash CFI (common flash interface) IDs using the function
00032           HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
00033           structure declared by the function caller.
00034         
00035       (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
00036           HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation  
00037        
00038       (+) You can monitor the NOR device HAL state by calling the function
00039           HAL_NOR_GetState() 
00040     [..]
00041      (@) This driver is a set of generic APIs which handle standard NOR flash operations.
00042          If a NOR flash device contains different operations and/or implementations, 
00043          it should be implemented separately.
00044 
00045      *** NOR HAL driver macros list ***
00046      ============================================= 
00047      [..]
00048        Below the list of most used macros in NOR HAL driver.
00049        
00050       (+) NOR_WRITE : NOR memory write data to specified address
00051 
00052   @endverbatim
00053   ******************************************************************************
00054   * @attention
00055   *
00056   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00057   *
00058   * Redistribution and use in source and binary forms, with or without modification,
00059   * are permitted provided that the following conditions are met:
00060   *   1. Redistributions of source code must retain the above copyright notice,
00061   *      this list of conditions and the following disclaimer.
00062   *   2. Redistributions in binary form must reproduce the above copyright notice,
00063   *      this list of conditions and the following disclaimer in the documentation
00064   *      and/or other materials provided with the distribution.
00065   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00066   *      may be used to endorse or promote products derived from this software
00067   *      without specific prior written permission.
00068   *
00069   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00070   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00071   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00072   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00073   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00074   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00075   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00076   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00077   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00078   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00079   *
00080   ******************************************************************************
00081   */ 
00082 
00083 /* Includes ------------------------------------------------------------------*/
00084 #include "stm32f4xx_hal.h"
00085 
00086 /** @addtogroup STM32F4xx_HAL_Driver
00087   * @{
00088   */
00089 
00090 /** @defgroup NOR NOR
00091   * @brief NOR driver modules
00092   * @{
00093   */
00094 #ifdef HAL_NOR_MODULE_ENABLED
00095 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
00096     defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
00097     defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
00098     defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F413xx) || defined(STM32F423xx)
00099 /* Private typedef -----------------------------------------------------------*/
00100 /* Private define ------------------------------------------------------------*/
00101       
00102 /** @defgroup NOR_Private_Defines NOR Private Defines
00103   * @{
00104   */
00105 
00106 /* Constants to define address to set to write a command */
00107 #define NOR_CMD_ADDRESS_FIRST                 (uint16_t)0x0555
00108 #define NOR_CMD_ADDRESS_FIRST_CFI             (uint16_t)0x0055
00109 #define NOR_CMD_ADDRESS_SECOND                (uint16_t)0x02AA
00110 #define NOR_CMD_ADDRESS_THIRD                 (uint16_t)0x0555
00111 #define NOR_CMD_ADDRESS_FOURTH                (uint16_t)0x0555
00112 #define NOR_CMD_ADDRESS_FIFTH                 (uint16_t)0x02AA
00113 #define NOR_CMD_ADDRESS_SIXTH                 (uint16_t)0x0555
00114 
00115 /* Constants to define data to program a command */
00116 #define NOR_CMD_DATA_READ_RESET               (uint16_t)0x00F0
00117 #define NOR_CMD_DATA_FIRST                    (uint16_t)0x00AA
00118 #define NOR_CMD_DATA_SECOND                   (uint16_t)0x0055
00119 #define NOR_CMD_DATA_AUTO_SELECT              (uint16_t)0x0090
00120 #define NOR_CMD_DATA_PROGRAM                  (uint16_t)0x00A0
00121 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD   (uint16_t)0x0080
00122 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH  (uint16_t)0x00AA
00123 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH   (uint16_t)0x0055
00124 #define NOR_CMD_DATA_CHIP_ERASE               (uint16_t)0x0010
00125 #define NOR_CMD_DATA_CFI                      (uint16_t)0x0098
00126 
00127 #define NOR_CMD_DATA_BUFFER_AND_PROG          (uint8_t)0x25
00128 #define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM  (uint8_t)0x29
00129 #define NOR_CMD_DATA_BLOCK_ERASE              (uint8_t)0x30
00130 
00131 /* Mask on NOR STATUS REGISTER */
00132 #define NOR_MASK_STATUS_DQ5                   (uint16_t)0x0020
00133 #define NOR_MASK_STATUS_DQ6                   (uint16_t)0x0040
00134 
00135 /**
00136   * @}
00137   */
00138       
00139 /* Private macro -------------------------------------------------------------*/
00140 /* Private variables ---------------------------------------------------------*/
00141 /** @defgroup NOR_Private_Variables NOR Private Variables
00142   * @{
00143   */
00144 
00145 static uint32_t uwNORMemoryDataWidth  = NOR_MEMORY_8B;
00146 
00147 /**
00148   * @}
00149   */
00150 
00151 /* Private functions ---------------------------------------------------------*/
00152 /* Exported functions --------------------------------------------------------*/
00153 /** @defgroup NOR_Exported_Functions NOR Exported Functions
00154   * @{
00155   */
00156 
00157 /** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions 
00158   * @brief    Initialization and Configuration functions 
00159   *
00160   @verbatim    
00161   ==============================================================================
00162            ##### NOR Initialization and de_initialization functions #####
00163   ==============================================================================
00164   [..]  
00165     This section provides functions allowing to initialize/de-initialize
00166     the NOR memory
00167   
00168 @endverbatim
00169   * @{
00170   */
00171     
00172 /**
00173   * @brief  Perform the NOR memory Initialization sequence
00174   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00175   *                the configuration information for NOR module.
00176   * @param  Timing pointer to NOR control timing structure 
00177   * @param  ExtTiming pointer to NOR extended mode timing structure    
00178   * @retval HAL status
00179   */
00180 HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming)
00181 {
00182   /* Check the NOR handle parameter */
00183   if(hnor == NULL)
00184   {
00185      return HAL_ERROR;
00186   }
00187   
00188   if(hnor->State == HAL_NOR_STATE_RESET)
00189   {
00190     /* Allocate lock resource and initialize it */
00191     hnor->Lock = HAL_UNLOCKED;
00192     /* Initialize the low level hardware (MSP) */
00193     HAL_NOR_MspInit(hnor);
00194   }
00195   
00196   /* Initialize NOR control Interface */
00197   FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
00198 
00199   /* Initialize NOR timing Interface */
00200   FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank); 
00201 
00202   /* Initialize NOR extended mode timing Interface */
00203   FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
00204 
00205   /* Enable the NORSRAM device */
00206   __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
00207 
00208   /* Initialize NOR Memory Data Width*/
00209   if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8)
00210   {
00211     uwNORMemoryDataWidth = NOR_MEMORY_8B;
00212   }
00213   else
00214   {
00215     uwNORMemoryDataWidth = NOR_MEMORY_16B;
00216   }
00217 
00218   /* Check the NOR controller state */
00219   hnor->State = HAL_NOR_STATE_READY; 
00220   
00221   return HAL_OK;
00222 }
00223 
00224 /**
00225   * @brief  Perform NOR memory De-Initialization sequence
00226   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00227   *                the configuration information for NOR module.
00228   * @retval HAL status
00229   */
00230 HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)  
00231 {
00232   /* De-Initialize the low level hardware (MSP) */
00233   HAL_NOR_MspDeInit(hnor);
00234  
00235   /* Configure the NOR registers with their reset values */
00236   FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
00237   
00238   /* Update the NOR controller state */
00239   hnor->State = HAL_NOR_STATE_RESET;
00240 
00241   /* Release Lock */
00242   __HAL_UNLOCK(hnor);
00243 
00244   return HAL_OK;
00245 }
00246 
00247 /**
00248   * @brief  NOR MSP Init
00249   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00250   *                the configuration information for NOR module.
00251   * @retval None
00252   */
00253 __weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
00254 {
00255   /* Prevent unused argument(s) compilation warning */
00256   UNUSED(hnor);
00257   /* NOTE : This function Should not be modified, when the callback is needed,
00258             the HAL_NOR_MspInit could be implemented in the user file
00259    */ 
00260 }
00261 
00262 /**
00263   * @brief  NOR MSP DeInit
00264   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00265   *                the configuration information for NOR module.
00266   * @retval None
00267   */
00268 __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
00269 {
00270   /* Prevent unused argument(s) compilation warning */
00271   UNUSED(hnor);
00272   /* NOTE : This function Should not be modified, when the callback is needed,
00273             the HAL_NOR_MspDeInit could be implemented in the user file
00274    */ 
00275 }
00276 
00277 /**
00278   * @brief  NOR MSP Wait for Ready/Busy signal
00279   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00280   *                the configuration information for NOR module.
00281   * @param  Timeout Maximum timeout value
00282   * @retval None
00283   */
00284 __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
00285 {
00286   /* Prevent unused argument(s) compilation warning */
00287   UNUSED(hnor);
00288   UNUSED(Timeout);
00289   
00290   /* NOTE : This function Should not be modified, when the callback is needed,
00291             the HAL_NOR_MspWait could be implemented in the user file
00292    */ 
00293 }
00294   
00295 /**
00296   * @}
00297   */
00298 
00299 /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions 
00300   * @brief    Input Output and memory control functions 
00301   *
00302   @verbatim    
00303   ==============================================================================
00304                 ##### NOR Input and Output functions #####
00305   ==============================================================================
00306   [..]  
00307     This section provides functions allowing to use and control the NOR memory
00308   
00309 @endverbatim
00310   * @{
00311   */
00312   
00313 /**
00314   * @brief  Read NOR flash IDs
00315   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00316   *                the configuration information for NOR module.
00317   * @param  pNOR_ID  pointer to NOR ID structure
00318   * @retval HAL status
00319   */
00320 HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
00321 {
00322   uint32_t deviceaddress = 0U;
00323   
00324   /* Process Locked */
00325   __HAL_LOCK(hnor);
00326   
00327   /* Check the NOR controller state */
00328   if(hnor->State == HAL_NOR_STATE_BUSY)
00329   {
00330      return HAL_BUSY;
00331   }
00332   
00333   /* Select the NOR device address */
00334   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00335   {
00336     deviceaddress = NOR_MEMORY_ADRESS1;
00337   }
00338   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00339   {
00340     deviceaddress = NOR_MEMORY_ADRESS2;
00341   }
00342   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00343   {
00344     deviceaddress = NOR_MEMORY_ADRESS3;
00345   }
00346   else /* FMC_NORSRAM_BANK4 */
00347   {
00348     deviceaddress = NOR_MEMORY_ADRESS4;
00349   }  
00350     
00351   /* Update the NOR controller state */
00352   hnor->State = HAL_NOR_STATE_BUSY;
00353   
00354   /* Send read ID command */
00355   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00356   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00357   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
00358 
00359   /* Read the NOR IDs */
00360   pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
00361   pNOR_ID->Device_Code1      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR);
00362   pNOR_ID->Device_Code2      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR);
00363   pNOR_ID->Device_Code3      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR);
00364   
00365   /* Check the NOR controller state */
00366   hnor->State = HAL_NOR_STATE_READY;
00367   
00368   /* Process unlocked */
00369   __HAL_UNLOCK(hnor);   
00370   
00371   return HAL_OK;
00372 }
00373 
00374 /**
00375   * @brief  Returns the NOR memory to Read mode.
00376   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00377   *                the configuration information for NOR module.
00378   * @retval HAL status
00379   */
00380 HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
00381 {
00382   uint32_t deviceaddress = 0U;  
00383   
00384   /* Process Locked */
00385   __HAL_LOCK(hnor);
00386   
00387   /* Check the NOR controller state */
00388   if(hnor->State == HAL_NOR_STATE_BUSY)
00389   {
00390      return HAL_BUSY;
00391   }
00392   
00393   /* Select the NOR device address */
00394   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00395   {
00396     deviceaddress = NOR_MEMORY_ADRESS1;
00397   }
00398   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00399   {
00400     deviceaddress = NOR_MEMORY_ADRESS2;
00401   }
00402   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00403   {
00404     deviceaddress = NOR_MEMORY_ADRESS3;
00405   }
00406   else /* FMC_NORSRAM_BANK4 */
00407   {
00408     deviceaddress = NOR_MEMORY_ADRESS4;
00409   }  
00410   
00411   NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
00412 
00413   /* Check the NOR controller state */
00414   hnor->State = HAL_NOR_STATE_READY;
00415   
00416   /* Process unlocked */
00417   __HAL_UNLOCK(hnor);   
00418   
00419   return HAL_OK;
00420 }
00421 
00422 /**
00423   * @brief  Read data from NOR memory 
00424   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00425   *                the configuration information for NOR module.
00426   * @param  pAddress pointer to Device address
00427   * @param  pData  pointer to read data  
00428   * @retval HAL status
00429   */
00430 HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00431 {
00432   uint32_t deviceaddress = 0U;
00433   
00434   /* Process Locked */
00435   __HAL_LOCK(hnor);
00436   
00437   /* Check the NOR controller state */
00438   if(hnor->State == HAL_NOR_STATE_BUSY)
00439   {
00440      return HAL_BUSY;
00441   }
00442   
00443   /* Select the NOR device address */
00444   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00445   {
00446     deviceaddress = NOR_MEMORY_ADRESS1;
00447   }
00448   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00449   {
00450     deviceaddress = NOR_MEMORY_ADRESS2;
00451   }
00452   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00453   {
00454     deviceaddress = NOR_MEMORY_ADRESS3;
00455   }
00456   else /* FMC_NORSRAM_BANK4 */
00457   {
00458     deviceaddress = NOR_MEMORY_ADRESS4;
00459   } 
00460     
00461   /* Update the NOR controller state */
00462   hnor->State = HAL_NOR_STATE_BUSY;
00463   
00464   /* Send read data command */
00465   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 
00466   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);  
00467   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00468 
00469   /* Read the data */
00470   *pData = *(__IO uint32_t *)(uint32_t)pAddress;
00471   
00472   /* Check the NOR controller state */
00473   hnor->State = HAL_NOR_STATE_READY;
00474   
00475   /* Process unlocked */
00476   __HAL_UNLOCK(hnor);
00477   
00478   return HAL_OK;  
00479 }
00480 
00481 /**
00482   * @brief  Program data to NOR memory 
00483   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00484   *                the configuration information for NOR module.
00485   * @param  pAddress Device address
00486   * @param  pData  pointer to the data to write   
00487   * @retval HAL status
00488   */
00489 HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00490 {
00491   uint32_t deviceaddress = 0U;
00492   
00493   /* Process Locked */
00494   __HAL_LOCK(hnor);
00495   
00496   /* Check the NOR controller state */
00497   if(hnor->State == HAL_NOR_STATE_BUSY)
00498   {
00499      return HAL_BUSY;
00500   }
00501   
00502   /* Select the NOR device address */
00503   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00504   {
00505     deviceaddress = NOR_MEMORY_ADRESS1;
00506   }
00507   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00508   {
00509     deviceaddress = NOR_MEMORY_ADRESS2;
00510   }
00511   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00512   {
00513     deviceaddress = NOR_MEMORY_ADRESS3;
00514   }
00515   else /* FMC_NORSRAM_BANK4 */
00516   {
00517     deviceaddress = NOR_MEMORY_ADRESS4;
00518   } 
00519     
00520   /* Update the NOR controller state */
00521   hnor->State = HAL_NOR_STATE_BUSY;
00522   
00523   /* Send program data command */
00524   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00525   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00526   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
00527 
00528   /* Write the data */
00529   NOR_WRITE(pAddress, *pData);
00530   
00531   /* Check the NOR controller state */
00532   hnor->State = HAL_NOR_STATE_READY;
00533   
00534   /* Process unlocked */
00535   __HAL_UNLOCK(hnor);
00536   
00537   return HAL_OK;  
00538 }
00539 
00540 /**
00541   * @brief  Reads a half-word buffer from the NOR memory.
00542   * @param  hnor pointer to the NOR handle
00543   * @param  uwAddress NOR memory internal address to read from.
00544   * @param  pData pointer to the buffer that receives the data read from the 
00545   *         NOR memory.
00546   * @param  uwBufferSize  number of Half word to read.
00547   * @retval HAL status
00548   */
00549 HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
00550 {
00551   uint32_t deviceaddress = 0U;
00552   
00553   /* Process Locked */
00554   __HAL_LOCK(hnor);
00555   
00556   /* Check the NOR controller state */
00557   if(hnor->State == HAL_NOR_STATE_BUSY)
00558   {
00559      return HAL_BUSY;
00560   }
00561   
00562   /* Select the NOR device address */
00563   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00564   {
00565     deviceaddress = NOR_MEMORY_ADRESS1;
00566   }
00567   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00568   {
00569     deviceaddress = NOR_MEMORY_ADRESS2;
00570   }
00571   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00572   {
00573     deviceaddress = NOR_MEMORY_ADRESS3;
00574   }
00575   else /* FMC_NORSRAM_BANK4 */
00576   {
00577     deviceaddress = NOR_MEMORY_ADRESS4;
00578   }  
00579     
00580   /* Update the NOR controller state */
00581   hnor->State = HAL_NOR_STATE_BUSY;
00582   
00583   /* Send read data command */
00584   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 
00585   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);  
00586   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00587   
00588   /* Read buffer */
00589   while( uwBufferSize > 0U) 
00590   {
00591     *pData++ = *(__IO uint16_t *)uwAddress;
00592     uwAddress += 2U;
00593     uwBufferSize--;
00594   } 
00595   
00596   /* Check the NOR controller state */
00597   hnor->State = HAL_NOR_STATE_READY;
00598   
00599   /* Process unlocked */
00600   __HAL_UNLOCK(hnor);
00601   
00602   return HAL_OK;  
00603 }
00604 
00605 /**
00606   * @brief  Writes a half-word buffer to the NOR memory. This function must be used 
00607             only with S29GL128P NOR memory. 
00608   * @param  hnor pointer to the NOR handle
00609   * @param  uwAddress NOR memory internal start write address 
00610   * @param  pData pointer to source data buffer. 
00611   * @param  uwBufferSize Size of the buffer to write
00612   * @retval HAL status
00613   */ 
00614 HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
00615 {
00616   uint16_t * p_currentaddress = (uint16_t *)NULL;
00617   uint16_t * p_endaddress = (uint16_t *)NULL;
00618   uint32_t lastloadedaddress = 0U, deviceaddress = 0U;
00619   
00620   /* Process Locked */
00621   __HAL_LOCK(hnor);
00622   
00623   /* Check the NOR controller state */
00624   if(hnor->State == HAL_NOR_STATE_BUSY)
00625   {
00626      return HAL_BUSY;
00627   }
00628   
00629   /* Select the NOR device address */
00630   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00631   {
00632     deviceaddress = NOR_MEMORY_ADRESS1;
00633   }
00634   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00635   {
00636     deviceaddress = NOR_MEMORY_ADRESS2;
00637   }
00638   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00639   {
00640     deviceaddress = NOR_MEMORY_ADRESS3;
00641   }
00642   else /* FMC_NORSRAM_BANK4 */
00643   {
00644     deviceaddress = NOR_MEMORY_ADRESS4;
00645   }  
00646     
00647   /* Update the NOR controller state */
00648   hnor->State = HAL_NOR_STATE_BUSY;
00649   
00650   /* Initialize variables */
00651   p_currentaddress  = (uint16_t*)((uint32_t)(uwAddress));
00652   p_endaddress      = p_currentaddress + (uwBufferSize-1U);
00653   lastloadedaddress = (uint32_t)(uwAddress);
00654 
00655   /* Issue unlock command sequence */
00656   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00657   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 
00658 
00659   /* Write Buffer Load Command */
00660   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG); 
00661   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, uwAddress), (uwBufferSize - 1U)); 
00662 
00663   /* Load Data into NOR Buffer */
00664   while(p_currentaddress <= p_endaddress)
00665   {
00666     /* Store last loaded address & data value (for polling) */
00667      lastloadedaddress = (uint32_t)p_currentaddress;
00668  
00669     NOR_WRITE(p_currentaddress, *pData++);
00670     
00671     p_currentaddress ++; 
00672   }
00673 
00674   NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
00675   
00676   /* Check the NOR controller state */
00677   hnor->State = HAL_NOR_STATE_READY;
00678   
00679   /* Process unlocked */
00680   __HAL_UNLOCK(hnor);
00681   
00682   return HAL_OK; 
00683   
00684 }
00685 
00686 /**
00687   * @brief  Erase the specified block of the NOR memory 
00688   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00689   *                the configuration information for NOR module.
00690   * @param  BlockAddress  Block to erase address 
00691   * @param  Address Device address
00692   * @retval HAL status
00693   */
00694 HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
00695 {
00696   uint32_t deviceaddress = 0U;
00697 
00698   /* Process Locked */
00699   __HAL_LOCK(hnor);
00700   
00701   /* Check the NOR controller state */
00702   if(hnor->State == HAL_NOR_STATE_BUSY)
00703   {
00704      return HAL_BUSY;
00705   }
00706   
00707   /* Select the NOR device address */
00708   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00709   {
00710     deviceaddress = NOR_MEMORY_ADRESS1;
00711   }
00712   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00713   {
00714     deviceaddress = NOR_MEMORY_ADRESS2;
00715   }
00716   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00717   {
00718     deviceaddress = NOR_MEMORY_ADRESS3;
00719   }
00720   else /* FMC_NORSRAM_BANK4 */
00721   {
00722     deviceaddress = NOR_MEMORY_ADRESS4;
00723   }
00724     
00725   /* Update the NOR controller state */
00726   hnor->State = HAL_NOR_STATE_BUSY;
00727   
00728   /* Send block erase command sequence */
00729   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00730   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00731   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
00732   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
00733   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
00734   NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
00735 
00736   /* Check the NOR memory status and update the controller state */
00737   hnor->State = HAL_NOR_STATE_READY;
00738     
00739   /* Process unlocked */
00740   __HAL_UNLOCK(hnor);
00741   
00742   return HAL_OK;
00743  
00744 }
00745 
00746 /**
00747   * @brief  Erase the entire NOR chip.
00748   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00749   *                the configuration information for NOR module.
00750   * @param  Address  Device address  
00751   * @retval HAL status
00752   */
00753 HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
00754 {
00755   uint32_t deviceaddress = 0U;
00756   
00757   /* Prevent unused argument(s) compilation warning */
00758   UNUSED(Address);
00759   
00760   /* Process Locked */
00761   __HAL_LOCK(hnor);
00762   
00763   /* Check the NOR controller state */
00764   if(hnor->State == HAL_NOR_STATE_BUSY)
00765   {
00766      return HAL_BUSY;
00767   }
00768   
00769   /* Select the NOR device address */
00770   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00771   {
00772     deviceaddress = NOR_MEMORY_ADRESS1;
00773   }
00774   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00775   {
00776     deviceaddress = NOR_MEMORY_ADRESS2;
00777   }
00778   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00779   {
00780     deviceaddress = NOR_MEMORY_ADRESS3;
00781   }
00782   else /* FMC_NORSRAM_BANK4 */
00783   {
00784     deviceaddress = NOR_MEMORY_ADRESS4;
00785   }
00786     
00787   /* Update the NOR controller state */
00788   hnor->State = HAL_NOR_STATE_BUSY;  
00789     
00790   /* Send NOR chip erase command sequence */
00791   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00792   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00793   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
00794   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
00795   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);  
00796   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
00797   
00798   /* Check the NOR memory status and update the controller state */
00799   hnor->State = HAL_NOR_STATE_READY;
00800     
00801   /* Process unlocked */
00802   __HAL_UNLOCK(hnor);
00803   
00804   return HAL_OK;  
00805 }
00806 
00807 /**
00808   * @brief  Read NOR flash CFI IDs
00809   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00810   *                the configuration information for NOR module.
00811   * @param  pNOR_CFI  pointer to NOR CFI IDs structure  
00812   * @retval HAL status
00813   */
00814 HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
00815 {
00816   uint32_t deviceaddress = 0U;
00817   
00818   /* Process Locked */
00819   __HAL_LOCK(hnor);
00820   
00821   /* Check the NOR controller state */
00822   if(hnor->State == HAL_NOR_STATE_BUSY)
00823   {
00824      return HAL_BUSY;
00825   }
00826   
00827   /* Select the NOR device address */
00828   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00829   {
00830     deviceaddress = NOR_MEMORY_ADRESS1;
00831   }
00832   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00833   {
00834     deviceaddress = NOR_MEMORY_ADRESS2;
00835   }
00836   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00837   {
00838     deviceaddress = NOR_MEMORY_ADRESS3;
00839   }
00840   else /* FMC_NORSRAM_BANK4 */
00841   {
00842     deviceaddress = NOR_MEMORY_ADRESS4;
00843   }  
00844     
00845   /* Update the NOR controller state */
00846   hnor->State = HAL_NOR_STATE_BUSY;
00847   
00848   /* Send read CFI query command */
00849   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
00850 
00851   /* read the NOR CFI information */
00852   pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
00853   pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
00854   pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
00855   pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
00856 
00857   /* Check the NOR controller state */
00858   hnor->State = HAL_NOR_STATE_READY;
00859   
00860   /* Process unlocked */
00861   __HAL_UNLOCK(hnor);
00862   
00863   return HAL_OK;
00864 }
00865 
00866 /**
00867   * @}
00868   */
00869   
00870 /** @defgroup NOR_Exported_Functions_Group3 NOR Control functions
00871  *  @brief   management functions 
00872  *
00873 @verbatim   
00874   ==============================================================================
00875                         ##### NOR Control functions #####
00876   ==============================================================================
00877   [..]
00878     This subsection provides a set of functions allowing to control dynamically
00879     the NOR interface.
00880 
00881 @endverbatim
00882   * @{
00883   */
00884     
00885 /**
00886   * @brief  Enables dynamically NOR write operation.
00887   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00888   *                the configuration information for NOR module.
00889   * @retval HAL status
00890   */
00891 HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
00892 {
00893   /* Process Locked */
00894   __HAL_LOCK(hnor);
00895 
00896   /* Enable write operation */
00897   FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank); 
00898   
00899   /* Update the NOR controller state */
00900   hnor->State = HAL_NOR_STATE_READY;
00901   
00902   /* Process unlocked */
00903   __HAL_UNLOCK(hnor); 
00904   
00905   return HAL_OK;  
00906 }
00907 
00908 /**
00909   * @brief  Disables dynamically NOR write operation.
00910   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00911   *                the configuration information for NOR module.
00912   * @retval HAL status
00913   */
00914 HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
00915 {
00916   /* Process Locked */
00917   __HAL_LOCK(hnor);
00918 
00919   /* Update the SRAM controller state */
00920   hnor->State = HAL_NOR_STATE_BUSY;
00921     
00922   /* Disable write operation */
00923   FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); 
00924   
00925   /* Update the NOR controller state */
00926   hnor->State = HAL_NOR_STATE_PROTECTED;
00927   
00928   /* Process unlocked */
00929   __HAL_UNLOCK(hnor); 
00930   
00931   return HAL_OK;  
00932 }
00933 
00934 /**
00935   * @}
00936   */  
00937   
00938 /** @defgroup NOR_Exported_Functions_Group4 NOR State functions 
00939  *  @brief   Peripheral State functions 
00940  *
00941 @verbatim   
00942   ==============================================================================
00943                       ##### NOR State functions #####
00944   ==============================================================================  
00945   [..]
00946     This subsection permits to get in run-time the status of the NOR controller 
00947     and the data flow.
00948 
00949 @endverbatim
00950   * @{
00951   */
00952   
00953 /**
00954   * @brief  return the NOR controller state
00955   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00956   *                the configuration information for NOR module.
00957   * @retval NOR controller state
00958   */
00959 HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
00960 {
00961   return hnor->State;
00962 }
00963 
00964 /**
00965   * @brief  Returns the NOR operation status.
00966   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00967   *                the configuration information for NOR module.   
00968   * @param  Address Device address
00969   * @param  Timeout NOR programming Timeout
00970   * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
00971   *         or HAL_NOR_STATUS_TIMEOUT
00972   */
00973 HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
00974 { 
00975   HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
00976   uint16_t tmpSR1 = 0, tmpSR2 = 0;
00977   uint32_t tickstart = 0U;
00978 
00979   /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
00980   HAL_NOR_MspWait(hnor, Timeout);
00981   
00982   /* Get the NOR memory operation status -------------------------------------*/
00983   
00984   /* Get tick */
00985   tickstart = HAL_GetTick();
00986   while((status != HAL_NOR_STATUS_SUCCESS ) && (status != HAL_NOR_STATUS_TIMEOUT))
00987   {
00988     /* Check for the Timeout */
00989     if(Timeout != HAL_MAX_DELAY)
00990     {
00991       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00992       {
00993         status = HAL_NOR_STATUS_TIMEOUT; 
00994       } 
00995     } 
00996 
00997     /* Read NOR status register (DQ6 and DQ5) */
00998     tmpSR1 = *(__IO uint16_t *)Address;
00999     tmpSR2 = *(__IO uint16_t *)Address;
01000 
01001     /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01002     if((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) 
01003     {
01004       return HAL_NOR_STATUS_SUCCESS ;
01005     }
01006     
01007     if((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
01008     {
01009       status = HAL_NOR_STATUS_ONGOING;
01010     }
01011     
01012     tmpSR1 = *(__IO uint16_t *)Address;
01013     tmpSR2 = *(__IO uint16_t *)Address;
01014 
01015     /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01016     if((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) 
01017     {
01018       return HAL_NOR_STATUS_SUCCESS;
01019     }
01020     if((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
01021     {
01022       return HAL_NOR_STATUS_ERROR;
01023     } 
01024   }
01025 
01026   /* Return the operation status */
01027   return status;
01028 }
01029 
01030 /**
01031   * @}
01032   */
01033 
01034 /**
01035   * @}
01036   */
01037 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx ||\
01038           STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
01039           STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F413xx ||\
01040           STM32F423xx */
01041 #endif /* HAL_NOR_MODULE_ENABLED */
01042 /**
01043   * @}
01044   */
01045 
01046 /**
01047   * @}
01048   */
01049 
01050 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/