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