TUKS MCU Introductory course / TUKS-COURSE-2-LED
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_nor.c Source File

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