1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_nor.c
4   * @author  MCD Application Team
5   * @brief   NOR HAL module driver.
6   *          This file provides a generic firmware to drive NOR memories mounted
7   *          as external device.
8   *
9   @verbatim
10   ==============================================================================
11                      ##### How to use this driver #####
12   ==============================================================================
13     [..]
14       This driver is a generic layered driver which contains a set of APIs used to
15       control NOR flash memories. It uses the FMC layer functions to interface
16       with NOR devices. This driver is used as follows:
17 
18       (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
19           with control and timing parameters for both normal and extended mode.
20 
21       (+) Read NOR flash memory manufacturer code and device IDs using the function
22           HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
23           structure declared by the function caller.
24 
25       (+) Access NOR flash memory by read/write data unit operations using the functions
26           HAL_NOR_Read(), HAL_NOR_Program().
27 
28       (+) Perform NOR flash erase block/chip operations using the functions
29           HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
30 
31       (+) Read the NOR flash CFI (common flash interface) IDs using the function
32           HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
33           structure declared by the function caller.
34 
35       (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
36           HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation
37 
38       (+) You can monitor the NOR device HAL state by calling the function
39           HAL_NOR_GetState()
40     [..]
41      (@) This driver is a set of generic APIs which handle standard NOR flash operations.
42          If a NOR flash device contains different operations and/or implementations,
43          it should be implemented separately.
44 
45      *** NOR HAL driver macros list ***
46      =============================================
47      [..]
48        Below the list of most used macros in NOR HAL driver.
49 
50       (+) NOR_WRITE : NOR memory write data to specified address
51 
52     *** Callback registration ***
53     =============================================
54     [..]
55       The compilation define  USE_HAL_NOR_REGISTER_CALLBACKS when set to 1
56       allows the user to configure dynamically the driver callbacks.
57 
58       Use Functions @ref HAL_NOR_RegisterCallback() to register a user callback,
59       it allows to register following callbacks:
60         (+) MspInitCallback    : NOR MspInit.
61         (+) MspDeInitCallback  : NOR MspDeInit.
62       This function takes as parameters the HAL peripheral handle, the Callback ID
63       and a pointer to the user callback function.
64 
65       Use function @ref HAL_NOR_UnRegisterCallback() to reset a callback to the default
66       weak (surcharged) function. It allows to reset following callbacks:
67         (+) MspInitCallback    : NOR MspInit.
68         (+) MspDeInitCallback  : NOR MspDeInit.
69       This function) takes as parameters the HAL peripheral handle and the Callback ID.
70 
71       By default, after the @ref HAL_NOR_Init and if the state is HAL_NOR_STATE_RESET
72       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
73       Exception done for MspInit and MspDeInit callbacks that are respectively
74       reset to the legacy weak (surcharged) functions in the @ref HAL_NOR_Init
75       and @ref  HAL_NOR_DeInit only when these callbacks are null (not registered beforehand).
76       If not, MspInit or MspDeInit are not null, the @ref HAL_NOR_Init and @ref HAL_NOR_DeInit
77       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
78 
79       Callbacks can be registered/unregistered in READY state only.
80       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
81       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
82       during the Init/DeInit.
83       In that case first register the MspInit/MspDeInit user callbacks
84       using @ref HAL_NOR_RegisterCallback before calling @ref HAL_NOR_DeInit
85       or @ref HAL_NOR_Init function.
86 
87       When The compilation define USE_HAL_NOR_REGISTER_CALLBACKS is set to 0 or
88       not defined, the callback registering feature is not available
89       and weak (surcharged) callbacks are used.
90 
91   @endverbatim
92   ******************************************************************************
93   * @attention
94   *
95   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
96   * All rights reserved.</center></h2>
97   *
98   * This software component is licensed by ST under BSD 3-Clause license,
99   * the "License"; You may not use this file except in compliance with the
100   * License. You may obtain a copy of the License at:
101   *                       opensource.org/licenses/BSD-3-Clause
102   *
103   ******************************************************************************
104   */
105 
106 /* Includes ------------------------------------------------------------------*/
107 #include "stm32l5xx_hal.h"
108 
109 
110 /** @addtogroup STM32L5xx_HAL_Driver
111   * @{
112   */
113 
114 #ifdef HAL_NOR_MODULE_ENABLED
115 
116 /** @defgroup NOR NOR
117   * @brief NOR driver modules
118   * @{
119   */
120 
121 /* Private typedef -----------------------------------------------------------*/
122 /* Private define ------------------------------------------------------------*/
123 
124 /** @defgroup NOR_Private_Defines NOR Private Defines
125   * @{
126   */
127 
128 /* Constants to define address to set to write a command */
129 #define NOR_CMD_ADDRESS_FIRST                 (uint16_t)0x0555
130 #define NOR_CMD_ADDRESS_FIRST_CFI             (uint16_t)0x0055
131 #define NOR_CMD_ADDRESS_SECOND                (uint16_t)0x02AA
132 #define NOR_CMD_ADDRESS_THIRD                 (uint16_t)0x0555
133 #define NOR_CMD_ADDRESS_FOURTH                (uint16_t)0x0555
134 #define NOR_CMD_ADDRESS_FIFTH                 (uint16_t)0x02AA
135 #define NOR_CMD_ADDRESS_SIXTH                 (uint16_t)0x0555
136 
137 /* Constants to define data to program a command */
138 #define NOR_CMD_DATA_READ_RESET               (uint16_t)0x00F0
139 #define NOR_CMD_DATA_FIRST                    (uint16_t)0x00AA
140 #define NOR_CMD_DATA_SECOND                   (uint16_t)0x0055
141 #define NOR_CMD_DATA_AUTO_SELECT              (uint16_t)0x0090
142 #define NOR_CMD_DATA_PROGRAM                  (uint16_t)0x00A0
143 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD   (uint16_t)0x0080
144 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH  (uint16_t)0x00AA
145 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH   (uint16_t)0x0055
146 #define NOR_CMD_DATA_CHIP_ERASE               (uint16_t)0x0010
147 #define NOR_CMD_DATA_CFI                      (uint16_t)0x0098
148 
149 #define NOR_CMD_DATA_BUFFER_AND_PROG          (uint8_t)0x25
150 #define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM  (uint8_t)0x29
151 #define NOR_CMD_DATA_BLOCK_ERASE              (uint8_t)0x30
152 
153 #define NOR_CMD_READ_ARRAY                    (uint16_t)0x00FF
154 #define NOR_CMD_WORD_PROGRAM                  (uint16_t)0x0040
155 #define NOR_CMD_BUFFERED_PROGRAM              (uint16_t)0x00E8
156 #define NOR_CMD_CONFIRM                       (uint16_t)0x00D0
157 #define NOR_CMD_BLOCK_ERASE                   (uint16_t)0x0020
158 #define NOR_CMD_BLOCK_UNLOCK                  (uint16_t)0x0060
159 #define NOR_CMD_READ_STATUS_REG               (uint16_t)0x0070
160 #define NOR_CMD_CLEAR_STATUS_REG              (uint16_t)0x0050
161 
162 /* Mask on NOR STATUS REGISTER */
163 #define NOR_MASK_STATUS_DQ4                   (uint16_t)0x0010
164 #define NOR_MASK_STATUS_DQ5                   (uint16_t)0x0020
165 #define NOR_MASK_STATUS_DQ6                   (uint16_t)0x0040
166 #define NOR_MASK_STATUS_DQ7                   (uint16_t)0x0080
167 
168 /* Address of the primary command set */
169 #define NOR_ADDRESS_COMMAND_SET               (uint16_t)0x0013
170 
171 /* Command set code assignment (defined in JEDEC JEP137B version may 2004) */
172 #define NOR_INTEL_SHARP_EXT_COMMAND_SET       (uint16_t)0x0001 /* Supported in this driver */
173 #define NOR_AMD_FUJITSU_COMMAND_SET           (uint16_t)0x0002 /* Supported in this driver */
174 #define NOR_INTEL_STANDARD_COMMAND_SET        (uint16_t)0x0003 /* Not Supported in this driver */
175 #define NOR_AMD_FUJITSU_EXT_COMMAND_SET       (uint16_t)0x0004 /* Not Supported in this driver */
176 #define NOR_WINDBOND_STANDARD_COMMAND_SET     (uint16_t)0x0006 /* Not Supported in this driver */
177 #define NOR_MITSUBISHI_STANDARD_COMMAND_SET   (uint16_t)0x0100 /* Not Supported in this driver */
178 #define NOR_MITSUBISHI_EXT_COMMAND_SET        (uint16_t)0x0101 /* Not Supported in this driver */
179 #define NOR_PAGE_WRITE_COMMAND_SET            (uint16_t)0x0102 /* Not Supported in this driver */
180 #define NOR_INTEL_PERFORMANCE_COMMAND_SET     (uint16_t)0x0200 /* Not Supported in this driver */
181 #define NOR_INTEL_DATA_COMMAND_SET            (uint16_t)0x0210 /* Not Supported in this driver */
182 
183 /**
184   * @}
185   */
186 
187 /* Private macro -------------------------------------------------------------*/
188 /* Private variables ---------------------------------------------------------*/
189 /** @defgroup NOR_Private_Variables NOR Private Variables
190   * @{
191   */
192 
193 static uint32_t uwNORMemoryDataWidth  = NOR_MEMORY_8B;
194 
195 /**
196   * @}
197   */
198 
199 /* Private functions ---------------------------------------------------------*/
200 /* Exported functions --------------------------------------------------------*/
201 /** @defgroup NOR_Exported_Functions NOR Exported Functions
202   * @{
203   */
204 
205 /** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
206   * @brief    Initialization and Configuration functions
207   *
208   @verbatim
209   ==============================================================================
210            ##### NOR Initialization and de_initialization functions #####
211   ==============================================================================
212   [..]
213     This section provides functions allowing to initialize/de-initialize
214     the NOR memory
215 
216 @endverbatim
217   * @{
218   */
219 
220 /**
221   * @brief  Perform the NOR memory Initialization sequence
222   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
223   *                the configuration information for NOR module.
224   * @param  Timing pointer to NOR control timing structure
225   * @param  ExtTiming pointer to NOR extended mode timing structure
226   * @retval HAL status
227   */
HAL_NOR_Init(NOR_HandleTypeDef * hnor,FMC_NORSRAM_TimingTypeDef * Timing,FMC_NORSRAM_TimingTypeDef * ExtTiming)228 HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing,
229                                FMC_NORSRAM_TimingTypeDef *ExtTiming)
230 {
231   uint32_t deviceaddress;
232 
233   /* Check the NOR handle parameter */
234   if (hnor == NULL)
235   {
236     return HAL_ERROR;
237   }
238 
239   if (hnor->State == HAL_NOR_STATE_RESET)
240   {
241     /* Allocate lock resource and initialize it */
242     hnor->Lock = HAL_UNLOCKED;
243 
244 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
245     if (hnor->MspInitCallback == NULL)
246     {
247       hnor->MspInitCallback = HAL_NOR_MspInit;
248     }
249 
250     /* Init the low level hardware */
251     hnor->MspInitCallback(hnor);
252 #else
253     /* Initialize the low level hardware (MSP) */
254     HAL_NOR_MspInit(hnor);
255 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
256   }
257 
258   /* Initialize NOR control Interface */
259   (void)FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
260 
261   /* Initialize NOR timing Interface */
262   (void)FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
263 
264   /* Initialize NOR extended mode timing Interface */
265   (void)FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
266 
267   /* Enable the NORSRAM device */
268   __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
269 
270   /* Initialize NOR Memory Data Width*/
271   if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8)
272   {
273     uwNORMemoryDataWidth = NOR_MEMORY_8B;
274   }
275   else
276   {
277     uwNORMemoryDataWidth = NOR_MEMORY_16B;
278   }
279 
280   /* Initialize the NOR controller state */
281   hnor->State = HAL_NOR_STATE_READY;
282 
283   /* Select the NOR device address */
284   if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
285   {
286     deviceaddress = NOR_MEMORY_ADRESS1;
287   }
288   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
289   {
290     deviceaddress = NOR_MEMORY_ADRESS2;
291   }
292   else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
293   {
294     deviceaddress = NOR_MEMORY_ADRESS3;
295   }
296   else /* FMC_NORSRAM_BANK4 */
297   {
298     deviceaddress = NOR_MEMORY_ADRESS4;
299   }
300 
301   /* Get the value of the command set */
302   NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
303   hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET);
304 
305   return HAL_NOR_ReturnToReadMode(hnor);
306 }
307 
308 /**
309   * @brief  Perform NOR memory De-Initialization sequence
310   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
311   *                the configuration information for NOR module.
312   * @retval HAL status
313   */
HAL_NOR_DeInit(NOR_HandleTypeDef * hnor)314 HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)
315 {
316 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
317   if (hnor->MspDeInitCallback == NULL)
318   {
319     hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
320   }
321 
322   /* DeInit the low level hardware */
323   hnor->MspDeInitCallback(hnor);
324 #else
325   /* De-Initialize the low level hardware (MSP) */
326   HAL_NOR_MspDeInit(hnor);
327 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
328 
329   /* Configure the NOR registers with their reset values */
330   (void)FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
331 
332   /* Reset the NOR controller state */
333   hnor->State = HAL_NOR_STATE_RESET;
334 
335   /* Release Lock */
336   __HAL_UNLOCK(hnor);
337 
338   return HAL_OK;
339 }
340 
341 /**
342   * @brief  NOR MSP Init
343   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
344   *                the configuration information for NOR module.
345   * @retval None
346   */
HAL_NOR_MspInit(NOR_HandleTypeDef * hnor)347 __weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
348 {
349   /* Prevent unused argument(s) compilation warning */
350   UNUSED(hnor);
351 
352   /* NOTE : This function Should not be modified, when the callback is needed,
353             the HAL_NOR_MspInit could be implemented in the user file
354    */
355 }
356 
357 /**
358   * @brief  NOR MSP DeInit
359   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
360   *                the configuration information for NOR module.
361   * @retval None
362   */
HAL_NOR_MspDeInit(NOR_HandleTypeDef * hnor)363 __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
364 {
365   /* Prevent unused argument(s) compilation warning */
366   UNUSED(hnor);
367 
368   /* NOTE : This function Should not be modified, when the callback is needed,
369             the HAL_NOR_MspDeInit could be implemented in the user file
370    */
371 }
372 
373 /**
374   * @brief  NOR MSP Wait for Ready/Busy signal
375   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
376   *                the configuration information for NOR module.
377   * @param  Timeout Maximum timeout value
378   * @retval None
379   */
HAL_NOR_MspWait(NOR_HandleTypeDef * hnor,uint32_t Timeout)380 __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
381 {
382   /* Prevent unused argument(s) compilation warning */
383   UNUSED(hnor);
384   UNUSED(Timeout);
385 
386   /* NOTE : This function Should not be modified, when the callback is needed,
387             the HAL_NOR_MspWait could be implemented in the user file
388    */
389 }
390 
391 /**
392   * @}
393   */
394 
395 /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
396   * @brief    Input Output and memory control functions
397   *
398   @verbatim
399   ==============================================================================
400                 ##### NOR Input and Output functions #####
401   ==============================================================================
402   [..]
403     This section provides functions allowing to use and control the NOR memory
404 
405 @endverbatim
406   * @{
407   */
408 
409 /**
410   * @brief  Read NOR flash IDs
411   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
412   *                the configuration information for NOR module.
413   * @param  pNOR_ID  pointer to NOR ID structure
414   * @retval HAL status
415   */
HAL_NOR_Read_ID(NOR_HandleTypeDef * hnor,NOR_IDTypeDef * pNOR_ID)416 HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
417 {
418   uint32_t deviceaddress;
419   HAL_NOR_StateTypeDef state;
420   HAL_StatusTypeDef status = HAL_OK;
421 
422   /* Check the NOR controller state */
423   state = hnor->State;
424   if (state == HAL_NOR_STATE_BUSY)
425   {
426     return HAL_BUSY;
427   }
428   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
429   {
430     /* Process Locked */
431     __HAL_LOCK(hnor);
432 
433     /* Update the NOR controller state */
434     hnor->State = HAL_NOR_STATE_BUSY;
435 
436     /* Select the NOR device address */
437     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
438     {
439       deviceaddress = NOR_MEMORY_ADRESS1;
440     }
441     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
442     {
443       deviceaddress = NOR_MEMORY_ADRESS2;
444     }
445     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
446     {
447       deviceaddress = NOR_MEMORY_ADRESS3;
448     }
449     else /* FMC_NORSRAM_BANK4 */
450     {
451       deviceaddress = NOR_MEMORY_ADRESS4;
452     }
453 
454     /* Send read ID command */
455     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
456     {
457       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
458       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
459       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
460     }
461     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
462     {
463       NOR_WRITE(deviceaddress, NOR_CMD_DATA_AUTO_SELECT);
464     }
465     else
466     {
467       /* Primary command set not supported by the driver */
468       status = HAL_ERROR;
469     }
470 
471     if (status != HAL_ERROR)
472     {
473       /* Read the NOR IDs */
474       pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
475       pNOR_ID->Device_Code1      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
476                                                                      DEVICE_CODE1_ADDR);
477       pNOR_ID->Device_Code2      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
478                                                                      DEVICE_CODE2_ADDR);
479       pNOR_ID->Device_Code3      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth,
480                                                                      DEVICE_CODE3_ADDR);
481     }
482 
483     /* Check the NOR controller state */
484     hnor->State = state;
485 
486     /* Process unlocked */
487     __HAL_UNLOCK(hnor);
488   }
489   else
490   {
491     return HAL_ERROR;
492   }
493 
494   return status;
495 }
496 
497 /**
498   * @brief  Returns the NOR memory to Read mode.
499   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
500   *                the configuration information for NOR module.
501   * @retval HAL status
502   */
HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef * hnor)503 HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
504 {
505   uint32_t deviceaddress;
506   HAL_NOR_StateTypeDef state;
507   HAL_StatusTypeDef status = HAL_OK;
508 
509   /* Check the NOR controller state */
510   state = hnor->State;
511   if (state == HAL_NOR_STATE_BUSY)
512   {
513     return HAL_BUSY;
514   }
515   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
516   {
517     /* Process Locked */
518     __HAL_LOCK(hnor);
519 
520     /* Update the NOR controller state */
521     hnor->State = HAL_NOR_STATE_BUSY;
522 
523     /* Select the NOR device address */
524     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
525     {
526       deviceaddress = NOR_MEMORY_ADRESS1;
527     }
528     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
529     {
530       deviceaddress = NOR_MEMORY_ADRESS2;
531     }
532     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
533     {
534       deviceaddress = NOR_MEMORY_ADRESS3;
535     }
536     else /* FMC_NORSRAM_BANK4 */
537     {
538       deviceaddress = NOR_MEMORY_ADRESS4;
539     }
540 
541     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
542     {
543       NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
544     }
545     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
546     {
547       NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
548     }
549     else
550     {
551       /* Primary command set not supported by the driver */
552       status = HAL_ERROR;
553     }
554 
555     /* Check the NOR controller state */
556     hnor->State = state;
557 
558     /* Process unlocked */
559     __HAL_UNLOCK(hnor);
560   }
561   else
562   {
563     return HAL_ERROR;
564   }
565 
566   return status;
567 }
568 
569 /**
570   * @brief  Read data from NOR memory
571   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
572   *                the configuration information for NOR module.
573   * @param  pAddress pointer to Device address
574   * @param  pData  pointer to read data
575   * @retval HAL status
576   */
HAL_NOR_Read(NOR_HandleTypeDef * hnor,uint32_t * pAddress,uint16_t * pData)577 HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
578 {
579   uint32_t deviceaddress;
580   HAL_NOR_StateTypeDef state;
581   HAL_StatusTypeDef status = HAL_OK;
582 
583   /* Check the NOR controller state */
584   state = hnor->State;
585   if (state == HAL_NOR_STATE_BUSY)
586   {
587     return HAL_BUSY;
588   }
589   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
590   {
591     /* Process Locked */
592     __HAL_LOCK(hnor);
593 
594     /* Update the NOR controller state */
595     hnor->State = HAL_NOR_STATE_BUSY;
596 
597     /* Select the NOR device address */
598     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
599     {
600       deviceaddress = NOR_MEMORY_ADRESS1;
601     }
602     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
603     {
604       deviceaddress = NOR_MEMORY_ADRESS2;
605     }
606     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
607     {
608       deviceaddress = NOR_MEMORY_ADRESS3;
609     }
610     else /* FMC_NORSRAM_BANK4 */
611     {
612       deviceaddress = NOR_MEMORY_ADRESS4;
613     }
614 
615     /* Send read data command */
616     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
617     {
618       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
619       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
620       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
621     }
622     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
623     {
624       NOR_WRITE(pAddress, NOR_CMD_READ_ARRAY);
625     }
626     else
627     {
628       /* Primary command set not supported by the driver */
629       status = HAL_ERROR;
630     }
631 
632     if (status != HAL_ERROR)
633     {
634       /* Read the data */
635       *pData = (uint16_t)(*(__IO uint32_t *)pAddress);
636     }
637 
638     /* Check the NOR controller state */
639     hnor->State = state;
640 
641     /* Process unlocked */
642     __HAL_UNLOCK(hnor);
643   }
644   else
645   {
646     return HAL_ERROR;
647   }
648 
649   return status;
650 }
651 
652 /**
653   * @brief  Program data to NOR memory
654   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
655   *                the configuration information for NOR module.
656   * @param  pAddress Device address
657   * @param  pData  pointer to the data to write
658   * @retval HAL status
659   */
HAL_NOR_Program(NOR_HandleTypeDef * hnor,uint32_t * pAddress,uint16_t * pData)660 HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
661 {
662   uint32_t deviceaddress;
663   HAL_StatusTypeDef status = HAL_OK;
664 
665   /* Check the NOR controller state */
666   if (hnor->State == HAL_NOR_STATE_BUSY)
667   {
668     return HAL_BUSY;
669   }
670   else if (hnor->State == HAL_NOR_STATE_READY)
671   {
672     /* Process Locked */
673     __HAL_LOCK(hnor);
674 
675     /* Update the NOR controller state */
676     hnor->State = HAL_NOR_STATE_BUSY;
677 
678     /* Select the NOR device address */
679     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
680     {
681       deviceaddress = NOR_MEMORY_ADRESS1;
682     }
683     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
684     {
685       deviceaddress = NOR_MEMORY_ADRESS2;
686     }
687     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
688     {
689       deviceaddress = NOR_MEMORY_ADRESS3;
690     }
691     else /* FMC_NORSRAM_BANK4 */
692     {
693       deviceaddress = NOR_MEMORY_ADRESS4;
694     }
695 
696     /* Send program data command */
697     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
698     {
699       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
700       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
701       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
702     }
703     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
704     {
705       NOR_WRITE(pAddress, NOR_CMD_WORD_PROGRAM);
706     }
707     else
708     {
709       /* Primary command set not supported by the driver */
710       status = HAL_ERROR;
711     }
712 
713     if (status != HAL_ERROR)
714     {
715       /* Write the data */
716       NOR_WRITE(pAddress, *pData);
717     }
718 
719     /* Check the NOR controller state */
720     hnor->State = HAL_NOR_STATE_READY;
721 
722     /* Process unlocked */
723     __HAL_UNLOCK(hnor);
724   }
725   else
726   {
727     return HAL_ERROR;
728   }
729 
730   return status;
731 }
732 
733 /**
734   * @brief  Reads a half-word buffer from the NOR memory.
735   * @param  hnor pointer to the NOR handle
736   * @param  uwAddress NOR memory internal address to read from.
737   * @param  pData pointer to the buffer that receives the data read from the
738   *         NOR memory.
739   * @param  uwBufferSize  number of Half word to read.
740   * @retval HAL status
741   */
HAL_NOR_ReadBuffer(NOR_HandleTypeDef * hnor,uint32_t uwAddress,uint16_t * pData,uint32_t uwBufferSize)742 HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
743                                      uint32_t uwBufferSize)
744 {
745   uint32_t deviceaddress;
746   uint32_t size = uwBufferSize;
747   uint32_t address = uwAddress;
748   uint16_t *data = pData;
749   HAL_NOR_StateTypeDef state;
750   HAL_StatusTypeDef status = HAL_OK;
751 
752   /* Check the NOR controller state */
753   state = hnor->State;
754   if (state == HAL_NOR_STATE_BUSY)
755   {
756     return HAL_BUSY;
757   }
758   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
759   {
760     /* Process Locked */
761     __HAL_LOCK(hnor);
762 
763     /* Update the NOR controller state */
764     hnor->State = HAL_NOR_STATE_BUSY;
765 
766     /* Select the NOR device address */
767     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
768     {
769       deviceaddress = NOR_MEMORY_ADRESS1;
770     }
771     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
772     {
773       deviceaddress = NOR_MEMORY_ADRESS2;
774     }
775     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
776     {
777       deviceaddress = NOR_MEMORY_ADRESS3;
778     }
779     else /* FMC_NORSRAM_BANK4 */
780     {
781       deviceaddress = NOR_MEMORY_ADRESS4;
782     }
783 
784     /* Send read data command */
785     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
786     {
787       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
788       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
789       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET);
790     }
791     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
792     {
793       NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY);
794     }
795     else
796     {
797       /* Primary command set not supported by the driver */
798       status = HAL_ERROR;
799     }
800 
801     if (status != HAL_ERROR)
802     {
803       /* Read buffer */
804       while (size > 0U)
805       {
806         *data = *(__IO uint16_t *)address;
807         data++;
808         address += 2U;
809         size--;
810       }
811     }
812 
813     /* Check the NOR controller state */
814     hnor->State = state;
815 
816     /* Process unlocked */
817     __HAL_UNLOCK(hnor);
818   }
819   else
820   {
821     return HAL_ERROR;
822   }
823 
824   return status;
825 }
826 
827 /**
828   * @brief  Writes a half-word buffer to the NOR memory. This function must be used
829             only with S29GL128P NOR memory.
830   * @param  hnor pointer to the NOR handle
831   * @param  uwAddress NOR memory internal start write address
832   * @param  pData pointer to source data buffer.
833   * @param  uwBufferSize Size of the buffer to write
834   * @retval HAL status
835   */
HAL_NOR_ProgramBuffer(NOR_HandleTypeDef * hnor,uint32_t uwAddress,uint16_t * pData,uint32_t uwBufferSize)836 HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData,
837                                         uint32_t uwBufferSize)
838 {
839   uint16_t *p_currentaddress;
840   const uint16_t *p_endaddress;
841   uint16_t *data = pData;
842   uint32_t deviceaddress;
843   HAL_StatusTypeDef status = HAL_OK;
844 
845   /* Check the NOR controller state */
846   if (hnor->State == HAL_NOR_STATE_BUSY)
847   {
848     return HAL_BUSY;
849   }
850   else if (hnor->State == HAL_NOR_STATE_READY)
851   {
852     /* Process Locked */
853     __HAL_LOCK(hnor);
854 
855     /* Update the NOR controller state */
856     hnor->State = HAL_NOR_STATE_BUSY;
857 
858     /* Select the NOR device address */
859     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
860     {
861       deviceaddress = NOR_MEMORY_ADRESS1;
862     }
863     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
864     {
865       deviceaddress = NOR_MEMORY_ADRESS2;
866     }
867     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
868     {
869       deviceaddress = NOR_MEMORY_ADRESS3;
870     }
871     else /* FMC_NORSRAM_BANK4 */
872     {
873       deviceaddress = NOR_MEMORY_ADRESS4;
874     }
875 
876     /* Initialize variables */
877     p_currentaddress  = (uint16_t *)(deviceaddress + uwAddress);
878     p_endaddress      = (uint16_t *)(deviceaddress + uwAddress + (2U * (uwBufferSize - 1U)));
879 
880     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
881     {
882       /* Issue unlock command sequence */
883       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
884       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
885 
886       /* Write Buffer Load Command */
887       NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG);
888       NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
889     }
890     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
891     {
892       /* Write Buffer Load Command */
893       NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_BUFFERED_PROGRAM);
894       NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U));
895     }
896     else
897     {
898       /* Primary command set not supported by the driver */
899       status = HAL_ERROR;
900     }
901 
902     if (status != HAL_ERROR)
903     {
904       /* Load Data into NOR Buffer */
905       while (p_currentaddress <= p_endaddress)
906       {
907         NOR_WRITE(p_currentaddress, *data);
908 
909         data++;
910         p_currentaddress ++;
911       }
912 
913       if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
914       {
915         NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
916       }
917       else /* => hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET */
918       {
919         NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_CONFIRM);
920       }
921     }
922 
923     /* Check the NOR controller state */
924     hnor->State = HAL_NOR_STATE_READY;
925 
926     /* Process unlocked */
927     __HAL_UNLOCK(hnor);
928   }
929   else
930   {
931     return HAL_ERROR;
932   }
933 
934   return status;
935 
936 }
937 
938 /**
939   * @brief  Erase the specified block of the NOR memory
940   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
941   *                the configuration information for NOR module.
942   * @param  BlockAddress  Block to erase address
943   * @param  Address Device address
944   * @retval HAL status
945   */
HAL_NOR_Erase_Block(NOR_HandleTypeDef * hnor,uint32_t BlockAddress,uint32_t Address)946 HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
947 {
948   uint32_t deviceaddress;
949   HAL_StatusTypeDef status = HAL_OK;
950 
951   /* Check the NOR controller state */
952   if (hnor->State == HAL_NOR_STATE_BUSY)
953   {
954     return HAL_BUSY;
955   }
956   else if (hnor->State == HAL_NOR_STATE_READY)
957   {
958     /* Process Locked */
959     __HAL_LOCK(hnor);
960 
961     /* Update the NOR controller state */
962     hnor->State = HAL_NOR_STATE_BUSY;
963 
964     /* Select the NOR device address */
965     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
966     {
967       deviceaddress = NOR_MEMORY_ADRESS1;
968     }
969     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
970     {
971       deviceaddress = NOR_MEMORY_ADRESS2;
972     }
973     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
974     {
975       deviceaddress = NOR_MEMORY_ADRESS3;
976     }
977     else /* FMC_NORSRAM_BANK4 */
978     {
979       deviceaddress = NOR_MEMORY_ADRESS4;
980     }
981 
982     /* Send block erase command sequence */
983     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
984     {
985       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
986       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
987       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
988                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
989       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
990                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
991       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
992                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
993       NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
994     }
995     else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
996     {
997       NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_UNLOCK);
998       NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
999       NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_ERASE);
1000       NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
1001     }
1002     else
1003     {
1004       /* Primary command set not supported by the driver */
1005       status = HAL_ERROR;
1006     }
1007 
1008     /* Check the NOR memory status and update the controller state */
1009     hnor->State = HAL_NOR_STATE_READY;
1010 
1011     /* Process unlocked */
1012     __HAL_UNLOCK(hnor);
1013   }
1014   else
1015   {
1016     return HAL_ERROR;
1017   }
1018 
1019   return status;
1020 
1021 }
1022 
1023 /**
1024   * @brief  Erase the entire NOR chip.
1025   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1026   *                the configuration information for NOR module.
1027   * @param  Address  Device address
1028   * @retval HAL status
1029   */
HAL_NOR_Erase_Chip(NOR_HandleTypeDef * hnor,uint32_t Address)1030 HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
1031 {
1032   uint32_t deviceaddress;
1033   HAL_StatusTypeDef status = HAL_OK;
1034   UNUSED(Address);
1035 
1036   /* Check the NOR controller state */
1037   if (hnor->State == HAL_NOR_STATE_BUSY)
1038   {
1039     return HAL_BUSY;
1040   }
1041   else if (hnor->State == HAL_NOR_STATE_READY)
1042   {
1043     /* Process Locked */
1044     __HAL_LOCK(hnor);
1045 
1046     /* Update the NOR controller state */
1047     hnor->State = HAL_NOR_STATE_BUSY;
1048 
1049     /* Select the NOR device address */
1050     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
1051     {
1052       deviceaddress = NOR_MEMORY_ADRESS1;
1053     }
1054     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
1055     {
1056       deviceaddress = NOR_MEMORY_ADRESS2;
1057     }
1058     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
1059     {
1060       deviceaddress = NOR_MEMORY_ADRESS3;
1061     }
1062     else /* FMC_NORSRAM_BANK4 */
1063     {
1064       deviceaddress = NOR_MEMORY_ADRESS4;
1065     }
1066 
1067     /* Send NOR chip erase command sequence */
1068     if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
1069     {
1070       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
1071       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
1072       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
1073                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
1074       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
1075                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
1076       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
1077                 NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
1078       NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
1079     }
1080     else
1081     {
1082       /* Primary command set not supported by the driver */
1083       status = HAL_ERROR;
1084     }
1085 
1086     /* Check the NOR memory status and update the controller state */
1087     hnor->State = HAL_NOR_STATE_READY;
1088 
1089     /* Process unlocked */
1090     __HAL_UNLOCK(hnor);
1091   }
1092   else
1093   {
1094     return HAL_ERROR;
1095   }
1096 
1097   return status;
1098 }
1099 
1100 /**
1101   * @brief  Read NOR flash CFI IDs
1102   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1103   *                the configuration information for NOR module.
1104   * @param  pNOR_CFI  pointer to NOR CFI IDs structure
1105   * @retval HAL status
1106   */
HAL_NOR_Read_CFI(NOR_HandleTypeDef * hnor,NOR_CFITypeDef * pNOR_CFI)1107 HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
1108 {
1109   uint32_t deviceaddress;
1110   HAL_NOR_StateTypeDef state;
1111 
1112   /* Check the NOR controller state */
1113   state = hnor->State;
1114   if (state == HAL_NOR_STATE_BUSY)
1115   {
1116     return HAL_BUSY;
1117   }
1118   else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED))
1119   {
1120     /* Process Locked */
1121     __HAL_LOCK(hnor);
1122 
1123     /* Update the NOR controller state */
1124     hnor->State = HAL_NOR_STATE_BUSY;
1125 
1126     /* Select the NOR device address */
1127     if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
1128     {
1129       deviceaddress = NOR_MEMORY_ADRESS1;
1130     }
1131     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
1132     {
1133       deviceaddress = NOR_MEMORY_ADRESS2;
1134     }
1135     else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
1136     {
1137       deviceaddress = NOR_MEMORY_ADRESS3;
1138     }
1139     else /* FMC_NORSRAM_BANK4 */
1140     {
1141       deviceaddress = NOR_MEMORY_ADRESS4;
1142     }
1143 
1144     /* Send read CFI query command */
1145     NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
1146 
1147     /* read the NOR CFI information */
1148     pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
1149     pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
1150     pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
1151     pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
1152 
1153     /* Check the NOR controller state */
1154     hnor->State = state;
1155 
1156     /* Process unlocked */
1157     __HAL_UNLOCK(hnor);
1158   }
1159   else
1160   {
1161     return HAL_ERROR;
1162   }
1163 
1164   return HAL_OK;
1165 }
1166 
1167 #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1)
1168 /**
1169   * @brief  Register a User NOR Callback
1170   *         To be used instead of the weak (surcharged) predefined callback
1171   * @param hnor : NOR handle
1172   * @param CallbackId : ID of the callback to be registered
1173   *        This parameter can be one of the following values:
1174   *          @arg @ref HAL_NOR_MSP_INIT_CB_ID       NOR MspInit callback ID
1175   *          @arg @ref HAL_NOR_MSP_DEINIT_CB_ID     NOR MspDeInit callback ID
1176   * @param pCallback : pointer to the Callback function
1177   * @retval status
1178   */
HAL_NOR_RegisterCallback(NOR_HandleTypeDef * hnor,HAL_NOR_CallbackIDTypeDef CallbackId,pNOR_CallbackTypeDef pCallback)1179 HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId,
1180                                            pNOR_CallbackTypeDef pCallback)
1181 {
1182   HAL_StatusTypeDef status = HAL_OK;
1183   HAL_NOR_StateTypeDef state;
1184 
1185   if (pCallback == NULL)
1186   {
1187     return HAL_ERROR;
1188   }
1189 
1190   /* Process locked */
1191   __HAL_LOCK(hnor);
1192 
1193   state = hnor->State;
1194   if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
1195   {
1196     switch (CallbackId)
1197     {
1198       case HAL_NOR_MSP_INIT_CB_ID :
1199         hnor->MspInitCallback = pCallback;
1200         break;
1201       case HAL_NOR_MSP_DEINIT_CB_ID :
1202         hnor->MspDeInitCallback = pCallback;
1203         break;
1204       default :
1205         /* update return status */
1206         status =  HAL_ERROR;
1207         break;
1208     }
1209   }
1210   else
1211   {
1212     /* update return status */
1213     status =  HAL_ERROR;
1214   }
1215 
1216   /* Release Lock */
1217   __HAL_UNLOCK(hnor);
1218   return status;
1219 }
1220 
1221 /**
1222   * @brief  Unregister a User NOR Callback
1223   *         NOR Callback is redirected to the weak (surcharged) predefined callback
1224   * @param hnor : NOR handle
1225   * @param CallbackId : ID of the callback to be unregistered
1226   *        This parameter can be one of the following values:
1227   *          @arg @ref HAL_NOR_MSP_INIT_CB_ID       NOR MspInit callback ID
1228   *          @arg @ref HAL_NOR_MSP_DEINIT_CB_ID     NOR MspDeInit callback ID
1229   * @retval status
1230   */
HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef * hnor,HAL_NOR_CallbackIDTypeDef CallbackId)1231 HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId)
1232 {
1233   HAL_StatusTypeDef status = HAL_OK;
1234   HAL_NOR_StateTypeDef state;
1235 
1236   /* Process locked */
1237   __HAL_LOCK(hnor);
1238 
1239   state = hnor->State;
1240   if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED))
1241   {
1242     switch (CallbackId)
1243     {
1244       case HAL_NOR_MSP_INIT_CB_ID :
1245         hnor->MspInitCallback = HAL_NOR_MspInit;
1246         break;
1247       case HAL_NOR_MSP_DEINIT_CB_ID :
1248         hnor->MspDeInitCallback = HAL_NOR_MspDeInit;
1249         break;
1250       default :
1251         /* update return status */
1252         status =  HAL_ERROR;
1253         break;
1254     }
1255   }
1256   else
1257   {
1258     /* update return status */
1259     status =  HAL_ERROR;
1260   }
1261 
1262   /* Release Lock */
1263   __HAL_UNLOCK(hnor);
1264   return status;
1265 }
1266 #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */
1267 
1268 /**
1269   * @}
1270   */
1271 
1272 /** @defgroup NOR_Exported_Functions_Group3 NOR Control functions
1273   *  @brief   management functions
1274   *
1275 @verbatim
1276   ==============================================================================
1277                         ##### NOR Control functions #####
1278   ==============================================================================
1279   [..]
1280     This subsection provides a set of functions allowing to control dynamically
1281     the NOR interface.
1282 
1283 @endverbatim
1284   * @{
1285   */
1286 
1287 /**
1288   * @brief  Enables dynamically NOR write operation.
1289   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1290   *                the configuration information for NOR module.
1291   * @retval HAL status
1292   */
HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef * hnor)1293 HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
1294 {
1295   /* Check the NOR controller state */
1296   if (hnor->State == HAL_NOR_STATE_PROTECTED)
1297   {
1298     /* Process Locked */
1299     __HAL_LOCK(hnor);
1300 
1301     /* Update the NOR controller state */
1302     hnor->State = HAL_NOR_STATE_BUSY;
1303 
1304     /* Enable write operation */
1305     (void)FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
1306 
1307     /* Update the NOR controller state */
1308     hnor->State = HAL_NOR_STATE_READY;
1309 
1310     /* Process unlocked */
1311     __HAL_UNLOCK(hnor);
1312   }
1313   else
1314   {
1315     return HAL_ERROR;
1316   }
1317 
1318   return HAL_OK;
1319 }
1320 
1321 /**
1322   * @brief  Disables dynamically NOR write operation.
1323   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1324   *                the configuration information for NOR module.
1325   * @retval HAL status
1326   */
HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef * hnor)1327 HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
1328 {
1329   /* Check the NOR controller state */
1330   if (hnor->State == HAL_NOR_STATE_READY)
1331   {
1332     /* Process Locked */
1333     __HAL_LOCK(hnor);
1334 
1335     /* Update the NOR controller state */
1336     hnor->State = HAL_NOR_STATE_BUSY;
1337 
1338     /* Disable write operation */
1339     (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
1340 
1341     /* Update the NOR controller state */
1342     hnor->State = HAL_NOR_STATE_PROTECTED;
1343 
1344     /* Process unlocked */
1345     __HAL_UNLOCK(hnor);
1346   }
1347   else
1348   {
1349     return HAL_ERROR;
1350   }
1351 
1352   return HAL_OK;
1353 }
1354 
1355 /**
1356   * @}
1357   */
1358 
1359 /** @defgroup NOR_Exported_Functions_Group4 NOR State functions
1360   *  @brief   Peripheral State functions
1361   *
1362 @verbatim
1363   ==============================================================================
1364                       ##### NOR State functions #####
1365   ==============================================================================
1366   [..]
1367     This subsection permits to get in run-time the status of the NOR controller
1368     and the data flow.
1369 
1370 @endverbatim
1371   * @{
1372   */
1373 
1374 /**
1375   * @brief  return the NOR controller state
1376   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1377   *                the configuration information for NOR module.
1378   * @retval NOR controller state
1379   */
HAL_NOR_GetState(NOR_HandleTypeDef * hnor)1380 HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
1381 {
1382   return hnor->State;
1383 }
1384 
1385 /**
1386   * @brief  Returns the NOR operation status.
1387   * @param  hnor pointer to a NOR_HandleTypeDef structure that contains
1388   *                the configuration information for NOR module.
1389   * @param  Address Device address
1390   * @param  Timeout NOR programming Timeout
1391   * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
1392   *         or HAL_NOR_STATUS_TIMEOUT
1393   */
HAL_NOR_GetStatus(NOR_HandleTypeDef * hnor,uint32_t Address,uint32_t Timeout)1394 HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
1395 {
1396   HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
1397   uint16_t tmpsr1;
1398   uint16_t tmpsr2;
1399   uint32_t tickstart;
1400 
1401   /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
1402   HAL_NOR_MspWait(hnor, Timeout);
1403 
1404   /* Get the NOR memory operation status -------------------------------------*/
1405 
1406   /* Get tick */
1407   tickstart = HAL_GetTick();
1408 
1409   if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
1410   {
1411     while ((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
1412     {
1413       /* Check for the Timeout */
1414       if (Timeout != HAL_MAX_DELAY)
1415       {
1416         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1417         {
1418           status = HAL_NOR_STATUS_TIMEOUT;
1419         }
1420       }
1421 
1422       /* Read NOR status register (DQ6 and DQ5) */
1423       tmpsr1 = *(__IO uint16_t *)Address;
1424       tmpsr2 = *(__IO uint16_t *)Address;
1425 
1426       /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
1427       if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
1428       {
1429         return HAL_NOR_STATUS_SUCCESS ;
1430       }
1431 
1432       if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
1433       {
1434         status = HAL_NOR_STATUS_ONGOING;
1435       }
1436 
1437       tmpsr1 = *(__IO uint16_t *)Address;
1438       tmpsr2 = *(__IO uint16_t *)Address;
1439 
1440       /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS  */
1441       if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6))
1442       {
1443         return HAL_NOR_STATUS_SUCCESS;
1444       }
1445       if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
1446       {
1447         return HAL_NOR_STATUS_ERROR;
1448       }
1449     }
1450   }
1451   else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
1452   {
1453     do
1454     {
1455       NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
1456       tmpsr2 = *(__IO uint16_t *)(Address);
1457 
1458       /* Check for the Timeout */
1459       if (Timeout != HAL_MAX_DELAY)
1460       {
1461         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1462         {
1463           return HAL_NOR_STATUS_TIMEOUT;
1464         }
1465       }
1466     } while ((tmpsr2 & NOR_MASK_STATUS_DQ7) == 0U);
1467 
1468     NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
1469     tmpsr1 = *(__IO uint16_t *)(Address);
1470     if ((tmpsr1  & (NOR_MASK_STATUS_DQ5 | NOR_MASK_STATUS_DQ4)) != 0U)
1471     {
1472       /* Clear the Status Register  */
1473       NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG);
1474       status = HAL_NOR_STATUS_ERROR;
1475     }
1476     else
1477     {
1478       status = HAL_NOR_STATUS_SUCCESS;
1479     }
1480   }
1481   else
1482   {
1483     /* Primary command set not supported by the driver */
1484     status = HAL_NOR_STATUS_ERROR;
1485   }
1486 
1487   /* Return the operation status */
1488   return status;
1489 }
1490 
1491 /**
1492   * @}
1493   */
1494 
1495 /**
1496   * @}
1497   */
1498 
1499 /**
1500   * @}
1501   */
1502 
1503 #endif /* HAL_NOR_MODULE_ENABLED */
1504 
1505 /**
1506   * @}
1507   */
1508 
1509 
1510 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1511