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