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