STM32L486xx HAL User Manual
stm32l4xx_hal_nor.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_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 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 "stm32l4xx_hal.h"
00085 
00086 #if defined(FMC_BANK1)
00087 
00088 /** @addtogroup STM32L4xx_HAL_Driver
00089   * @{
00090   */
00091 
00092 #ifdef HAL_NOR_MODULE_ENABLED
00093 
00094 /** @defgroup NOR NOR
00095   * @brief NOR driver modules
00096   * @{
00097   */
00098 
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  Initialize the NOR MSP.
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 
00258   /* NOTE : This function should not be modified, when the callback is needed,
00259             the HAL_NOR_MspInit could be implemented in the user file
00260    */
00261 }
00262 
00263 /**
00264   * @brief  DeInitialize the NOR MSP.
00265   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00266   *                the configuration information for NOR module.
00267   * @retval None
00268   */
00269 __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
00270 {
00271   /* Prevent unused argument(s) compilation warning */
00272   UNUSED(hnor);
00273 
00274   /* NOTE : This function should not be modified, when the callback is needed,
00275             the HAL_NOR_MspDeInit could be implemented in the user file
00276    */
00277 }
00278 
00279 /**
00280   * @brief  NOR MSP Wait for Ready/Busy signal
00281   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00282   *                the configuration information for NOR module.
00283   * @param  Timeout Maximum timeout value
00284   * @retval None
00285   */
00286 __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
00287 {
00288   /* Prevent unused argument(s) compilation warning */
00289   UNUSED(hnor);
00290   UNUSED(Timeout);
00291 
00292   /* NOTE : This function should not be modified, when the callback is needed,
00293             the HAL_NOR_MspWait could be implemented in the user file
00294    */
00295 }
00296 
00297 /**
00298   * @}
00299   */
00300 
00301 /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
00302   * @brief    Input Output and memory control functions
00303   *
00304   @verbatim
00305   ==============================================================================
00306                 ##### NOR Input and Output functions #####
00307   ==============================================================================
00308   [..]
00309     This section provides functions allowing to use and control the NOR memory
00310 
00311 @endverbatim
00312   * @{
00313   */
00314 
00315 /**
00316   * @brief  Read NOR flash IDs
00317   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00318   *                the configuration information for NOR module.
00319   * @param  pNOR_ID  pointer to NOR ID structure
00320   * @retval HAL status
00321   */
00322 HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
00323 {
00324   uint32_t deviceaddress = 0;
00325 
00326   /* Process Locked */
00327   __HAL_LOCK(hnor);
00328 
00329   /* Check the NOR controller state */
00330   if(hnor->State == HAL_NOR_STATE_BUSY)
00331   {
00332      return HAL_BUSY;
00333   }
00334 
00335   /* Select the NOR device address */
00336   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00337   {
00338     deviceaddress = NOR_MEMORY_ADRESS1;
00339   }
00340   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00341   {
00342     deviceaddress = NOR_MEMORY_ADRESS2;
00343   }
00344   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00345   {
00346     deviceaddress = NOR_MEMORY_ADRESS3;
00347   }
00348   else /* FMC_NORSRAM_BANK4 */
00349   {
00350     deviceaddress = NOR_MEMORY_ADRESS4;
00351   }
00352 
00353   /* Update the NOR controller state */
00354   hnor->State = HAL_NOR_STATE_BUSY;
00355 
00356   /* Send read ID command */
00357   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00358   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00359   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
00360 
00361   /* Read the NOR IDs */
00362   pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
00363   pNOR_ID->Device_Code1      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR);
00364   pNOR_ID->Device_Code2      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR);
00365   pNOR_ID->Device_Code3      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR);
00366 
00367   /* Check the NOR controller state */
00368   hnor->State = HAL_NOR_STATE_READY;
00369 
00370   /* Process unlocked */
00371   __HAL_UNLOCK(hnor);
00372 
00373   return HAL_OK;
00374 }
00375 
00376 /**
00377   * @brief  Return the NOR memory to Read mode.
00378   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00379   *                the configuration information for NOR module.
00380   * @retval HAL status
00381   */
00382 HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
00383 {
00384   uint32_t deviceaddress = 0;
00385 
00386   /* Process Locked */
00387   __HAL_LOCK(hnor);
00388 
00389   /* Check the NOR controller state */
00390   if(hnor->State == HAL_NOR_STATE_BUSY)
00391   {
00392      return HAL_BUSY;
00393   }
00394 
00395   /* Select the NOR device address */
00396   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00397   {
00398     deviceaddress = NOR_MEMORY_ADRESS1;
00399   }
00400   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00401   {
00402     deviceaddress = NOR_MEMORY_ADRESS2;
00403   }
00404   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00405   {
00406     deviceaddress = NOR_MEMORY_ADRESS3;
00407   }
00408   else /* FMC_NORSRAM_BANK4 */
00409   {
00410     deviceaddress = NOR_MEMORY_ADRESS4;
00411   }
00412 
00413   NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
00414 
00415   /* Check the NOR controller state */
00416   hnor->State = HAL_NOR_STATE_READY;
00417 
00418   /* Process unlocked */
00419   __HAL_UNLOCK(hnor);
00420 
00421   return HAL_OK;
00422 }
00423 
00424 /**
00425   * @brief  Read data from NOR memory
00426   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00427   *                the configuration information for NOR module.
00428   * @param  pAddress pointer to Device address
00429   * @param  pData  pointer to read data
00430   * @retval HAL status
00431   */
00432 HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00433 {
00434   uint32_t deviceaddress = 0;
00435 
00436   /* Process Locked */
00437   __HAL_LOCK(hnor);
00438 
00439   /* Check the NOR controller state */
00440   if(hnor->State == HAL_NOR_STATE_BUSY)
00441   {
00442      return HAL_BUSY;
00443   }
00444 
00445   /* Select the NOR device address */
00446   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00447   {
00448     deviceaddress = NOR_MEMORY_ADRESS1;
00449   }
00450   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00451   {
00452     deviceaddress = NOR_MEMORY_ADRESS2;
00453   }
00454   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00455   {
00456     deviceaddress = NOR_MEMORY_ADRESS3;
00457   }
00458   else /* FMC_NORSRAM_BANK4 */
00459   {
00460     deviceaddress = NOR_MEMORY_ADRESS4;
00461   }
00462 
00463   /* Update the NOR controller state */
00464   hnor->State = HAL_NOR_STATE_BUSY;
00465 
00466   /* Send read data command */
00467   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00468   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00469   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00470 
00471   /* Read the data */
00472   *pData = *(__IO uint32_t *)(uint32_t)pAddress;
00473 
00474   /* Check the NOR controller state */
00475   hnor->State = HAL_NOR_STATE_READY;
00476 
00477   /* Process unlocked */
00478   __HAL_UNLOCK(hnor);
00479 
00480   return HAL_OK;
00481 }
00482 
00483 /**
00484   * @brief  Program data to NOR memory
00485   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00486   *                the configuration information for NOR module.
00487   * @param  pAddress Device address
00488   * @param  pData  pointer to the data to write
00489   * @retval HAL status
00490   */
00491 HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
00492 {
00493   uint32_t deviceaddress = 0;
00494 
00495   /* Process Locked */
00496   __HAL_LOCK(hnor);
00497 
00498   /* Check the NOR controller state */
00499   if(hnor->State == HAL_NOR_STATE_BUSY)
00500   {
00501      return HAL_BUSY;
00502   }
00503 
00504   /* Select the NOR device address */
00505   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00506   {
00507     deviceaddress = NOR_MEMORY_ADRESS1;
00508   }
00509   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00510   {
00511     deviceaddress = NOR_MEMORY_ADRESS2;
00512   }
00513   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00514   {
00515     deviceaddress = NOR_MEMORY_ADRESS3;
00516   }
00517   else /* FMC_NORSRAM_BANK4 */
00518   {
00519     deviceaddress = NOR_MEMORY_ADRESS4;
00520   }
00521 
00522   /* Update the NOR controller state */
00523   hnor->State = HAL_NOR_STATE_BUSY;
00524 
00525   /* Send program data command */
00526   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00527   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00528   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
00529 
00530   /* Write the data */
00531   NOR_WRITE(pAddress, *pData);
00532 
00533   /* Check the NOR controller state */
00534   hnor->State = HAL_NOR_STATE_READY;
00535 
00536   /* Process unlocked */
00537   __HAL_UNLOCK(hnor);
00538 
00539   return HAL_OK;
00540 }
00541 
00542 /**
00543   * @brief  Read a half-word buffer from the NOR memory.
00544   * @param  hnor pointer to the NOR handle
00545   * @param  uwAddress NOR memory internal address to read from.
00546   * @param  pData pointer to the buffer that receives the data read from the
00547   *         NOR memory.
00548   * @param  uwBufferSize  number of Half word to read.
00549   * @retval HAL status
00550   */
00551 HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
00552 {
00553   uint32_t deviceaddress = 0;
00554 
00555   /* Process Locked */
00556   __HAL_LOCK(hnor);
00557 
00558   /* Check the NOR controller state */
00559   if(hnor->State == HAL_NOR_STATE_BUSY)
00560   {
00561      return HAL_BUSY;
00562   }
00563 
00564   /* Select the NOR device address */
00565   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00566   {
00567     deviceaddress = NOR_MEMORY_ADRESS1;
00568   }
00569   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00570   {
00571     deviceaddress = NOR_MEMORY_ADRESS2;
00572   }
00573   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00574   {
00575     deviceaddress = NOR_MEMORY_ADRESS3;
00576   }
00577   else /* FMC_NORSRAM_BANK4 */
00578   {
00579     deviceaddress = NOR_MEMORY_ADRESS4;
00580   }
00581 
00582   /* Update the NOR controller state */
00583   hnor->State = HAL_NOR_STATE_BUSY;
00584 
00585   /* Send read data command */
00586   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00587   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00588   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
00589 
00590   /* Read buffer */
00591   while( uwBufferSize > 0)
00592   {
00593     *pData++ = *(__IO uint16_t *)uwAddress;
00594     uwAddress += 2;
00595     uwBufferSize--;
00596   }
00597 
00598   /* Check the NOR controller state */
00599   hnor->State = HAL_NOR_STATE_READY;
00600 
00601   /* Process unlocked */
00602   __HAL_UNLOCK(hnor);
00603 
00604   return HAL_OK;
00605 }
00606 
00607 /**
00608   * @brief  Writes a half-word buffer to the NOR memory. This function must be used
00609             only with S29GL128P NOR memory.
00610   * @param  hnor pointer to the NOR handle
00611   * @param  uwAddress NOR memory internal start write address
00612   * @param  pData pointer to source data buffer.
00613   * @param  uwBufferSize Size of the buffer to write
00614   * @retval HAL status
00615   */
00616 HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
00617 {
00618   uint16_t * p_currentaddress = (uint16_t *)NULL;
00619   uint16_t * p_endaddress = (uint16_t *)NULL;
00620   uint32_t lastloadedaddress = 0, deviceaddress = 0;
00621 
00622   /* Process Locked */
00623   __HAL_LOCK(hnor);
00624 
00625   /* Check the NOR controller state */
00626   if(hnor->State == HAL_NOR_STATE_BUSY)
00627   {
00628      return HAL_BUSY;
00629   }
00630 
00631   /* Select the NOR device address */
00632   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00633   {
00634     deviceaddress = NOR_MEMORY_ADRESS1;
00635   }
00636   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00637   {
00638     deviceaddress = NOR_MEMORY_ADRESS2;
00639   }
00640   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00641   {
00642     deviceaddress = NOR_MEMORY_ADRESS3;
00643   }
00644   else /* FMC_NORSRAM_BANK4 */
00645   {
00646     deviceaddress = NOR_MEMORY_ADRESS4;
00647   }
00648 
00649   /* Update the NOR controller state */
00650   hnor->State = HAL_NOR_STATE_BUSY;
00651 
00652   /* Initialize variables */
00653   p_currentaddress  = (uint16_t*)((uint32_t)(uwAddress));
00654   p_endaddress      = p_currentaddress + (uwBufferSize-1);
00655   lastloadedaddress = (uint32_t)(uwAddress);
00656 
00657   /* Issue unlock command sequence */
00658   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00659   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00660 
00661   /* Write Buffer Load Command */
00662   NOR_WRITE((uint32_t)(p_currentaddress), NOR_CMD_DATA_BUFFER_AND_PROG);
00663   NOR_WRITE((uint32_t)(p_currentaddress), (uwBufferSize-1));
00664 
00665   /* Load Data into NOR Buffer */
00666   while(p_currentaddress <= p_endaddress)
00667   {
00668     /* Store last loaded address & data value (for polling) */
00669     lastloadedaddress = (uint32_t)p_currentaddress;
00670 
00671     NOR_WRITE(p_currentaddress, *pData++);
00672 
00673     p_currentaddress++;
00674   }
00675 
00676   NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
00677 
00678   /* Check the NOR controller state */
00679   hnor->State = HAL_NOR_STATE_READY;
00680 
00681   /* Process unlocked */
00682   __HAL_UNLOCK(hnor);
00683 
00684   return HAL_OK;
00685 
00686 }
00687 
00688 /**
00689   * @brief  Erase the specified block of the NOR memory
00690   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00691   *                the configuration information for NOR module.
00692   * @param  BlockAddress  Block to erase address
00693   * @param  Address Device address
00694   * @retval HAL status
00695   */
00696 HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
00697 {
00698   uint32_t deviceaddress = 0;
00699 
00700   /* Process Locked */
00701   __HAL_LOCK(hnor);
00702 
00703   /* Check the NOR controller state */
00704   if(hnor->State == HAL_NOR_STATE_BUSY)
00705   {
00706      return HAL_BUSY;
00707   }
00708 
00709   /* Select the NOR device address */
00710   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00711   {
00712     deviceaddress = NOR_MEMORY_ADRESS1;
00713   }
00714   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00715   {
00716     deviceaddress = NOR_MEMORY_ADRESS2;
00717   }
00718   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00719   {
00720     deviceaddress = NOR_MEMORY_ADRESS3;
00721   }
00722   else /* FMC_NORSRAM_BANK4 */
00723   {
00724     deviceaddress = NOR_MEMORY_ADRESS4;
00725   }
00726 
00727   /* Update the NOR controller state */
00728   hnor->State = HAL_NOR_STATE_BUSY;
00729 
00730   /* Send block erase command sequence */
00731   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00732   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00733   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
00734   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
00735   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
00736   NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
00737 
00738   /* Check the NOR memory status and update the controller state */
00739   hnor->State = HAL_NOR_STATE_READY;
00740 
00741   /* Process unlocked */
00742   __HAL_UNLOCK(hnor);
00743 
00744   return HAL_OK;
00745 
00746 }
00747 
00748 /**
00749   * @brief  Erase the entire NOR chip.
00750   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00751   *                the configuration information for NOR module.
00752   * @param  Address  Device address
00753   * @retval HAL status
00754   */
00755 HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
00756 {
00757   uint32_t deviceaddress = 0;
00758 
00759   /* Prevent unused argument(s) compilation warning */
00760   UNUSED(Address);
00761 
00762   /* Process Locked */
00763   __HAL_LOCK(hnor);
00764 
00765   /* Check the NOR controller state */
00766   if(hnor->State == HAL_NOR_STATE_BUSY)
00767   {
00768      return HAL_BUSY;
00769   }
00770 
00771   /* Select the NOR device address */
00772   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00773   {
00774     deviceaddress = NOR_MEMORY_ADRESS1;
00775   }
00776   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00777   {
00778     deviceaddress = NOR_MEMORY_ADRESS2;
00779   }
00780   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00781   {
00782     deviceaddress = NOR_MEMORY_ADRESS3;
00783   }
00784   else /* FMC_NORSRAM_BANK4 */
00785   {
00786     deviceaddress = NOR_MEMORY_ADRESS4;
00787   }
00788 
00789   /* Update the NOR controller state */
00790   hnor->State = HAL_NOR_STATE_BUSY;
00791 
00792   /* Send NOR chip erase command sequence */
00793   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
00794   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
00795   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
00796   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
00797   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
00798   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
00799 
00800   /* Check the NOR memory status and update the controller state */
00801   hnor->State = HAL_NOR_STATE_READY;
00802 
00803   /* Process unlocked */
00804   __HAL_UNLOCK(hnor);
00805 
00806   return HAL_OK;
00807 }
00808 
00809 /**
00810   * @brief  Read NOR flash CFI IDs
00811   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00812   *                the configuration information for NOR module.
00813   * @param  pNOR_CFI  pointer to NOR CFI IDs structure
00814   * @retval HAL status
00815   */
00816 HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
00817 {
00818   uint32_t deviceaddress = 0;
00819 
00820   /* Process Locked */
00821   __HAL_LOCK(hnor);
00822 
00823   /* Check the NOR controller state */
00824   if(hnor->State == HAL_NOR_STATE_BUSY)
00825   {
00826      return HAL_BUSY;
00827   }
00828 
00829   /* Select the NOR device address */
00830   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
00831   {
00832     deviceaddress = NOR_MEMORY_ADRESS1;
00833   }
00834   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
00835   {
00836     deviceaddress = NOR_MEMORY_ADRESS2;
00837   }
00838   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
00839   {
00840     deviceaddress = NOR_MEMORY_ADRESS3;
00841   }
00842   else /* FMC_NORSRAM_BANK4 */
00843   {
00844     deviceaddress = NOR_MEMORY_ADRESS4;
00845   }
00846 
00847   /* Update the NOR controller state */
00848   hnor->State = HAL_NOR_STATE_BUSY;
00849 
00850   /* Send read CFI query command */
00851   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
00852 
00853   /* read the NOR CFI information */
00854   pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
00855   pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
00856   pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
00857   pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
00858 
00859   /* Check the NOR controller state */
00860   hnor->State = HAL_NOR_STATE_READY;
00861 
00862   /* Process unlocked */
00863   __HAL_UNLOCK(hnor);
00864 
00865   return HAL_OK;
00866 }
00867 
00868 /**
00869   * @}
00870   */
00871 
00872 /** @defgroup NOR_Exported_Functions_Group3 NOR Control functions
00873  *  @brief   management functions
00874  *
00875 @verbatim
00876   ==============================================================================
00877                         ##### NOR Control functions #####
00878   ==============================================================================
00879   [..]
00880     This subsection provides a set of functions allowing to control dynamically
00881     the NOR interface.
00882 
00883 @endverbatim
00884   * @{
00885   */
00886 
00887 /**
00888   * @brief  Enable dynamically NOR write operation.
00889   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00890   *                the configuration information for NOR module.
00891   * @retval HAL status
00892   */
00893 HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
00894 {
00895   /* Process Locked */
00896   __HAL_LOCK(hnor);
00897 
00898   /* Enable write operation */
00899   FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
00900 
00901   /* Update the NOR controller state */
00902   hnor->State = HAL_NOR_STATE_READY;
00903 
00904   /* Process unlocked */
00905   __HAL_UNLOCK(hnor);
00906 
00907   return HAL_OK;
00908 }
00909 
00910 /**
00911   * @brief  Disable dynamically NOR write operation.
00912   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00913   *                the configuration information for NOR module.
00914   * @retval HAL status
00915   */
00916 HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
00917 {
00918   /* Process Locked */
00919   __HAL_LOCK(hnor);
00920 
00921   /* Update the SRAM controller state */
00922   hnor->State = HAL_NOR_STATE_BUSY;
00923 
00924   /* Disable write operation */
00925   FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
00926 
00927   /* Update the NOR controller state */
00928   hnor->State = HAL_NOR_STATE_PROTECTED;
00929 
00930   /* Process unlocked */
00931   __HAL_UNLOCK(hnor);
00932 
00933   return HAL_OK;
00934 }
00935 
00936 /**
00937   * @}
00938   */
00939 
00940 /** @defgroup NOR_Exported_Functions_Group4 NOR State functions
00941  *  @brief   Peripheral State functions
00942  *
00943 @verbatim
00944   ==============================================================================
00945                       ##### NOR State functions #####
00946   ==============================================================================
00947   [..]
00948     This subsection permits to get in run-time the status of the NOR controller
00949     and the data flow.
00950 
00951 @endverbatim
00952   * @{
00953   */
00954 
00955 /**
00956   * @brief  Return the NOR controller state
00957   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00958   *                the configuration information for NOR module.
00959   * @retval NOR controller state
00960   */
00961 HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
00962 {
00963   /* Return NOR handle state */
00964   return hnor->State;
00965 }
00966 
00967 /**
00968   * @brief  Return the NOR operation status.
00969   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
00970   *                the configuration information for NOR module.
00971   * @param  Address Device address
00972   * @param  Timeout NOR programming Timeout
00973   * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
00974   *         or HAL_NOR_STATUS_TIMEOUT
00975   */
00976 HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
00977 {
00978   HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
00979   uint16_t tmpSR1 = 0, tmpSR2 = 0;
00980   uint32_t tickstart = 0;
00981 
00982   /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
00983   HAL_NOR_MspWait(hnor, Timeout);
00984 
00985   /* Get the NOR memory operation status -------------------------------------*/
00986 
00987   /* Get tick */
00988   tickstart = HAL_GetTick();
00989   while((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
00990   {
00991     /* Check for the Timeout */
00992     if(Timeout != HAL_MAX_DELAY)
00993     {
00994       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
00995       {
00996         status = HAL_NOR_STATUS_TIMEOUT;
00997       }
00998     }
00999 
01000     /* Read NOR status register (DQ6 and DQ5) */
01001     tmpSR1 = *(__IO uint16_t *)Address;
01002     tmpSR2 = *(__IO uint16_t *)Address;
01003 
01004     /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01005     if ((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6))
01006     {
01007       return HAL_NOR_STATUS_SUCCESS;
01008     }
01009 
01010     if((tmpSR1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5)
01011     {
01012       status = HAL_NOR_STATUS_ONGOING;
01013     }
01014 
01015     tmpSR1 = *(__IO uint16_t *)Address;
01016     tmpSR2 = *(__IO uint16_t *)Address;
01017 
01018     /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
01019     if ((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6))
01020     {
01021       return HAL_NOR_STATUS_SUCCESS;
01022     }
01023     if ((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
01024     {
01025       return HAL_NOR_STATUS_ERROR;
01026     }
01027   }
01028 
01029   /* Return the operation status */
01030   return status;
01031 }
01032 
01033 /**
01034   * @}
01035   */
01036 
01037 /**
01038   * @}
01039   */
01040 
01041 /**
01042   * @}
01043   */
01044 
01045 #endif /* HAL_NOR_MODULE_ENABLED */
01046 
01047 /**
01048   * @}
01049   */
01050 
01051 #endif /* FMC_BANK1 */
01052 
01053 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/