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