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