STM32H735xx HAL User Manual
stm32h7xx_hal_nor.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_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   ******************************************************************************
00010   * @attention
00011   *
00012   * Copyright (c) 2017 STMicroelectronics.
00013   * All rights reserved.
00014   *
00015   * This software is licensed under terms that can be found in the LICENSE file
00016   * in the root directory of this software component.
00017   * If no LICENSE file comes with this software, it is provided AS-IS.
00018   *
00019   ******************************************************************************
00020   @verbatim
00021   ==============================================================================
00022                      ##### How to use this driver #####
00023   ==============================================================================
00024     [..]
00025       This driver is a generic layered driver which contains a set of APIs used to
00026       control NOR flash memories. It uses the FMC layer functions to interface
00027       with NOR devices. This driver is used as follows:
00028 
00029       (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
00030           with control and timing parameters for both normal and extended mode.
00031 
00032       (+) Read NOR flash memory manufacturer code and device IDs using the function
00033           HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
00034           structure declared by the function caller.
00035 
00036       (+) Access NOR flash memory by read/write data unit operations using the functions
00037           HAL_NOR_Read(), HAL_NOR_Program().
00038 
00039       (+) Perform NOR flash erase block/chip operations using the functions
00040           HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
00041 
00042       (+) Read the NOR flash CFI (common flash interface) IDs using the function
00043           HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
00044           structure declared by the function caller.
00045 
00046       (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
00047           HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation
00048 
00049       (+) You can monitor the NOR device HAL state by calling the function
00050           HAL_NOR_GetState()
00051     [..]
00052      (@) This driver is a set of generic APIs which handle standard NOR flash operations.
00053          If a NOR flash device contains different operations and/or implementations,
00054          it should be implemented separately.
00055 
00056      *** NOR HAL driver macros list ***
00057      =============================================
00058      [..]
00059        Below the list of most used macros in NOR HAL driver.
00060 
00061       (+) NOR_WRITE : NOR memory write data to specified address
00062 
00063     *** Callback registration ***
00064     =============================================
00065     [..]
00066       The compilation define  USE_HAL_NOR_REGISTER_CALLBACKS when set to 1
00067       allows the user to configure dynamically the driver callbacks.
00068 
00069       Use Functions HAL_NOR_RegisterCallback() to register a user callback,
00070       it allows to register following callbacks:
00071         (+) MspInitCallback    : NOR MspInit.
00072         (+) MspDeInitCallback  : NOR MspDeInit.
00073       This function takes as parameters the HAL peripheral handle, the Callback ID
00074       and a pointer to the user callback function.
00075 
00076       Use function HAL_NOR_UnRegisterCallback() to reset a callback to the default
00077       weak (surcharged) function. It allows to reset following callbacks:
00078         (+) MspInitCallback    : NOR MspInit.
00079         (+) MspDeInitCallback  : NOR MspDeInit.
00080       This function) takes as parameters the HAL peripheral handle and the Callback ID.
00081 
00082       By default, after the HAL_NOR_Init and if the state is HAL_NOR_STATE_RESET
00083       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00084       Exception done for MspInit and MspDeInit callbacks that are respectively
00085       reset to the legacy weak (surcharged) functions in the HAL_NOR_Init
00086       and  HAL_NOR_DeInit only when these callbacks are null (not registered beforehand).
00087       If not, MspInit or MspDeInit are not null, the HAL_NOR_Init and HAL_NOR_DeInit
00088       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00089 
00090       Callbacks can be registered/unregistered in READY state only.
00091       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00092       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00093       during the Init/DeInit.
00094       In that case first register the MspInit/MspDeInit user callbacks
00095       using HAL_NOR_RegisterCallback before calling HAL_NOR_DeInit
00096       or HAL_NOR_Init function.
00097 
00098       When The compilation define USE_HAL_NOR_REGISTER_CALLBACKS is set to 0 or
00099       not defined, the callback registering feature is not available
00100       and weak (surcharged) callbacks are used.
00101 
00102   @endverbatim
00103   ******************************************************************************
00104   */
00105 
00106 /* Includes ------------------------------------------------------------------*/
00107 #include "stm32h7xx_hal.h"
00108 
00109 
00110 /** @addtogroup STM32H7xx_HAL_Driver
00111   * @{
00112   */
00113 
00114 #ifdef HAL_NOR_MODULE_ENABLED
00115 
00116 /** @defgroup NOR NOR
00117   * @brief NOR driver modules
00118   * @{
00119   */
00120 
00121 /* Private typedef -----------------------------------------------------------*/
00122 /* Private define ------------------------------------------------------------*/
00123 
00124 /** @defgroup NOR_Private_Defines NOR Private Defines
00125   * @{
00126   */
00127 
00128 /* Constants to define address to set to write a command */
00129 #define NOR_CMD_ADDRESS_FIRST                 (uint16_t)0x0555
00130 #define NOR_CMD_ADDRESS_FIRST_CFI             (uint16_t)0x0055
00131 #define NOR_CMD_ADDRESS_SECOND                (uint16_t)0x02AA
00132 #define NOR_CMD_ADDRESS_THIRD                 (uint16_t)0x0555
00133 #define NOR_CMD_ADDRESS_FOURTH                (uint16_t)0x0555
00134 #define NOR_CMD_ADDRESS_FIFTH                 (uint16_t)0x02AA
00135 #define NOR_CMD_ADDRESS_SIXTH                 (uint16_t)0x0555
00136 
00137 /* Constants to define data to program a command */
00138 #define NOR_CMD_DATA_READ_RESET               (uint16_t)0x00F0
00139 #define NOR_CMD_DATA_FIRST                    (uint16_t)0x00AA
00140 #define NOR_CMD_DATA_SECOND                   (uint16_t)0x0055
00141 #define NOR_CMD_DATA_AUTO_SELECT              (uint16_t)0x0090
00142 #define NOR_CMD_DATA_PROGRAM                  (uint16_t)0x00A0
00143 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD   (uint16_t)0x0080
00144 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH  (uint16_t)0x00AA
00145 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH   (uint16_t)0x0055
00146 #define NOR_CMD_DATA_CHIP_ERASE               (uint16_t)0x0010
00147 #define NOR_CMD_DATA_CFI                      (uint16_t)0x0098
00148 
00149 #define NOR_CMD_DATA_BUFFER_AND_PROG          (uint8_t)0x25
00150 #define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM  (uint8_t)0x29
00151 #define NOR_CMD_DATA_BLOCK_ERASE              (uint8_t)0x30
00152 
00153 #define NOR_CMD_READ_ARRAY                    (uint16_t)0x00FF
00154 #define NOR_CMD_WORD_PROGRAM                  (uint16_t)0x0040
00155 #define NOR_CMD_BUFFERED_PROGRAM              (uint16_t)0x00E8
00156 #define NOR_CMD_CONFIRM                       (uint16_t)0x00D0
00157 #define NOR_CMD_BLOCK_ERASE                   (uint16_t)0x0020
00158 #define NOR_CMD_BLOCK_UNLOCK                  (uint16_t)0x0060
00159 #define NOR_CMD_READ_STATUS_REG               (uint16_t)0x0070
00160 #define NOR_CMD_CLEAR_STATUS_REG              (uint16_t)0x0050
00161 
00162 /* Mask on NOR STATUS REGISTER */
00163 #define NOR_MASK_STATUS_DQ4                   (uint16_t)0x0010
00164 #define NOR_MASK_STATUS_DQ5                   (uint16_t)0x0020
00165 #define NOR_MASK_STATUS_DQ6                   (uint16_t)0x0040
00166 #define NOR_MASK_STATUS_DQ7                   (uint16_t)0x0080
00167 
00168 /* Address of the primary command set */
00169 #define NOR_ADDRESS_COMMAND_SET               (uint16_t)0x0013
00170 
00171 /* Command set code assignment (defined in JEDEC JEP137B version may 2004) */
00172 #define NOR_INTEL_SHARP_EXT_COMMAND_SET       (uint16_t)0x0001 /* Supported in this driver */
00173 #define NOR_AMD_FUJITSU_COMMAND_SET           (uint16_t)0x0002 /* Supported in this driver */
00174 #define NOR_INTEL_STANDARD_COMMAND_SET        (uint16_t)0x0003 /* Not Supported in this driver */
00175 #define NOR_AMD_FUJITSU_EXT_COMMAND_SET       (uint16_t)0x0004 /* Not Supported in this driver */
00176 #define NOR_WINDBOND_STANDARD_COMMAND_SET     (uint16_t)0x0006 /* Not Supported in this driver */
00177 #define NOR_MITSUBISHI_STANDARD_COMMAND_SET   (uint16_t)0x0100 /* Not Supported in this driver */
00178 #define NOR_MITSUBISHI_EXT_COMMAND_SET        (uint16_t)0x0101 /* Not Supported in this driver */
00179 #define NOR_PAGE_WRITE_COMMAND_SET            (uint16_t)0x0102 /* Not Supported in this driver */
00180 #define NOR_INTEL_PERFORMANCE_COMMAND_SET     (uint16_t)0x0200 /* Not Supported in this driver */
00181 #define NOR_INTEL_DATA_COMMAND_SET            (uint16_t)0x0210 /* Not Supported in this driver */
00182 
00183 /**
00184   * @}
00185   */
00186 
00187 /* Private macro -------------------------------------------------------------*/
00188 /* Private variables ---------------------------------------------------------*/
00189 /** @defgroup NOR_Private_Variables NOR Private Variables
00190   * @{
00191   */
00192 
00193 static uint32_t uwNORMemoryDataWidth  = NOR_MEMORY_8B;
00194 
00195 /**
00196   * @}
00197   */
00198 
00199 /* Private functions ---------------------------------------------------------*/
00200 /* Exported functions --------------------------------------------------------*/
00201 /** @defgroup NOR_Exported_Functions NOR Exported Functions
00202   * @{
00203   */
00204 
00205 /** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
00206   * @brief    Initialization and Configuration functions
00207   *
00208   @verbatim
00209   ==============================================================================
00210            ##### NOR Initialization and de_initialization functions #####
00211   ==============================================================================
00212   [..]
00213     This section provides functions allowing to initialize/de-initialize
00214     the NOR memory
00215 
00216 @endverbatim
00217   * @{
00218   */
00219 
00220 /**
00221   * @brief  Perform the NOR memory Initialization sequence
00222   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00223   *                the configuration information for NOR module.
00224   * @param  Timing pointer to NOR control timing structure
00225   * @param  ExtTiming pointer to NOR extended mode timing structure
00226   * @retval HAL status
00227   */
00228 HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing,
00229                                FMC_NORSRAM_TimingTypeDef *ExtTiming)
00230 {
00231   uint32_t deviceaddress;
00232   HAL_StatusTypeDef status = HAL_OK;
00233 
00234   /* Check the NOR handle parameter */
00235   if (hnor == NULL)
00236   {
00237     return HAL_ERROR;
00238   }
00239 
00240   if (hnor->State == HAL_NOR_STATE_RESET)
00241   {
00242     /* Allocate lock resource and initialize it */
00243     hnor->Lock = HAL_UNLOCKED;
00244 
00245 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
00246     if (hnor->MspInitCallback == NULL)
00247     {
00248       hnor->MspInitCallback = HAL_NOR_MspInit;
00249     }
00250 
00251     /* Init the low level hardware */
00252     hnor->MspInitCallback(hnor);
00253 #else
00254     /* Initialize the low level hardware (MSP) */
00255     HAL_NOR_MspInit(hnor);
00256 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
00257   }
00258 
00259   /* Initialize NOR control Interface */
00260   (void)FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
00261 
00262   /* Initialize NOR timing Interface */
00263   (void)FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
00264 
00265   /* Initialize NOR extended mode timing Interface */
00266   (void)FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
00267 
00268   /* Enable the NORSRAM device */
00269   __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
00270 
00271   /* Initialize NOR Memory Data Width*/
00272   if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8)
00273   {
00274     uwNORMemoryDataWidth = NOR_MEMORY_8B;
00275   }
00276   else
00277   {
00278     uwNORMemoryDataWidth = NOR_MEMORY_16B;
00279   }
00280 
00281   /* Enable FMC Peripheral */
00282   __FMC_ENABLE();
00283 
00284   /* Initialize the NOR controller state */
00285   hnor->State = HAL_NOR_STATE_READY;
00286 
00287   /* Select the NOR device address */
00288   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00289   {
00290     deviceaddress = NOR_MEMORY_ADRESS1;
00291   }
00292   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00293   {
00294     deviceaddress = NOR_MEMORY_ADRESS2;
00295   }
00296   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00297   {
00298     deviceaddress = NOR_MEMORY_ADRESS3;
00299   }
00300   else /* FMC_NORSRAM_BANK4 */
00301   {
00302     deviceaddress = NOR_MEMORY_ADRESS4;
00303   }
00304 
00305   FMC_NORSRAM_WriteOperation_Enable(hnor->Instance,hnor->Init.NSBank);
00306   
00307   /* Get the value of the command set */
00308   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
00309   hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET);
00310   
00311   status = HAL_NOR_ReturnToReadMode(hnor);
00312 
00313   if (hnor->Init.WriteOperation == FMC_WRITE_OPERATION_DISABLE)
00314   {
00315     FMC_NORSRAM_WriteOperation_Disable(hnor->Instance,hnor->Init.NSBank);
00316 
00317     /* Update the NOR controller state */
00318     hnor->State = HAL_NOR_STATE_PROTECTED;
00319   }
00320 
00321   return status;
00322 }
00323 
00324 /**
00325   * @brief  Perform NOR memory De-Initialization sequence
00326   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00327   *                the configuration information for NOR module.
00328   * @retval HAL status
00329   */
00330 HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)
00331 {
00332 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
00333   if (hnor->MspDeInitCallback == NULL)
00334   {
00335     hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
00336   }
00337 
00338   /* DeInit the low level hardware */
00339   hnor->MspDeInitCallback(hnor);
00340 #else
00341   /* De-Initialize the low level hardware (MSP) */
00342   HAL_NOR_MspDeInit(hnor);
00343 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
00344 
00345   /* Configure the NOR registers with their reset values */
00346   (void)FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
00347 
00348   /* Reset the NOR controller state */
00349   hnor->State = HAL_NOR_STATE_RESET;
00350 
00351   /* Release Lock */
00352   __HAL_UNLOCK(hnor);
00353 
00354   return HAL_OK;
00355 }
00356 
00357 /**
00358   * @brief  NOR MSP Init
00359   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00360   *                the configuration information for NOR module.
00361   * @retval None
00362   */
00363 __weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
00364 {
00365   /* Prevent unused argument(s) compilation warning */
00366   UNUSED(hnor);
00367 
00368   /* NOTE : This function Should not be modified, when the callback is needed,
00369             the HAL_NOR_MspInit could be implemented in the user file
00370    */
00371 }
00372 
00373 /**
00374   * @brief  NOR MSP DeInit
00375   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00376   *                the configuration information for NOR module.
00377   * @retval None
00378   */
00379 __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
00380 {
00381   /* Prevent unused argument(s) compilation warning */
00382   UNUSED(hnor);
00383 
00384   /* NOTE : This function Should not be modified, when the callback is needed,
00385             the HAL_NOR_MspDeInit could be implemented in the user file
00386    */
00387 }
00388 
00389 /**
00390   * @brief  NOR MSP Wait for Ready/Busy signal
00391   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00392   *                the configuration information for NOR module.
00393   * @param  Timeout Maximum timeout value
00394   * @retval None
00395   */
00396 __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
00397 {
00398   /* Prevent unused argument(s) compilation warning */
00399   UNUSED(hnor);
00400   UNUSED(Timeout);
00401 
00402   /* NOTE : This function Should not be modified, when the callback is needed,
00403             the HAL_NOR_MspWait could be implemented in the user file
00404    */
00405 }
00406 
00407 /**
00408   * @}
00409   */
00410 
00411 /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
00412   * @brief    Input Output and memory control functions
00413   *
00414   @verbatim
00415   ==============================================================================
00416                 ##### NOR Input and Output functions #####
00417   ==============================================================================
00418   [..]
00419     This section provides functions allowing to use and control the NOR memory
00420 
00421 @endverbatim
00422   * @{
00423   */
00424 
00425 /**
00426   * @brief  Read NOR flash IDs
00427   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00428   *                the configuration information for NOR module.
00429   * @param  pNOR_ID  pointer to NOR ID structure
00430   * @retval HAL status
00431   */
00432 HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
00433 {
00434   uint32_t deviceaddress;
00435   HAL_NOR_StateTypeDef state;
00436   HAL_StatusTypeDef status = HAL_OK;
00437 
00438   /* Check the NOR controller state */
00439   state = hnor->State;
00440   if (state == HAL_NOR_STATE_BUSY)
00441   {
00442     return HAL_BUSY;
00443   }
00444   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
00445   {
00446     /* Process Locked */
00447     __HAL_LOCK(hnor);
00448 
00449     /* Update the NOR controller state */
00450     hnor->State = HAL_NOR_STATE_BUSY;
00451 
00452     /* Select the NOR device address */
00453     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00454     {
00455       deviceaddress = NOR_MEMORY_ADRESS1;
00456     }
00457     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00458     {
00459       deviceaddress = NOR_MEMORY_ADRESS2;
00460     }
00461     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00462     {
00463       deviceaddress = NOR_MEMORY_ADRESS3;
00464     }
00465     else /* FMC_NORSRAM_BANK4 */
00466     {
00467       deviceaddress = NOR_MEMORY_ADRESS4;
00468     }
00469 
00470     /* Send read ID command */
00471     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00472     {
00473       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00474       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00475       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
00476     }
00477     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00478     {
00479       NOR_WRITE(deviceaddress, NOR_CMD_DATA_AUTO_SELECT);
00480     }
00481     else
00482     {
00483       /* Primary command set not supported by the driver */
00484       status = HAL_ERROR;
00485     }
00486 
00487     if (status != HAL_ERROR)
00488     {
00489       /* Read the NOR IDs */
00490       pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
00491       pNOR_ID->Device_Code1      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
00492                                                                      DEVICE_CODE1_ADDR);
00493       pNOR_ID->Device_Code2      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
00494                                                                      DEVICE_CODE2_ADDR);
00495       pNOR_ID->Device_Code3      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
00496                                                                      DEVICE_CODE3_ADDR);
00497     }
00498 
00499     /* Check the NOR controller state */
00500     hnor->State = state;
00501 
00502     /* Process unlocked */
00503     __HAL_UNLOCK(hnor);
00504   }
00505   else
00506   {
00507     return HAL_ERROR;
00508   }
00509 
00510   return status;
00511 }
00512 
00513 /**
00514   * @brief  Returns the NOR memory to Read mode.
00515   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00516   *                the configuration information for NOR module.
00517   * @retval HAL status
00518   */
00519 HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
00520 {
00521   uint32_t deviceaddress;
00522   HAL_NOR_StateTypeDef state;
00523   HAL_StatusTypeDef status = HAL_OK;
00524 
00525   /* Check the NOR controller state */
00526   state = hnor->State;
00527   if (state == HAL_NOR_STATE_BUSY)
00528   {
00529     return HAL_BUSY;
00530   }
00531   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
00532   {
00533     /* Process Locked */
00534     __HAL_LOCK(hnor);
00535 
00536     /* Update the NOR controller state */
00537     hnor->State = HAL_NOR_STATE_BUSY;
00538 
00539     /* Select the NOR device address */
00540     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00541     {
00542       deviceaddress = NOR_MEMORY_ADRESS1;
00543     }
00544     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00545     {
00546       deviceaddress = NOR_MEMORY_ADRESS2;
00547     }
00548     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00549     {
00550       deviceaddress = NOR_MEMORY_ADRESS3;
00551     }
00552     else /* FMC_NORSRAM_BANK4 */
00553     {
00554       deviceaddress = NOR_MEMORY_ADRESS4;
00555     }
00556 
00557     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00558     {
00559       NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
00560     }
00561     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00562     {
00563       NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
00564     }
00565     else
00566     {
00567       /* Primary command set not supported by the driver */
00568       status = HAL_ERROR;
00569     }
00570 
00571     /* Check the NOR controller state */
00572     hnor->State = state;
00573 
00574     /* Process unlocked */
00575     __HAL_UNLOCK(hnor);
00576   }
00577   else
00578   {
00579     return HAL_ERROR;
00580   }
00581 
00582   return status;
00583 }
00584 
00585 /**
00586   * @brief  Read data from NOR memory
00587   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00588   *                the configuration information for NOR module.
00589   * @param  pAddress pointer to Device address
00590   * @param  pData  pointer to read data
00591   * @retval HAL status
00592   */
00593 HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00594 {
00595   uint32_t deviceaddress;
00596   HAL_NOR_StateTypeDef state;
00597   HAL_StatusTypeDef status = HAL_OK;
00598 
00599   /* Check the NOR controller state */
00600   state = hnor->State;
00601   if (state == HAL_NOR_STATE_BUSY)
00602   {
00603     return HAL_BUSY;
00604   }
00605   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
00606   {
00607     /* Process Locked */
00608     __HAL_LOCK(hnor);
00609 
00610     /* Update the NOR controller state */
00611     hnor->State = HAL_NOR_STATE_BUSY;
00612 
00613     /* Select the NOR device address */
00614     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00615     {
00616       deviceaddress = NOR_MEMORY_ADRESS1;
00617     }
00618     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00619     {
00620       deviceaddress = NOR_MEMORY_ADRESS2;
00621     }
00622     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00623     {
00624       deviceaddress = NOR_MEMORY_ADRESS3;
00625     }
00626     else /* FMC_NORSRAM_BANK4 */
00627     {
00628       deviceaddress = NOR_MEMORY_ADRESS4;
00629     }
00630 
00631     /* Send read data command */
00632     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00633     {
00634       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00635       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00636       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00637     }
00638     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00639     {
00640       NOR_WRITE(pAddress, NOR_CMD_READ_ARRAY);
00641     }
00642     else
00643     {
00644       /* Primary command set not supported by the driver */
00645       status = HAL_ERROR;
00646     }
00647 
00648     if (status != HAL_ERROR)
00649     {
00650       /* Read the data */
00651       *pData = (uint16_t)(*(__IO uint32_t *)pAddress);
00652     }
00653 
00654     /* Check the NOR controller state */
00655     hnor->State = state;
00656 
00657     /* Process unlocked */
00658     __HAL_UNLOCK(hnor);
00659   }
00660   else
00661   {
00662     return HAL_ERROR;
00663   }
00664 
00665   return status;
00666 }
00667 
00668 /**
00669   * @brief  Program data to NOR memory
00670   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00671   *                the configuration information for NOR module.
00672   * @param  pAddress Device address
00673   * @param  pData  pointer to the data to write
00674   * @retval HAL status
00675   */
00676 HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00677 {
00678   uint32_t deviceaddress;
00679   HAL_StatusTypeDef status = HAL_OK;
00680 
00681   /* Check the NOR controller state */
00682   if (hnor->State == HAL_NOR_STATE_BUSY)
00683   {
00684     return HAL_BUSY;
00685   }
00686   else if (hnor->State == HAL_NOR_STATE_READY)
00687   {
00688     /* Process Locked */
00689     __HAL_LOCK(hnor);
00690 
00691     /* Update the NOR controller state */
00692     hnor->State = HAL_NOR_STATE_BUSY;
00693 
00694     /* Select the NOR device address */
00695     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00696     {
00697       deviceaddress = NOR_MEMORY_ADRESS1;
00698     }
00699     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00700     {
00701       deviceaddress = NOR_MEMORY_ADRESS2;
00702     }
00703     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00704     {
00705       deviceaddress = NOR_MEMORY_ADRESS3;
00706     }
00707     else /* FMC_NORSRAM_BANK4 */
00708     {
00709       deviceaddress = NOR_MEMORY_ADRESS4;
00710     }
00711 
00712     /* Send program data command */
00713     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00714     {
00715       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00716       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00717       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
00718     }
00719     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00720     {
00721       NOR_WRITE(pAddress, NOR_CMD_WORD_PROGRAM);
00722     }
00723     else
00724     {
00725       /* Primary command set not supported by the driver */
00726       status = HAL_ERROR;
00727     }
00728 
00729     if (status != HAL_ERROR)
00730     {
00731       /* Write the data */
00732       NOR_WRITE(pAddress, *pData);
00733     }
00734 
00735     /* Check the NOR controller state */
00736     hnor->State = HAL_NOR_STATE_READY;
00737 
00738     /* Process unlocked */
00739     __HAL_UNLOCK(hnor);
00740   }
00741   else
00742   {
00743     return HAL_ERROR;
00744   }
00745 
00746   return status;
00747 }
00748 
00749 /**
00750   * @brief  Reads a half-word buffer from the NOR memory.
00751   * @param  hnor pointer to the NOR handle
00752   * @param  uwAddress NOR memory internal address to read from.
00753   * @param  pData pointer to the buffer that receives the data read from the
00754   *         NOR memory.
00755   * @param  uwBufferSize  number of Half word to read.
00756   * @retval HAL status
00757   */
00758 HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
00759                                      uint32_t uwBufferSize)
00760 {
00761   uint32_t deviceaddress;
00762   uint32_t size = uwBufferSize;
00763   uint32_t address = uwAddress;
00764   uint16_t *data = pData;
00765   HAL_NOR_StateTypeDef state;
00766   HAL_StatusTypeDef status = HAL_OK;
00767 
00768   /* Check the NOR controller state */
00769   state = hnor->State;
00770   if (state == HAL_NOR_STATE_BUSY)
00771   {
00772     return HAL_BUSY;
00773   }
00774   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
00775   {
00776     /* Process Locked */
00777     __HAL_LOCK(hnor);
00778 
00779     /* Update the NOR controller state */
00780     hnor->State = HAL_NOR_STATE_BUSY;
00781 
00782     /* Select the NOR device address */
00783     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00784     {
00785       deviceaddress = NOR_MEMORY_ADRESS1;
00786     }
00787     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00788     {
00789       deviceaddress = NOR_MEMORY_ADRESS2;
00790     }
00791     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00792     {
00793       deviceaddress = NOR_MEMORY_ADRESS3;
00794     }
00795     else /* FMC_NORSRAM_BANK4 */
00796     {
00797       deviceaddress = NOR_MEMORY_ADRESS4;
00798     }
00799 
00800     /* Send read data command */
00801     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00802     {
00803       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00804       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00805       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00806     }
00807     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00808     {
00809       NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
00810     }
00811     else
00812     {
00813       /* Primary command set not supported by the driver */
00814       status = HAL_ERROR;
00815     }
00816 
00817     if (status != HAL_ERROR)
00818     {
00819       /* Read buffer */
00820       while (size > 0U)
00821       {
00822         *data = *(__IO uint16_t *)address;
00823         data++;
00824         address += 2U;
00825         size--;
00826       }
00827     }
00828 
00829     /* Check the NOR controller state */
00830     hnor->State = state;
00831 
00832     /* Process unlocked */
00833     __HAL_UNLOCK(hnor);
00834   }
00835   else
00836   {
00837     return HAL_ERROR;
00838   }
00839 
00840   return status;
00841 }
00842 
00843 /**
00844   * @brief  Writes a half-word buffer to the NOR memory. This function must be used
00845             only with S29GL128P NOR memory.
00846   * @param  hnor pointer to the NOR handle
00847   * @param  uwAddress NOR memory internal start write address
00848   * @param  pData pointer to source data buffer.
00849   * @param  uwBufferSize Size of the buffer to write
00850   * @retval HAL status
00851   */
00852 HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
00853                                         uint32_t uwBufferSize)
00854 {
00855   uint16_t *p_currentaddress;
00856   const uint16_t *p_endaddress;
00857   uint16_t *data = pData;
00858   uint32_t deviceaddress;
00859   HAL_StatusTypeDef status = HAL_OK;
00860 
00861   /* Check the NOR controller state */
00862   if (hnor->State == HAL_NOR_STATE_BUSY)
00863   {
00864     return HAL_BUSY;
00865   }
00866   else if (hnor->State == HAL_NOR_STATE_READY)
00867   {
00868     /* Process Locked */
00869     __HAL_LOCK(hnor);
00870 
00871     /* Update the NOR controller state */
00872     hnor->State = HAL_NOR_STATE_BUSY;
00873 
00874     /* Select the NOR device address */
00875     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00876     {
00877       deviceaddress = NOR_MEMORY_ADRESS1;
00878     }
00879     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00880     {
00881       deviceaddress = NOR_MEMORY_ADRESS2;
00882     }
00883     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00884     {
00885       deviceaddress = NOR_MEMORY_ADRESS3;
00886     }
00887     else /* FMC_NORSRAM_BANK4 */
00888     {
00889       deviceaddress = NOR_MEMORY_ADRESS4;
00890     }
00891 
00892     /* Initialize variables */
00893     p_currentaddress  = (uint16_t *)(deviceaddress + uwAddress);
00894     p_endaddress      = (uint16_t *)(deviceaddress + uwAddress + (2U * (uwBufferSize - 1U)));
00895 
00896     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00897     {
00898       /* Issue unlock command sequence */
00899       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00900       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00901 
00902       /* Write Buffer Load Command */
00903       NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG);
00904       NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
00905     }
00906     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
00907     {
00908       /* Write Buffer Load Command */
00909       NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_BUFFERED_PROGRAM);
00910       NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
00911     }
00912     else
00913     {
00914       /* Primary command set not supported by the driver */
00915       status = HAL_ERROR;
00916     }
00917 
00918     if (status != HAL_ERROR)
00919     {
00920       /* Load Data into NOR Buffer */
00921       while (p_currentaddress <= p_endaddress)
00922       {
00923         NOR_WRITE(p_currentaddress, *data);
00924 
00925         data++;
00926         p_currentaddress ++;
00927       }
00928 
00929       if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
00930       {
00931         NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
00932       }
00933       else /* => hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET */
00934       {
00935         NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_CONFIRM);
00936       }
00937     }
00938 
00939     /* Check the NOR controller state */
00940     hnor->State = HAL_NOR_STATE_READY;
00941 
00942     /* Process unlocked */
00943     __HAL_UNLOCK(hnor);
00944   }
00945   else
00946   {
00947     return HAL_ERROR;
00948   }
00949 
00950   return status;
00951 
00952 }
00953 
00954 /**
00955   * @brief  Erase the specified block of the NOR memory
00956   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00957   *                the configuration information for NOR module.
00958   * @param  BlockAddress  Block to erase address
00959   * @param  Address Device address
00960   * @retval HAL status
00961   */
00962 HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
00963 {
00964   uint32_t deviceaddress;
00965   HAL_StatusTypeDef status = HAL_OK;
00966 
00967   /* Check the NOR controller state */
00968   if (hnor->State == HAL_NOR_STATE_BUSY)
00969   {
00970     return HAL_BUSY;
00971   }
00972   else if (hnor->State == HAL_NOR_STATE_READY)
00973   {
00974     /* Process Locked */
00975     __HAL_LOCK(hnor);
00976 
00977     /* Update the NOR controller state */
00978     hnor->State = HAL_NOR_STATE_BUSY;
00979 
00980     /* Select the NOR device address */
00981     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00982     {
00983       deviceaddress = NOR_MEMORY_ADRESS1;
00984     }
00985     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00986     {
00987       deviceaddress = NOR_MEMORY_ADRESS2;
00988     }
00989     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00990     {
00991       deviceaddress = NOR_MEMORY_ADRESS3;
00992     }
00993     else /* FMC_NORSRAM_BANK4 */
00994     {
00995       deviceaddress = NOR_MEMORY_ADRESS4;
00996     }
00997 
00998     /* Send block erase command sequence */
00999     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
01000     {
01001       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
01002       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
01003       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
01004                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
01005       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
01006                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
01007       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
01008                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
01009       NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
01010     }
01011     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
01012     {
01013       NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_UNLOCK);
01014       NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
01015       NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_ERASE);
01016       NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
01017     }
01018     else
01019     {
01020       /* Primary command set not supported by the driver */
01021       status = HAL_ERROR;
01022     }
01023 
01024     /* Check the NOR memory status and update the controller state */
01025     hnor->State = HAL_NOR_STATE_READY;
01026 
01027     /* Process unlocked */
01028     __HAL_UNLOCK(hnor);
01029   }
01030   else
01031   {
01032     return HAL_ERROR;
01033   }
01034 
01035   return status;
01036 
01037 }
01038 
01039 /**
01040   * @brief  Erase the entire NOR chip.
01041   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01042   *                the configuration information for NOR module.
01043   * @param  Address  Device address
01044   * @retval HAL status
01045   */
01046 HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
01047 {
01048   uint32_t deviceaddress;
01049   HAL_StatusTypeDef status = HAL_OK;
01050   UNUSED(Address);
01051 
01052   /* Check the NOR controller state */
01053   if (hnor->State == HAL_NOR_STATE_BUSY)
01054   {
01055     return HAL_BUSY;
01056   }
01057   else if (hnor->State == HAL_NOR_STATE_READY)
01058   {
01059     /* Process Locked */
01060     __HAL_LOCK(hnor);
01061 
01062     /* Update the NOR controller state */
01063     hnor->State = HAL_NOR_STATE_BUSY;
01064 
01065     /* Select the NOR device address */
01066     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
01067     {
01068       deviceaddress = NOR_MEMORY_ADRESS1;
01069     }
01070     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
01071     {
01072       deviceaddress = NOR_MEMORY_ADRESS2;
01073     }
01074     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
01075     {
01076       deviceaddress = NOR_MEMORY_ADRESS3;
01077     }
01078     else /* FMC_NORSRAM_BANK4 */
01079     {
01080       deviceaddress = NOR_MEMORY_ADRESS4;
01081     }
01082 
01083     /* Send NOR chip erase command sequence */
01084     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
01085     {
01086       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
01087       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
01088       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
01089                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
01090       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
01091                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
01092       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
01093                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
01094       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
01095     }
01096     else
01097     {
01098       /* Primary command set not supported by the driver */
01099       status = HAL_ERROR;
01100     }
01101 
01102     /* Check the NOR memory status and update the controller state */
01103     hnor->State = HAL_NOR_STATE_READY;
01104 
01105     /* Process unlocked */
01106     __HAL_UNLOCK(hnor);
01107   }
01108   else
01109   {
01110     return HAL_ERROR;
01111   }
01112 
01113   return status;
01114 }
01115 
01116 /**
01117   * @brief  Read NOR flash CFI IDs
01118   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01119   *                the configuration information for NOR module.
01120   * @param  pNOR_CFI  pointer to NOR CFI IDs structure
01121   * @retval HAL status
01122   */
01123 HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
01124 {
01125   uint32_t deviceaddress;
01126   HAL_NOR_StateTypeDef state;
01127 
01128   /* Check the NOR controller state */
01129   state = hnor->State;
01130   if (state == HAL_NOR_STATE_BUSY)
01131   {
01132     return HAL_BUSY;
01133   }
01134   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
01135   {
01136     /* Process Locked */
01137     __HAL_LOCK(hnor);
01138 
01139     /* Update the NOR controller state */
01140     hnor->State = HAL_NOR_STATE_BUSY;
01141 
01142     /* Select the NOR device address */
01143     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
01144     {
01145       deviceaddress = NOR_MEMORY_ADRESS1;
01146     }
01147     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
01148     {
01149       deviceaddress = NOR_MEMORY_ADRESS2;
01150     }
01151     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
01152     {
01153       deviceaddress = NOR_MEMORY_ADRESS3;
01154     }
01155     else /* FMC_NORSRAM_BANK4 */
01156     {
01157       deviceaddress = NOR_MEMORY_ADRESS4;
01158     }
01159 
01160     /* Send read CFI query command */
01161     NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
01162 
01163     /* read the NOR CFI information */
01164     pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
01165     pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
01166     pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
01167     pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
01168 
01169     /* Check the NOR controller state */
01170     hnor->State = state;
01171 
01172     /* Process unlocked */
01173     __HAL_UNLOCK(hnor);
01174   }
01175   else
01176   {
01177     return HAL_ERROR;
01178   }
01179 
01180   return HAL_OK;
01181 }
01182 
01183 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
01184 /**
01185   * @brief  Register a User NOR Callback
01186   *         To be used instead of the weak (surcharged) predefined callback
01187   * @param hnor : NOR handle
01188   * @param CallbackId : ID of the callback to be registered
01189   *        This parameter can be one of the following values:
01190   *          @arg @ref HAL_NOR_MSP_INIT_CB_ID       NOR MspInit callback ID
01191   *          @arg @ref HAL_NOR_MSP_DEINIT_CB_ID     NOR MspDeInit callback ID
01192   * @param pCallback : pointer to the Callback function
01193   * @retval status
01194   */
01195 HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId,
01196                                            pNOR_CallbackTypeDef pCallback)
01197 {
01198   HAL_StatusTypeDef status = HAL_OK;
01199   HAL_NOR_StateTypeDef state;
01200 
01201   if (pCallback == NULL)
01202   {
01203     return HAL_ERROR;
01204   }
01205 
01206   /* Process locked */
01207   __HAL_LOCK(hnor);
01208 
01209   state = hnor->State;
01210   if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
01211   {
01212     switch (CallbackId)
01213     {
01214       case HAL_NOR_MSP_INIT_CB_ID :
01215         hnor->MspInitCallback = pCallback;
01216         break;
01217       case HAL_NOR_MSP_DEINIT_CB_ID :
01218         hnor->MspDeInitCallback = pCallback;
01219         break;
01220       default :
01221         /* update return status */
01222         status =  HAL_ERROR;
01223         break;
01224     }
01225   }
01226   else
01227   {
01228     /* update return status */
01229     status =  HAL_ERROR;
01230   }
01231 
01232   /* Release Lock */
01233   __HAL_UNLOCK(hnor);
01234   return status;
01235 }
01236 
01237 /**
01238   * @brief  Unregister a User NOR Callback
01239   *         NOR Callback is redirected to the weak (surcharged) predefined callback
01240   * @param hnor : NOR handle
01241   * @param CallbackId : ID of the callback to be unregistered
01242   *        This parameter can be one of the following values:
01243   *          @arg @ref HAL_NOR_MSP_INIT_CB_ID       NOR MspInit callback ID
01244   *          @arg @ref HAL_NOR_MSP_DEINIT_CB_ID     NOR MspDeInit callback ID
01245   * @retval status
01246   */
01247 HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId)
01248 {
01249   HAL_StatusTypeDef status = HAL_OK;
01250   HAL_NOR_StateTypeDef state;
01251 
01252   /* Process locked */
01253   __HAL_LOCK(hnor);
01254 
01255   state = hnor->State;
01256   if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
01257   {
01258     switch (CallbackId)
01259     {
01260       case HAL_NOR_MSP_INIT_CB_ID :
01261         hnor->MspInitCallback = HAL_NOR_MspInit;
01262         break;
01263       case HAL_NOR_MSP_DEINIT_CB_ID :
01264         hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
01265         break;
01266       default :
01267         /* update return status */
01268         status =  HAL_ERROR;
01269         break;
01270     }
01271   }
01272   else
01273   {
01274     /* update return status */
01275     status =  HAL_ERROR;
01276   }
01277 
01278   /* Release Lock */
01279   __HAL_UNLOCK(hnor);
01280   return status;
01281 }
01282 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
01283 
01284 /**
01285   * @}
01286   */
01287 
01288 /** @defgroup NOR_Exported_Functions_Group3 NOR Control functions
01289   *  @brief   management functions
01290   *
01291 @verbatim
01292   ==============================================================================
01293                         ##### NOR Control functions #####
01294   ==============================================================================
01295   [..]
01296     This subsection provides a set of functions allowing to control dynamically
01297     the NOR interface.
01298 
01299 @endverbatim
01300   * @{
01301   */
01302 
01303 /**
01304   * @brief  Enables dynamically NOR write operation.
01305   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01306   *                the configuration information for NOR module.
01307   * @retval HAL status
01308   */
01309 HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
01310 {
01311   /* Check the NOR controller state */
01312   if (hnor->State == HAL_NOR_STATE_PROTECTED)
01313   {
01314     /* Process Locked */
01315     __HAL_LOCK(hnor);
01316 
01317     /* Update the NOR controller state */
01318     hnor->State = HAL_NOR_STATE_BUSY;
01319 
01320     /* Enable write operation */
01321     (void)FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
01322 
01323     /* Update the NOR controller state */
01324     hnor->State = HAL_NOR_STATE_READY;
01325 
01326     /* Process unlocked */
01327     __HAL_UNLOCK(hnor);
01328   }
01329   else
01330   {
01331     return HAL_ERROR;
01332   }
01333 
01334   return HAL_OK;
01335 }
01336 
01337 /**
01338   * @brief  Disables dynamically NOR write operation.
01339   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01340   *                the configuration information for NOR module.
01341   * @retval HAL status
01342   */
01343 HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
01344 {
01345   /* Check the NOR controller state */
01346   if (hnor->State == HAL_NOR_STATE_READY)
01347   {
01348     /* Process Locked */
01349     __HAL_LOCK(hnor);
01350 
01351     /* Update the NOR controller state */
01352     hnor->State = HAL_NOR_STATE_BUSY;
01353 
01354     /* Disable write operation */
01355     (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
01356 
01357     /* Update the NOR controller state */
01358     hnor->State = HAL_NOR_STATE_PROTECTED;
01359 
01360     /* Process unlocked */
01361     __HAL_UNLOCK(hnor);
01362   }
01363   else
01364   {
01365     return HAL_ERROR;
01366   }
01367 
01368   return HAL_OK;
01369 }
01370 
01371 /**
01372   * @}
01373   */
01374 
01375 /** @defgroup NOR_Exported_Functions_Group4 NOR State functions
01376   *  @brief   Peripheral State functions
01377   *
01378 @verbatim
01379   ==============================================================================
01380                       ##### NOR State functions #####
01381   ==============================================================================
01382   [..]
01383     This subsection permits to get in run-time the status of the NOR controller
01384     and the data flow.
01385 
01386 @endverbatim
01387   * @{
01388   */
01389 
01390 /**
01391   * @brief  return the NOR controller state
01392   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01393   *                the configuration information for NOR module.
01394   * @retval NOR controller state
01395   */
01396 HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
01397 {
01398   return hnor->State;
01399 }
01400 
01401 /**
01402   * @brief  Returns the NOR operation status.
01403   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
01404   *                the configuration information for NOR module.
01405   * @param  Address Device address
01406   * @param  Timeout NOR programming Timeout
01407   * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
01408   *         or HAL_NOR_STATUS_TIMEOUT
01409   */
01410 HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
01411 {
01412   HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
01413   uint16_t tmpsr1;
01414   uint16_t tmpsr2;
01415   uint32_t tickstart;
01416 
01417   /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
01418   HAL_NOR_MspWait(hnor, Timeout);
01419 
01420   /* Get the NOR memory operation status -------------------------------------*/
01421 
01422   /* Get tick */
01423   tickstart = HAL_GetTick();
01424 
01425   if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
01426   {
01427     while ((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
01428     {
01429       /* Check for the Timeout */
01430       if (Timeout != HAL_MAX_DELAY)
01431       {
01432         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01433         {
01434           status = HAL_NOR_STATUS_TIMEOUT;
01435         }
01436       }
01437 
01438       /* Read NOR status register (DQ6 and DQ5) */
01439       tmpsr1 = *(__IO uint16_t *)Address;
01440       tmpsr2 = *(__IO uint16_t *)Address;
01441 
01442       /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01443       if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
01444       {
01445         return HAL_NOR_STATUS_SUCCESS ;
01446       }
01447 
01448       if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
01449       {
01450         status = HAL_NOR_STATUS_ONGOING;
01451       }
01452 
01453       tmpsr1 = *(__IO uint16_t *)Address;
01454       tmpsr2 = *(__IO uint16_t *)Address;
01455 
01456       /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01457       if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
01458       {
01459         return HAL_NOR_STATUS_SUCCESS;
01460       }
01461       if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
01462       {
01463         return HAL_NOR_STATUS_ERROR;
01464       }
01465     }
01466   }
01467   else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
01468   {
01469     do
01470     {
01471       NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
01472       tmpsr2 = *(__IO uint16_t *)(Address);
01473 
01474       /* Check for the Timeout */
01475       if (Timeout != HAL_MAX_DELAY)
01476       {
01477         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01478         {
01479           return HAL_NOR_STATUS_TIMEOUT;
01480         }
01481       }
01482     } while ((tmpsr2 & NOR_MASK_STATUS_DQ7) == 0U);
01483 
01484     NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
01485     tmpsr1 = *(__IO uint16_t *)(Address);
01486     if ((tmpsr1  & (NOR_MASK_STATUS_DQ5 | NOR_MASK_STATUS_DQ4)) != 0U)
01487     {
01488       /* Clear the Status Register  */
01489       NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
01490       status = HAL_NOR_STATUS_ERROR;
01491     }
01492     else
01493     {
01494       status = HAL_NOR_STATUS_SUCCESS;
01495     }
01496   }
01497   else
01498   {
01499     /* Primary command set not supported by the driver */
01500     status = HAL_NOR_STATUS_ERROR;
01501   }
01502 
01503   /* Return the operation status */
01504   return status;
01505 }
01506 
01507 /**
01508   * @}
01509   */
01510 
01511 /**
01512   * @}
01513   */
01514 
01515 /**
01516   * @}
01517   */
01518 
01519 #endif /* HAL_NOR_MODULE_ENABLED */
01520 
01521 /**
01522   * @}
01523   */
01524