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