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