1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_nand.c
4   * @author  MCD Application Team
5   * @brief   NAND HAL module driver.
6   *          This file provides a generic firmware to drive NAND 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 NAND flash memories. It uses the FMC/FSMC layer functions to interface
27       with NAND devices. This driver is used as follows:
28 
29       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
30           with control and timing parameters for both common and attribute spaces.
31 
32       (+) Read NAND flash memory maker and device IDs using the function
33           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
34           structure declared by the function caller.
35 
36       (+) Access NAND flash memory by read/write operations using the functions
37           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
38           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
39           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
40           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
41           to read/write page(s)/spare area(s). These functions use specific device
42           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
43           structure. The read/write address information is contained by the Nand_Address_Typedef
44           structure passed as parameter.
45 
46       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
47 
48       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
49           The erase block address information is contained in the Nand_Address_Typedef
50           structure passed as parameter.
51 
52       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
53 
54       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
55           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
56           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
57 
58       (+) You can monitor the NAND device HAL state by calling the function
59           HAL_NAND_GetState()
60 
61     [..]
62       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
63           If a NAND flash device contains different operations and/or implementations,
64           it should be implemented separately.
65 
66     *** Callback registration ***
67     =============================================
68     [..]
69       The compilation define  USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
70       allows the user to configure dynamically the driver callbacks.
71 
72       Use Functions HAL_NAND_RegisterCallback() to register a user callback,
73       it allows to register following callbacks:
74         (+) MspInitCallback    : NAND MspInit.
75         (+) MspDeInitCallback  : NAND MspDeInit.
76       This function takes as parameters the HAL peripheral handle, the Callback ID
77       and a pointer to the user callback function.
78 
79       Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default
80       weak (surcharged) function. It allows to reset following callbacks:
81         (+) MspInitCallback    : NAND MspInit.
82         (+) MspDeInitCallback  : NAND MspDeInit.
83       This function) takes as parameters the HAL peripheral handle and the Callback ID.
84 
85       By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
86       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
87       Exception done for MspInit and MspDeInit callbacks that are respectively
88       reset to the legacy weak (surcharged) functions in the HAL_NAND_Init
89       and  HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
90       If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit
91       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
92 
93       Callbacks can be registered/unregistered in READY state only.
94       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
95       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
96       during the Init/DeInit.
97       In that case first register the MspInit/MspDeInit user callbacks
98       using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit
99       or HAL_NAND_Init function.
100 
101       When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
102       not defined, the callback registering feature is not available
103       and weak (surcharged) callbacks are used.
104 
105   @endverbatim
106   ******************************************************************************
107   */
108 
109 /* Includes ------------------------------------------------------------------*/
110 #include "stm32f4xx_hal.h"
111 
112 #if defined(FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
113 
114 /** @addtogroup STM32F4xx_HAL_Driver
115   * @{
116   */
117 
118 #ifdef HAL_NAND_MODULE_ENABLED
119 
120 /** @defgroup NAND NAND
121   * @brief NAND HAL module driver
122   * @{
123   */
124 
125 /* Private typedef -----------------------------------------------------------*/
126 /* Private Constants ------------------------------------------------------------*/
127 /* Private macro -------------------------------------------------------------*/
128 /* Private variables ---------------------------------------------------------*/
129 /* Private function prototypes -----------------------------------------------*/
130 /* Exported functions ---------------------------------------------------------*/
131 
132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
133   * @{
134   */
135 
136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
137   * @brief    Initialization and Configuration functions
138   *
139   @verbatim
140   ==============================================================================
141             ##### NAND Initialization and de-initialization functions #####
142   ==============================================================================
143   [..]
144     This section provides functions allowing to initialize/de-initialize
145     the NAND memory
146 
147 @endverbatim
148   * @{
149   */
150 
151 /**
152   * @brief  Perform NAND memory Initialization sequence
153   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
154   *                the configuration information for NAND module.
155   * @param  ComSpace_Timing pointer to Common space timing structure
156   * @param  AttSpace_Timing pointer to Attribute space timing structure
157   * @retval HAL status
158   */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)159 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
160                                  FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
161 {
162   /* Check the NAND handle state */
163   if (hnand == NULL)
164   {
165     return HAL_ERROR;
166   }
167 
168   if (hnand->State == HAL_NAND_STATE_RESET)
169   {
170     /* Allocate lock resource and initialize it */
171     hnand->Lock = HAL_UNLOCKED;
172 
173 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
174     if (hnand->MspInitCallback == NULL)
175     {
176       hnand->MspInitCallback = HAL_NAND_MspInit;
177     }
178     hnand->ItCallback = HAL_NAND_ITCallback;
179 
180     /* Init the low level hardware */
181     hnand->MspInitCallback(hnand);
182 #else
183     /* Initialize the low level hardware (MSP) */
184     HAL_NAND_MspInit(hnand);
185 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
186   }
187 
188   /* Initialize NAND control Interface */
189   (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
190 
191   /* Initialize NAND common space timing Interface */
192   (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
193 
194   /* Initialize NAND attribute space timing Interface */
195   (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
196 
197   /* Enable the NAND device */
198 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
199   __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
200 #else
201   __FMC_NAND_ENABLE(hnand->Instance);
202 #endif
203 
204   /* Update the NAND controller state */
205   hnand->State = HAL_NAND_STATE_READY;
206 
207   return HAL_OK;
208 }
209 
210 /**
211   * @brief  Perform NAND memory De-Initialization sequence
212   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
213   *                the configuration information for NAND module.
214   * @retval HAL status
215   */
HAL_NAND_DeInit(NAND_HandleTypeDef * hnand)216 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
217 {
218 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
219   if (hnand->MspDeInitCallback == NULL)
220   {
221     hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
222   }
223 
224   /* DeInit the low level hardware */
225   hnand->MspDeInitCallback(hnand);
226 #else
227   /* Initialize the low level hardware (MSP) */
228   HAL_NAND_MspDeInit(hnand);
229 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
230 
231   /* Configure the NAND registers with their reset values */
232   (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
233 
234   /* Reset the NAND controller state */
235   hnand->State = HAL_NAND_STATE_RESET;
236 
237   /* Release Lock */
238   __HAL_UNLOCK(hnand);
239 
240   return HAL_OK;
241 }
242 
243 /**
244   * @brief  NAND MSP Init
245   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
246   *                the configuration information for NAND module.
247   * @retval None
248   */
HAL_NAND_MspInit(NAND_HandleTypeDef * hnand)249 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
250 {
251   /* Prevent unused argument(s) compilation warning */
252   UNUSED(hnand);
253 
254   /* NOTE : This function Should not be modified, when the callback is needed,
255             the HAL_NAND_MspInit could be implemented in the user file
256    */
257 }
258 
259 /**
260   * @brief  NAND MSP DeInit
261   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
262   *                the configuration information for NAND module.
263   * @retval None
264   */
HAL_NAND_MspDeInit(NAND_HandleTypeDef * hnand)265 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
266 {
267   /* Prevent unused argument(s) compilation warning */
268   UNUSED(hnand);
269 
270   /* NOTE : This function Should not be modified, when the callback is needed,
271             the HAL_NAND_MspDeInit could be implemented in the user file
272    */
273 }
274 
275 
276 /**
277   * @brief  This function handles NAND device interrupt request.
278   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
279   *                the configuration information for NAND module.
280   * @retval HAL status
281   */
HAL_NAND_IRQHandler(NAND_HandleTypeDef * hnand)282 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
283 {
284   /* Check NAND interrupt Rising edge flag */
285   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
286   {
287     /* NAND interrupt callback*/
288 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
289     hnand->ItCallback(hnand);
290 #else
291     HAL_NAND_ITCallback(hnand);
292 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
293 
294     /* Clear NAND interrupt Rising edge pending bit */
295 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
296     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
297 #else
298     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
299 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
300   }
301 
302   /* Check NAND interrupt Level flag */
303   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
304   {
305     /* NAND interrupt callback*/
306 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
307     hnand->ItCallback(hnand);
308 #else
309     HAL_NAND_ITCallback(hnand);
310 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
311 
312     /* Clear NAND interrupt Level pending bit */
313 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
314     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
315 #else
316     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
317 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
318   }
319 
320   /* Check NAND interrupt Falling edge flag */
321   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
322   {
323     /* NAND interrupt callback*/
324 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
325     hnand->ItCallback(hnand);
326 #else
327     HAL_NAND_ITCallback(hnand);
328 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
329 
330     /* Clear NAND interrupt Falling edge pending bit */
331 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
332     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
333 #else
334     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
335 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
336   }
337 
338   /* Check NAND interrupt FIFO empty flag */
339   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
340   {
341     /* NAND interrupt callback*/
342 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
343     hnand->ItCallback(hnand);
344 #else
345     HAL_NAND_ITCallback(hnand);
346 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
347 
348     /* Clear NAND interrupt FIFO empty pending bit */
349 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
350     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
351 #else
352     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
353 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
354   }
355 
356 }
357 
358 /**
359   * @brief  NAND interrupt feature callback
360   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
361   *                the configuration information for NAND module.
362   * @retval None
363   */
HAL_NAND_ITCallback(NAND_HandleTypeDef * hnand)364 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
365 {
366   /* Prevent unused argument(s) compilation warning */
367   UNUSED(hnand);
368 
369   /* NOTE : This function Should not be modified, when the callback is needed,
370             the HAL_NAND_ITCallback could be implemented in the user file
371    */
372 }
373 
374 /**
375   * @}
376   */
377 
378 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
379   * @brief    Input Output and memory control functions
380   *
381   @verbatim
382   ==============================================================================
383                     ##### NAND Input and Output functions #####
384   ==============================================================================
385   [..]
386     This section provides functions allowing to use and control the NAND
387     memory
388 
389 @endverbatim
390   * @{
391   */
392 
393 /**
394   * @brief  Read the NAND memory electronic signature
395   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
396   *                the configuration information for NAND module.
397   * @param  pNAND_ID NAND ID structure
398   * @retval HAL status
399   */
HAL_NAND_Read_ID(NAND_HandleTypeDef * hnand,NAND_IDTypeDef * pNAND_ID)400 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
401 {
402   __IO uint32_t data = 0;
403   __IO uint32_t data1 = 0;
404   uint32_t deviceaddress;
405 
406   /* Check the NAND controller state */
407   if (hnand->State == HAL_NAND_STATE_BUSY)
408   {
409     return HAL_BUSY;
410   }
411   else if (hnand->State == HAL_NAND_STATE_READY)
412   {
413     /* Process Locked */
414     __HAL_LOCK(hnand);
415 
416     /* Update the NAND controller state */
417     hnand->State = HAL_NAND_STATE_BUSY;
418 
419     /* Identify the device address */
420 #if defined(FMC_Bank2_3)
421     if (hnand->Init.NandBank == FMC_NAND_BANK2)
422     {
423       deviceaddress = NAND_DEVICE1;
424     }
425     else
426     {
427       deviceaddress = NAND_DEVICE2;
428     }
429 #else
430     deviceaddress = NAND_DEVICE;
431 #endif
432 
433     /* Send Read ID command sequence */
434     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
435     __DSB();
436     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
437     __DSB();
438 
439     /* Read the electronic signature from NAND flash */
440 #ifdef FSMC_PCR2_PWID
441     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
442 #else /* FMC_PCR2_PWID is defined */
443     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
444 #endif
445     {
446       data = *(__IO uint32_t *)deviceaddress;
447 
448       /* Return the data read */
449       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
450       pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
451       pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
452       pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
453     }
454     else
455     {
456       data = *(__IO uint32_t *)deviceaddress;
457       data1 = *((__IO uint32_t *)deviceaddress + 4);
458 
459       /* Return the data read */
460       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
461       pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
462       pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
463       pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
464     }
465 
466     /* Update the NAND controller state */
467     hnand->State = HAL_NAND_STATE_READY;
468 
469     /* Process unlocked */
470     __HAL_UNLOCK(hnand);
471   }
472   else
473   {
474     return HAL_ERROR;
475   }
476 
477   return HAL_OK;
478 }
479 
480 /**
481   * @brief  NAND memory reset
482   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
483   *                the configuration information for NAND module.
484   * @retval HAL status
485   */
HAL_NAND_Reset(NAND_HandleTypeDef * hnand)486 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
487 {
488   uint32_t deviceaddress;
489 
490   /* Check the NAND controller state */
491   if (hnand->State == HAL_NAND_STATE_BUSY)
492   {
493     return HAL_BUSY;
494   }
495   else if (hnand->State == HAL_NAND_STATE_READY)
496   {
497     /* Process Locked */
498     __HAL_LOCK(hnand);
499 
500     /* Update the NAND controller state */
501     hnand->State = HAL_NAND_STATE_BUSY;
502 
503     /* Identify the device address */
504 #if defined(FMC_Bank2_3)
505     if (hnand->Init.NandBank == FMC_NAND_BANK2)
506     {
507       deviceaddress = NAND_DEVICE1;
508     }
509     else
510     {
511       deviceaddress = NAND_DEVICE2;
512     }
513 #else
514     deviceaddress = NAND_DEVICE;
515 #endif
516 
517     /* Send NAND reset command */
518     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
519 
520     /* Update the NAND controller state */
521     hnand->State = HAL_NAND_STATE_READY;
522 
523     /* Process unlocked */
524     __HAL_UNLOCK(hnand);
525   }
526   else
527   {
528     return HAL_ERROR;
529   }
530 
531   return HAL_OK;
532 
533 }
534 
535 /**
536   * @brief  Configure the device: Enter the physical parameters of the device
537   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
538   *                the configuration information for NAND module.
539   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
540   * @retval HAL status
541   */
HAL_NAND_ConfigDevice(NAND_HandleTypeDef * hnand,NAND_DeviceConfigTypeDef * pDeviceConfig)542 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
543 {
544   hnand->Config.PageSize           = pDeviceConfig->PageSize;
545   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
546   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
547   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
548   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
549   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
550   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
551 
552   return HAL_OK;
553 }
554 
555 /**
556   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
557   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
558   *                the configuration information for NAND module.
559   * @param  pAddress  pointer to NAND address structure
560   * @param  pBuffer  pointer to destination read buffer
561   * @param  NumPageToRead  number of pages to read from block
562   * @retval HAL status
563   */
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToRead)564 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
565                                         uint32_t NumPageToRead)
566 {
567   uint32_t index;
568   uint32_t tickstart;
569   uint32_t deviceaddress;
570   uint32_t numpagesread = 0U;
571   uint32_t nandaddress;
572   uint32_t nbpages = NumPageToRead;
573   uint8_t *buff = pBuffer;
574 
575   /* Check the NAND controller state */
576   if (hnand->State == HAL_NAND_STATE_BUSY)
577   {
578     return HAL_BUSY;
579   }
580   else if (hnand->State == HAL_NAND_STATE_READY)
581   {
582     /* Process Locked */
583     __HAL_LOCK(hnand);
584 
585     /* Update the NAND controller state */
586     hnand->State = HAL_NAND_STATE_BUSY;
587 
588     /* Identify the device address */
589 #if defined(FMC_Bank2_3)
590     if (hnand->Init.NandBank == FMC_NAND_BANK2)
591     {
592       deviceaddress = NAND_DEVICE1;
593     }
594     else
595     {
596       deviceaddress = NAND_DEVICE2;
597     }
598 #else
599     deviceaddress = NAND_DEVICE;
600 #endif
601 
602     /* NAND raw address calculation */
603     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
604 
605     /* Page(s) read loop */
606     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
607     {
608       /* Send read page command sequence */
609       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
610       __DSB();
611 
612       /* Cards with page size <= 512 bytes */
613       if ((hnand->Config.PageSize) <= 512U)
614       {
615         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
616         {
617           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
618           __DSB();
619           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
620           __DSB();
621           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
622           __DSB();
623         }
624         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
625         {
626           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
627           __DSB();
628           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
629           __DSB();
630           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
631           __DSB();
632           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
633           __DSB();
634         }
635       }
636       else /* (hnand->Config.PageSize) > 512 */
637       {
638         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
639         {
640           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
641           __DSB();
642           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
643           __DSB();
644           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
645           __DSB();
646           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
647           __DSB();
648         }
649         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
650         {
651           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
652           __DSB();
653           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
654           __DSB();
655           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
656           __DSB();
657           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
658           __DSB();
659           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
660           __DSB();
661         }
662       }
663 
664       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
665       __DSB();
666 
667 
668       if (hnand->Config.ExtraCommandEnable == ENABLE)
669       {
670         /* Get tick */
671         tickstart = HAL_GetTick();
672 
673         /* Read status until NAND is ready */
674         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
675         {
676           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
677           {
678             /* Update the NAND controller state */
679             hnand->State = HAL_NAND_STATE_ERROR;
680 
681             /* Process unlocked */
682             __HAL_UNLOCK(hnand);
683 
684             return HAL_TIMEOUT;
685           }
686         }
687 
688         /* Go back to read mode */
689         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
690         __DSB();
691       }
692 
693       /* Get Data into Buffer */
694       for (index = 0U; index < hnand->Config.PageSize; index++)
695       {
696         *buff = *(uint8_t *)deviceaddress;
697         buff++;
698       }
699 
700       /* Increment read pages number */
701       numpagesread++;
702 
703       /* Decrement pages to read */
704       nbpages--;
705 
706       /* Increment the NAND address */
707       nandaddress = (uint32_t)(nandaddress + 1U);
708     }
709 
710     /* Update the NAND controller state */
711     hnand->State = HAL_NAND_STATE_READY;
712 
713     /* Process unlocked */
714     __HAL_UNLOCK(hnand);
715   }
716   else
717   {
718     return HAL_ERROR;
719   }
720 
721   return HAL_OK;
722 }
723 
724 /**
725   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
726   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
727   *                the configuration information for NAND module.
728   * @param  pAddress  pointer to NAND address structure
729   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
730   * @param  NumPageToRead  number of pages to read from block
731   * @retval HAL status
732   */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)733 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
734                                          uint32_t NumPageToRead)
735 {
736   uint32_t index;
737   uint32_t tickstart;
738   uint32_t deviceaddress;
739   uint32_t numpagesread = 0U;
740   uint32_t nandaddress;
741   uint32_t nbpages = NumPageToRead;
742   uint16_t *buff = pBuffer;
743 
744   /* Check the NAND controller state */
745   if (hnand->State == HAL_NAND_STATE_BUSY)
746   {
747     return HAL_BUSY;
748   }
749   else if (hnand->State == HAL_NAND_STATE_READY)
750   {
751     /* Process Locked */
752     __HAL_LOCK(hnand);
753 
754     /* Update the NAND controller state */
755     hnand->State = HAL_NAND_STATE_BUSY;
756 
757     /* Identify the device address */
758 #if defined(FMC_Bank2_3)
759     if (hnand->Init.NandBank == FMC_NAND_BANK2)
760     {
761       deviceaddress = NAND_DEVICE1;
762     }
763     else
764     {
765       deviceaddress = NAND_DEVICE2;
766     }
767 #else
768     deviceaddress = NAND_DEVICE;
769 #endif
770 
771     /* NAND raw address calculation */
772     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
773 
774     /* Page(s) read loop */
775     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
776     {
777       /* Send read page command sequence */
778       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
779       __DSB();
780 
781       /* Cards with page size <= 512 bytes */
782       if ((hnand->Config.PageSize) <= 512U)
783       {
784         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
785         {
786           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
787           __DSB();
788           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
789           __DSB();
790           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
791           __DSB();
792         }
793         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
794         {
795           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
796           __DSB();
797           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
798           __DSB();
799           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
800           __DSB();
801           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
802           __DSB();
803         }
804       }
805       else /* (hnand->Config.PageSize) > 512 */
806       {
807         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
808         {
809           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
810           __DSB();
811           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
812           __DSB();
813           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
814           __DSB();
815           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
816           __DSB();
817         }
818         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
819         {
820           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
821           __DSB();
822           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
823           __DSB();
824           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
825           __DSB();
826           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
827           __DSB();
828           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
829           __DSB();
830         }
831       }
832 
833       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
834       __DSB();
835 
836       if (hnand->Config.ExtraCommandEnable == ENABLE)
837       {
838         /* Get tick */
839         tickstart = HAL_GetTick();
840 
841         /* Read status until NAND is ready */
842         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
843         {
844           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
845           {
846             /* Update the NAND controller state */
847             hnand->State = HAL_NAND_STATE_ERROR;
848 
849             /* Process unlocked */
850             __HAL_UNLOCK(hnand);
851 
852             return HAL_TIMEOUT;
853           }
854         }
855 
856         /* Go back to read mode */
857         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
858         __DSB();
859       }
860 
861       /* Calculate PageSize */
862 #if defined(FSMC_PCR2_PWID)
863     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
864 #else
865     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
866 #endif /* FSMC_PCR2_PWID */
867       {
868         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
869       }
870       else
871       {
872         /* Do nothing */
873         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
874       }
875 
876       /* Get Data into Buffer */
877       for (index = 0U; index < hnand->Config.PageSize; index++)
878       {
879         *buff = *(uint16_t *)deviceaddress;
880         buff++;
881       }
882 
883       /* Increment read pages number */
884       numpagesread++;
885 
886       /* Decrement pages to read */
887       nbpages--;
888 
889       /* Increment the NAND address */
890       nandaddress = (uint32_t)(nandaddress + 1U);
891     }
892 
893     /* Update the NAND controller state */
894     hnand->State = HAL_NAND_STATE_READY;
895 
896     /* Process unlocked */
897     __HAL_UNLOCK(hnand);
898   }
899   else
900   {
901     return HAL_ERROR;
902   }
903 
904   return HAL_OK;
905 }
906 
907 /**
908   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
909   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
910   *                the configuration information for NAND module.
911   * @param  pAddress  pointer to NAND address structure
912   * @param  pBuffer  pointer to source buffer to write
913   * @param  NumPageToWrite   number of pages to write to block
914   * @retval HAL status
915   */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)916 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
917                                          uint32_t NumPageToWrite)
918 {
919   uint32_t index;
920   uint32_t tickstart;
921   uint32_t deviceaddress;
922   uint32_t numpageswritten = 0U;
923   uint32_t nandaddress;
924   uint32_t nbpages = NumPageToWrite;
925   uint8_t *buff = pBuffer;
926 
927   /* Check the NAND controller state */
928   if (hnand->State == HAL_NAND_STATE_BUSY)
929   {
930     return HAL_BUSY;
931   }
932   else if (hnand->State == HAL_NAND_STATE_READY)
933   {
934     /* Process Locked */
935     __HAL_LOCK(hnand);
936 
937     /* Update the NAND controller state */
938     hnand->State = HAL_NAND_STATE_BUSY;
939 
940     /* Identify the device address */
941 #if defined(FMC_Bank2_3)
942     if (hnand->Init.NandBank == FMC_NAND_BANK2)
943     {
944       deviceaddress = NAND_DEVICE1;
945     }
946     else
947     {
948       deviceaddress = NAND_DEVICE2;
949     }
950 #else
951     deviceaddress = NAND_DEVICE;
952 #endif
953 
954     /* NAND raw address calculation */
955     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
956 
957     /* Page(s) write loop */
958     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
959     {
960       /* Send write page command sequence */
961       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
962       __DSB();
963       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
964       __DSB();
965 
966       /* Cards with page size <= 512 bytes */
967       if ((hnand->Config.PageSize) <= 512U)
968       {
969         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
970         {
971           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
972           __DSB();
973           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
974           __DSB();
975           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
976           __DSB();
977         }
978         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
979         {
980           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
981           __DSB();
982           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
983           __DSB();
984           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
985           __DSB();
986           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
987           __DSB();
988         }
989       }
990       else /* (hnand->Config.PageSize) > 512 */
991       {
992         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
993         {
994           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
995           __DSB();
996           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
997           __DSB();
998           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
999           __DSB();
1000           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1001           __DSB();
1002         }
1003         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1004         {
1005           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1006           __DSB();
1007           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1008           __DSB();
1009           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1010           __DSB();
1011           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1012           __DSB();
1013           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1014           __DSB();
1015         }
1016       }
1017 
1018       /* Write data to memory */
1019       for (index = 0U; index < hnand->Config.PageSize; index++)
1020       {
1021         *(__IO uint8_t *)deviceaddress = *buff;
1022         buff++;
1023         __DSB();
1024       }
1025 
1026       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1027       __DSB();
1028 
1029       /* Get tick */
1030       tickstart = HAL_GetTick();
1031 
1032       /* Read status until NAND is ready */
1033       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1034       {
1035         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1036         {
1037           /* Update the NAND controller state */
1038           hnand->State = HAL_NAND_STATE_ERROR;
1039 
1040           /* Process unlocked */
1041           __HAL_UNLOCK(hnand);
1042 
1043           return HAL_TIMEOUT;
1044         }
1045       }
1046 
1047       /* Increment written pages number */
1048       numpageswritten++;
1049 
1050       /* Decrement pages to write */
1051       nbpages--;
1052 
1053       /* Increment the NAND address */
1054       nandaddress = (uint32_t)(nandaddress + 1U);
1055     }
1056 
1057     /* Update the NAND controller state */
1058     hnand->State = HAL_NAND_STATE_READY;
1059 
1060     /* Process unlocked */
1061     __HAL_UNLOCK(hnand);
1062   }
1063   else
1064   {
1065     return HAL_ERROR;
1066   }
1067 
1068   return HAL_OK;
1069 }
1070 
1071 /**
1072   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
1073   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1074   *                the configuration information for NAND module.
1075   * @param  pAddress  pointer to NAND address structure
1076   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
1077   * @param  NumPageToWrite   number of pages to write to block
1078   * @retval HAL status
1079   */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)1080 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
1081                                           uint32_t NumPageToWrite)
1082 {
1083   uint32_t index;
1084   uint32_t tickstart;
1085   uint32_t deviceaddress;
1086   uint32_t numpageswritten = 0U;
1087   uint32_t nandaddress;
1088   uint32_t nbpages = NumPageToWrite;
1089   uint16_t *buff = pBuffer;
1090 
1091   /* Check the NAND controller state */
1092   if (hnand->State == HAL_NAND_STATE_BUSY)
1093   {
1094     return HAL_BUSY;
1095   }
1096   else if (hnand->State == HAL_NAND_STATE_READY)
1097   {
1098     /* Process Locked */
1099     __HAL_LOCK(hnand);
1100 
1101     /* Update the NAND controller state */
1102     hnand->State = HAL_NAND_STATE_BUSY;
1103 
1104     /* Identify the device address */
1105 #if defined(FMC_Bank2_3)
1106     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1107     {
1108       deviceaddress = NAND_DEVICE1;
1109     }
1110     else
1111     {
1112       deviceaddress = NAND_DEVICE2;
1113     }
1114 #else
1115     deviceaddress = NAND_DEVICE;
1116 #endif
1117 
1118     /* NAND raw address calculation */
1119     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1120 
1121     /* Page(s) write loop */
1122     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1123     {
1124       /* Send write page command sequence */
1125       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1126       __DSB();
1127       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1128       __DSB();
1129 
1130       /* Cards with page size <= 512 bytes */
1131       if ((hnand->Config.PageSize) <= 512U)
1132       {
1133         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1134         {
1135           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1136           __DSB();
1137           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1138           __DSB();
1139           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1140           __DSB();
1141         }
1142         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1143         {
1144           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1145           __DSB();
1146           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1147           __DSB();
1148           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1149           __DSB();
1150           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1151           __DSB();
1152         }
1153       }
1154       else /* (hnand->Config.PageSize) > 512 */
1155       {
1156         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1157         {
1158           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1159           __DSB();
1160           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1161           __DSB();
1162           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1163           __DSB();
1164           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1165           __DSB();
1166         }
1167         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1168         {
1169           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1170           __DSB();
1171           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1172           __DSB();
1173           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1174           __DSB();
1175           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1176           __DSB();
1177           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1178           __DSB();
1179         }
1180       }
1181 
1182       /* Calculate PageSize */
1183 #if defined(FSMC_PCR2_PWID)
1184     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
1185 #else
1186     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
1187 #endif /* FSMC_PCR2_PWID */
1188       {
1189         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
1190       }
1191       else
1192       {
1193         /* Do nothing */
1194         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
1195       }
1196 
1197       /* Write data to memory */
1198       for (index = 0U; index < hnand->Config.PageSize; index++)
1199       {
1200         *(__IO uint16_t *)deviceaddress = *buff;
1201         buff++;
1202         __DSB();
1203       }
1204 
1205       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1206       __DSB();
1207 
1208       /* Get tick */
1209       tickstart = HAL_GetTick();
1210 
1211       /* Read status until NAND is ready */
1212       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1213       {
1214         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1215         {
1216           /* Update the NAND controller state */
1217           hnand->State = HAL_NAND_STATE_ERROR;
1218 
1219           /* Process unlocked */
1220           __HAL_UNLOCK(hnand);
1221 
1222           return HAL_TIMEOUT;
1223         }
1224       }
1225 
1226       /* Increment written pages number */
1227       numpageswritten++;
1228 
1229       /* Decrement pages to write */
1230       nbpages--;
1231 
1232       /* Increment the NAND address */
1233       nandaddress = (uint32_t)(nandaddress + 1U);
1234     }
1235 
1236     /* Update the NAND controller state */
1237     hnand->State = HAL_NAND_STATE_READY;
1238 
1239     /* Process unlocked */
1240     __HAL_UNLOCK(hnand);
1241   }
1242   else
1243   {
1244     return HAL_ERROR;
1245   }
1246 
1247   return HAL_OK;
1248 }
1249 
1250 /**
1251   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
1252   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1253   *                the configuration information for NAND module.
1254   * @param  pAddress  pointer to NAND address structure
1255   * @param  pBuffer pointer to source buffer to write
1256   * @param  NumSpareAreaToRead Number of spare area to read
1257   * @retval HAL status
1258   */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1259 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
1260                                              uint32_t NumSpareAreaToRead)
1261 {
1262   uint32_t index;
1263   uint32_t tickstart;
1264   uint32_t deviceaddress;
1265   uint32_t numsparearearead = 0U;
1266   uint32_t nandaddress;
1267   uint32_t columnaddress;
1268   uint32_t nbspare = NumSpareAreaToRead;
1269   uint8_t *buff = pBuffer;
1270 
1271   /* Check the NAND controller state */
1272   if (hnand->State == HAL_NAND_STATE_BUSY)
1273   {
1274     return HAL_BUSY;
1275   }
1276   else if (hnand->State == HAL_NAND_STATE_READY)
1277   {
1278     /* Process Locked */
1279     __HAL_LOCK(hnand);
1280 
1281     /* Update the NAND controller state */
1282     hnand->State = HAL_NAND_STATE_BUSY;
1283 
1284     /* Identify the device address */
1285 #if defined(FMC_Bank2_3)
1286     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1287     {
1288       deviceaddress = NAND_DEVICE1;
1289     }
1290     else
1291     {
1292       deviceaddress = NAND_DEVICE2;
1293     }
1294 #else
1295     deviceaddress = NAND_DEVICE;
1296 #endif
1297 
1298     /* NAND raw address calculation */
1299     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1300 
1301     /* Column in page address */
1302     columnaddress = COLUMN_ADDRESS(hnand);
1303 
1304     /* Spare area(s) read loop */
1305     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1306     {
1307       /* Cards with page size <= 512 bytes */
1308       if ((hnand->Config.PageSize) <= 512U)
1309       {
1310         /* Send read spare area command sequence */
1311         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1312         __DSB();
1313 
1314         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1315         {
1316           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1317           __DSB();
1318           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1319           __DSB();
1320           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1321           __DSB();
1322         }
1323         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1324         {
1325           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1326           __DSB();
1327           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1328           __DSB();
1329           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1330           __DSB();
1331           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1332           __DSB();
1333         }
1334       }
1335       else /* (hnand->Config.PageSize) > 512 */
1336       {
1337         /* Send read spare area command sequence */
1338         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1339         __DSB();
1340 
1341         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1342         {
1343           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1344           __DSB();
1345           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1346           __DSB();
1347           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1348           __DSB();
1349           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1350           __DSB();
1351         }
1352         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1353         {
1354           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1355           __DSB();
1356           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1357           __DSB();
1358           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1359           __DSB();
1360           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1361           __DSB();
1362           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1363           __DSB();
1364         }
1365       }
1366 
1367       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1368       __DSB();
1369 
1370       if (hnand->Config.ExtraCommandEnable == ENABLE)
1371       {
1372         /* Get tick */
1373         tickstart = HAL_GetTick();
1374 
1375         /* Read status until NAND is ready */
1376         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1377         {
1378           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1379           {
1380             /* Update the NAND controller state */
1381             hnand->State = HAL_NAND_STATE_ERROR;
1382 
1383             /* Process unlocked */
1384             __HAL_UNLOCK(hnand);
1385 
1386             return HAL_TIMEOUT;
1387           }
1388         }
1389 
1390         /* Go back to read mode */
1391         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1392         __DSB();
1393       }
1394 
1395       /* Get Data into Buffer */
1396       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1397       {
1398         *buff = *(uint8_t *)deviceaddress;
1399         buff++;
1400       }
1401 
1402       /* Increment read spare areas number */
1403       numsparearearead++;
1404 
1405       /* Decrement spare areas to read */
1406       nbspare--;
1407 
1408       /* Increment the NAND address */
1409       nandaddress = (uint32_t)(nandaddress + 1U);
1410     }
1411 
1412     /* Update the NAND controller state */
1413     hnand->State = HAL_NAND_STATE_READY;
1414 
1415     /* Process unlocked */
1416     __HAL_UNLOCK(hnand);
1417   }
1418   else
1419   {
1420     return HAL_ERROR;
1421   }
1422 
1423   return HAL_OK;
1424 }
1425 
1426 /**
1427   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
1428   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1429   *                the configuration information for NAND module.
1430   * @param  pAddress  pointer to NAND address structure
1431   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1432   * @param  NumSpareAreaToRead Number of spare area to read
1433   * @retval HAL status
1434   */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1435 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1436                                               uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1437 {
1438   uint32_t index;
1439   uint32_t tickstart;
1440   uint32_t deviceaddress;
1441   uint32_t numsparearearead = 0U;
1442   uint32_t nandaddress;
1443   uint32_t columnaddress;
1444   uint32_t nbspare = NumSpareAreaToRead;
1445   uint16_t *buff = pBuffer;
1446 
1447   /* Check the NAND controller state */
1448   if (hnand->State == HAL_NAND_STATE_BUSY)
1449   {
1450     return HAL_BUSY;
1451   }
1452   else if (hnand->State == HAL_NAND_STATE_READY)
1453   {
1454     /* Process Locked */
1455     __HAL_LOCK(hnand);
1456 
1457     /* Update the NAND controller state */
1458     hnand->State = HAL_NAND_STATE_BUSY;
1459 
1460     /* Identify the device address */
1461 #if defined(FMC_Bank2_3)
1462     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1463     {
1464       deviceaddress = NAND_DEVICE1;
1465     }
1466     else
1467     {
1468       deviceaddress = NAND_DEVICE2;
1469     }
1470 #else
1471     deviceaddress = NAND_DEVICE;
1472 #endif
1473 
1474     /* NAND raw address calculation */
1475     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1476 
1477     /* Column in page address */
1478     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1479 
1480     /* Spare area(s) read loop */
1481     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1482     {
1483       /* Cards with page size <= 512 bytes */
1484       if ((hnand->Config.PageSize) <= 512U)
1485       {
1486         /* Send read spare area command sequence */
1487         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1488         __DSB();
1489 
1490         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1491         {
1492           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1493           __DSB();
1494           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1495           __DSB();
1496           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1497           __DSB();
1498         }
1499         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1500         {
1501           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1502           __DSB();
1503           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1504           __DSB();
1505           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1506           __DSB();
1507           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1508           __DSB();
1509         }
1510       }
1511       else /* (hnand->Config.PageSize) > 512 */
1512       {
1513         /* Send read spare area command sequence */
1514         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1515         __DSB();
1516 
1517         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1518         {
1519           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1520           __DSB();
1521           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1522           __DSB();
1523           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1524           __DSB();
1525           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1526           __DSB();
1527         }
1528         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1529         {
1530           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1531           __DSB();
1532           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1533           __DSB();
1534           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1535           __DSB();
1536           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1537           __DSB();
1538           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1539           __DSB();
1540         }
1541       }
1542 
1543       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1544       __DSB();
1545 
1546       if (hnand->Config.ExtraCommandEnable == ENABLE)
1547       {
1548         /* Get tick */
1549         tickstart = HAL_GetTick();
1550 
1551         /* Read status until NAND is ready */
1552         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1553         {
1554           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1555           {
1556             /* Update the NAND controller state */
1557             hnand->State = HAL_NAND_STATE_ERROR;
1558 
1559             /* Process unlocked */
1560             __HAL_UNLOCK(hnand);
1561 
1562             return HAL_TIMEOUT;
1563           }
1564         }
1565 
1566         /* Go back to read mode */
1567         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1568         __DSB();
1569       }
1570 
1571       /* Get Data into Buffer */
1572       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1573       {
1574         *buff = *(uint16_t *)deviceaddress;
1575         buff++;
1576       }
1577 
1578       /* Increment read spare areas number */
1579       numsparearearead++;
1580 
1581       /* Decrement spare areas to read */
1582       nbspare--;
1583 
1584       /* Increment the NAND address */
1585       nandaddress = (uint32_t)(nandaddress + 1U);
1586     }
1587 
1588     /* Update the NAND controller state */
1589     hnand->State = HAL_NAND_STATE_READY;
1590 
1591     /* Process unlocked */
1592     __HAL_UNLOCK(hnand);
1593   }
1594   else
1595   {
1596     return HAL_ERROR;
1597   }
1598 
1599   return HAL_OK;
1600 }
1601 
1602 /**
1603   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
1604   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1605   *                the configuration information for NAND module.
1606   * @param  pAddress  pointer to NAND address structure
1607   * @param  pBuffer  pointer to source buffer to write
1608   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1609   * @retval HAL status
1610   */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1611 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1612                                               uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1613 {
1614   uint32_t index;
1615   uint32_t tickstart;
1616   uint32_t deviceaddress;
1617   uint32_t numspareareawritten = 0U;
1618   uint32_t nandaddress;
1619   uint32_t columnaddress;
1620   uint32_t nbspare = NumSpareAreaTowrite;
1621   uint8_t *buff = pBuffer;
1622 
1623   /* Check the NAND controller state */
1624   if (hnand->State == HAL_NAND_STATE_BUSY)
1625   {
1626     return HAL_BUSY;
1627   }
1628   else if (hnand->State == HAL_NAND_STATE_READY)
1629   {
1630     /* Process Locked */
1631     __HAL_LOCK(hnand);
1632 
1633     /* Update the NAND controller state */
1634     hnand->State = HAL_NAND_STATE_BUSY;
1635 
1636     /* Identify the device address */
1637 #if defined(FMC_Bank2_3)
1638     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1639     {
1640       deviceaddress = NAND_DEVICE1;
1641     }
1642     else
1643     {
1644       deviceaddress = NAND_DEVICE2;
1645     }
1646 #else
1647     deviceaddress = NAND_DEVICE;
1648 #endif
1649 
1650     /* Page address calculation */
1651     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1652 
1653     /* Column in page address */
1654     columnaddress = COLUMN_ADDRESS(hnand);
1655 
1656     /* Spare area(s) write loop */
1657     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1658     {
1659       /* Cards with page size <= 512 bytes */
1660       if ((hnand->Config.PageSize) <= 512U)
1661       {
1662         /* Send write Spare area command sequence */
1663         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1664         __DSB();
1665         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1666         __DSB();
1667 
1668         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1669         {
1670           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1671           __DSB();
1672           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1673           __DSB();
1674           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1675           __DSB();
1676         }
1677         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1678         {
1679           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1680           __DSB();
1681           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1682           __DSB();
1683           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1684           __DSB();
1685           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1686           __DSB();
1687         }
1688       }
1689       else /* (hnand->Config.PageSize) > 512 */
1690       {
1691         /* Send write Spare area command sequence */
1692         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1693         __DSB();
1694         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1695         __DSB();
1696 
1697         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1698         {
1699           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1700           __DSB();
1701           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1702           __DSB();
1703           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1704           __DSB();
1705           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1706           __DSB();
1707         }
1708         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1709         {
1710           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1711           __DSB();
1712           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1713           __DSB();
1714           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1715           __DSB();
1716           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1717           __DSB();
1718           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1719           __DSB();
1720         }
1721       }
1722 
1723       /* Write data to memory */
1724       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1725       {
1726         *(__IO uint8_t *)deviceaddress = *buff;
1727         buff++;
1728         __DSB();
1729       }
1730 
1731       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1732       __DSB();
1733 
1734       /* Get tick */
1735       tickstart = HAL_GetTick();
1736 
1737       /* Read status until NAND is ready */
1738       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1739       {
1740         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1741         {
1742           /* Update the NAND controller state */
1743           hnand->State = HAL_NAND_STATE_ERROR;
1744 
1745           /* Process unlocked */
1746           __HAL_UNLOCK(hnand);
1747 
1748           return HAL_TIMEOUT;
1749         }
1750       }
1751 
1752       /* Increment written spare areas number */
1753       numspareareawritten++;
1754 
1755       /* Decrement spare areas to write */
1756       nbspare--;
1757 
1758       /* Increment the NAND address */
1759       nandaddress = (uint32_t)(nandaddress + 1U);
1760     }
1761 
1762     /* Update the NAND controller state */
1763     hnand->State = HAL_NAND_STATE_READY;
1764 
1765     /* Process unlocked */
1766     __HAL_UNLOCK(hnand);
1767   }
1768   else
1769   {
1770     return HAL_ERROR;
1771   }
1772 
1773   return HAL_OK;
1774 }
1775 
1776 /**
1777   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
1778   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1779   *                the configuration information for NAND module.
1780   * @param  pAddress  pointer to NAND address structure
1781   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
1782   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1783   * @retval HAL status
1784   */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1785 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1786                                                uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1787 {
1788   uint32_t index;
1789   uint32_t tickstart;
1790   uint32_t deviceaddress;
1791   uint32_t numspareareawritten = 0U;
1792   uint32_t nandaddress;
1793   uint32_t columnaddress;
1794   uint32_t nbspare = NumSpareAreaTowrite;
1795   uint16_t *buff = pBuffer;
1796 
1797   /* Check the NAND controller state */
1798   if (hnand->State == HAL_NAND_STATE_BUSY)
1799   {
1800     return HAL_BUSY;
1801   }
1802   else if (hnand->State == HAL_NAND_STATE_READY)
1803   {
1804     /* Process Locked */
1805     __HAL_LOCK(hnand);
1806 
1807     /* Update the NAND controller state */
1808     hnand->State = HAL_NAND_STATE_BUSY;
1809 
1810     /* Identify the device address */
1811 #if defined(FMC_Bank2_3)
1812     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1813     {
1814       deviceaddress = NAND_DEVICE1;
1815     }
1816     else
1817     {
1818       deviceaddress = NAND_DEVICE2;
1819     }
1820 #else
1821     deviceaddress = NAND_DEVICE;
1822 #endif
1823 
1824     /* NAND raw address calculation */
1825     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1826 
1827     /* Column in page address */
1828     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1829 
1830     /* Spare area(s) write loop */
1831     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1832     {
1833       /* Cards with page size <= 512 bytes */
1834       if ((hnand->Config.PageSize) <= 512U)
1835       {
1836         /* Send write Spare area command sequence */
1837         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1838         __DSB();
1839         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1840         __DSB();
1841 
1842         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1843         {
1844           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1845           __DSB();
1846           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1847           __DSB();
1848           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1849           __DSB();
1850         }
1851         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1852         {
1853           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1854           __DSB();
1855           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1856           __DSB();
1857           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1858           __DSB();
1859           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1860           __DSB();
1861         }
1862       }
1863       else /* (hnand->Config.PageSize) > 512 */
1864       {
1865         /* Send write Spare area command sequence */
1866         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1867         __DSB();
1868         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1869         __DSB();
1870 
1871         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1872         {
1873           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1874           __DSB();
1875           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1876           __DSB();
1877           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1878           __DSB();
1879           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1880           __DSB();
1881         }
1882         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1883         {
1884           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1885           __DSB();
1886           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1887           __DSB();
1888           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1889           __DSB();
1890           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1891           __DSB();
1892           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1893           __DSB();
1894         }
1895       }
1896 
1897       /* Write data to memory */
1898       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1899       {
1900         *(__IO uint16_t *)deviceaddress = *buff;
1901         buff++;
1902         __DSB();
1903       }
1904 
1905       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1906       __DSB();
1907 
1908       /* Get tick */
1909       tickstart = HAL_GetTick();
1910 
1911       /* Read status until NAND is ready */
1912       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1913       {
1914         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1915         {
1916           /* Update the NAND controller state */
1917           hnand->State = HAL_NAND_STATE_ERROR;
1918 
1919           /* Process unlocked */
1920           __HAL_UNLOCK(hnand);
1921 
1922           return HAL_TIMEOUT;
1923         }
1924       }
1925 
1926       /* Increment written spare areas number */
1927       numspareareawritten++;
1928 
1929       /* Decrement spare areas to write */
1930       nbspare--;
1931 
1932       /* Increment the NAND address */
1933       nandaddress = (uint32_t)(nandaddress + 1U);
1934     }
1935 
1936     /* Update the NAND controller state */
1937     hnand->State = HAL_NAND_STATE_READY;
1938 
1939     /* Process unlocked */
1940     __HAL_UNLOCK(hnand);
1941   }
1942   else
1943   {
1944     return HAL_ERROR;
1945   }
1946 
1947   return HAL_OK;
1948 }
1949 
1950 /**
1951   * @brief  NAND memory Block erase
1952   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1953   *                the configuration information for NAND module.
1954   * @param  pAddress  pointer to NAND address structure
1955   * @retval HAL status
1956   */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1957 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1958 {
1959   uint32_t deviceaddress;
1960 
1961   /* Check the NAND controller state */
1962   if (hnand->State == HAL_NAND_STATE_BUSY)
1963   {
1964     return HAL_BUSY;
1965   }
1966   else if (hnand->State == HAL_NAND_STATE_READY)
1967   {
1968     /* Process Locked */
1969     __HAL_LOCK(hnand);
1970 
1971     /* Update the NAND controller state */
1972     hnand->State = HAL_NAND_STATE_BUSY;
1973 
1974     /* Identify the device address */
1975 #if defined(FMC_Bank2_3)
1976     if (hnand->Init.NandBank == FMC_NAND_BANK2)
1977     {
1978       deviceaddress = NAND_DEVICE1;
1979     }
1980     else
1981     {
1982       deviceaddress = NAND_DEVICE2;
1983     }
1984 #else
1985     deviceaddress = NAND_DEVICE;
1986 #endif
1987 
1988     /* Send Erase block command sequence */
1989     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
1990     __DSB();
1991     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1992     __DSB();
1993     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1994     __DSB();
1995     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1996     __DSB();
1997 
1998     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
1999     __DSB();
2000 
2001     /* Update the NAND controller state */
2002     hnand->State = HAL_NAND_STATE_READY;
2003 
2004     /* Process unlocked */
2005     __HAL_UNLOCK(hnand);
2006   }
2007   else
2008   {
2009     return HAL_ERROR;
2010   }
2011 
2012   return HAL_OK;
2013 }
2014 
2015 /**
2016   * @brief  Increment the NAND memory address
2017   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2018   *                the configuration information for NAND module.
2019   * @param pAddress pointer to NAND address structure
2020   * @retval The new status of the increment address operation. It can be:
2021   *           - NAND_VALID_ADDRESS: When the new address is valid address
2022   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
2023   */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)2024 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
2025 {
2026   uint32_t status = NAND_VALID_ADDRESS;
2027 
2028   /* Increment page address */
2029   pAddress->Page++;
2030 
2031   /* Check NAND address is valid */
2032   if (pAddress->Page == hnand->Config.BlockSize)
2033   {
2034     pAddress->Page = 0;
2035     pAddress->Block++;
2036 
2037     if (pAddress->Block == hnand->Config.PlaneSize)
2038     {
2039       pAddress->Block = 0;
2040       pAddress->Plane++;
2041 
2042       if (pAddress->Plane == (hnand->Config.PlaneNbr))
2043       {
2044         status = NAND_INVALID_ADDRESS;
2045       }
2046     }
2047   }
2048 
2049   return (status);
2050 }
2051 
2052 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
2053 /**
2054   * @brief  Register a User NAND Callback
2055   *         To be used instead of the weak (surcharged) predefined callback
2056   * @param hnand : NAND handle
2057   * @param CallbackId : ID of the callback to be registered
2058   *        This parameter can be one of the following values:
2059   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
2060   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
2061   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
2062   * @param pCallback : pointer to the Callback function
2063   * @retval status
2064   */
HAL_NAND_RegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId,pNAND_CallbackTypeDef pCallback)2065 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
2066                                             pNAND_CallbackTypeDef pCallback)
2067 {
2068   HAL_StatusTypeDef status = HAL_OK;
2069 
2070   if (pCallback == NULL)
2071   {
2072     return HAL_ERROR;
2073   }
2074 
2075   /* Process locked */
2076   __HAL_LOCK(hnand);
2077 
2078   if (hnand->State == HAL_NAND_STATE_READY)
2079   {
2080     switch (CallbackId)
2081     {
2082       case HAL_NAND_MSP_INIT_CB_ID :
2083         hnand->MspInitCallback = pCallback;
2084         break;
2085       case HAL_NAND_MSP_DEINIT_CB_ID :
2086         hnand->MspDeInitCallback = pCallback;
2087         break;
2088       case HAL_NAND_IT_CB_ID :
2089         hnand->ItCallback = pCallback;
2090         break;
2091       default :
2092         /* update return status */
2093         status =  HAL_ERROR;
2094         break;
2095     }
2096   }
2097   else if (hnand->State == HAL_NAND_STATE_RESET)
2098   {
2099     switch (CallbackId)
2100     {
2101       case HAL_NAND_MSP_INIT_CB_ID :
2102         hnand->MspInitCallback = pCallback;
2103         break;
2104       case HAL_NAND_MSP_DEINIT_CB_ID :
2105         hnand->MspDeInitCallback = pCallback;
2106         break;
2107       default :
2108         /* update return status */
2109         status =  HAL_ERROR;
2110         break;
2111     }
2112   }
2113   else
2114   {
2115     /* update return status */
2116     status =  HAL_ERROR;
2117   }
2118 
2119   /* Release Lock */
2120   __HAL_UNLOCK(hnand);
2121   return status;
2122 }
2123 
2124 /**
2125   * @brief  Unregister a User NAND Callback
2126   *         NAND Callback is redirected to the weak (surcharged) predefined callback
2127   * @param hnand : NAND handle
2128   * @param CallbackId : ID of the callback to be unregistered
2129   *        This parameter can be one of the following values:
2130   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
2131   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
2132   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
2133   * @retval status
2134   */
HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId)2135 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
2136 {
2137   HAL_StatusTypeDef status = HAL_OK;
2138 
2139   /* Process locked */
2140   __HAL_LOCK(hnand);
2141 
2142   if (hnand->State == HAL_NAND_STATE_READY)
2143   {
2144     switch (CallbackId)
2145     {
2146       case HAL_NAND_MSP_INIT_CB_ID :
2147         hnand->MspInitCallback = HAL_NAND_MspInit;
2148         break;
2149       case HAL_NAND_MSP_DEINIT_CB_ID :
2150         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
2151         break;
2152       case HAL_NAND_IT_CB_ID :
2153         hnand->ItCallback = HAL_NAND_ITCallback;
2154         break;
2155       default :
2156         /* update return status */
2157         status =  HAL_ERROR;
2158         break;
2159     }
2160   }
2161   else if (hnand->State == HAL_NAND_STATE_RESET)
2162   {
2163     switch (CallbackId)
2164     {
2165       case HAL_NAND_MSP_INIT_CB_ID :
2166         hnand->MspInitCallback = HAL_NAND_MspInit;
2167         break;
2168       case HAL_NAND_MSP_DEINIT_CB_ID :
2169         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
2170         break;
2171       default :
2172         /* update return status */
2173         status =  HAL_ERROR;
2174         break;
2175     }
2176   }
2177   else
2178   {
2179     /* update return status */
2180     status =  HAL_ERROR;
2181   }
2182 
2183   /* Release Lock */
2184   __HAL_UNLOCK(hnand);
2185   return status;
2186 }
2187 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
2188 
2189 /**
2190   * @}
2191   */
2192 
2193 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
2194   *  @brief   management functions
2195   *
2196 @verbatim
2197   ==============================================================================
2198                          ##### NAND Control functions #####
2199   ==============================================================================
2200   [..]
2201     This subsection provides a set of functions allowing to control dynamically
2202     the NAND interface.
2203 
2204 @endverbatim
2205   * @{
2206   */
2207 
2208 
2209 /**
2210   * @brief  Enables dynamically NAND ECC feature.
2211   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2212   *                the configuration information for NAND module.
2213   * @retval HAL status
2214   */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)2215 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2216 {
2217   /* Check the NAND controller state */
2218   if (hnand->State == HAL_NAND_STATE_BUSY)
2219   {
2220     return HAL_BUSY;
2221   }
2222   else if (hnand->State == HAL_NAND_STATE_READY)
2223   {
2224     /* Update the NAND state */
2225     hnand->State = HAL_NAND_STATE_BUSY;
2226 
2227     /* Enable ECC feature */
2228     (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2229 
2230     /* Update the NAND state */
2231     hnand->State = HAL_NAND_STATE_READY;
2232   }
2233   else
2234   {
2235     return HAL_ERROR;
2236   }
2237 
2238   return HAL_OK;
2239 }
2240 
2241 /**
2242   * @brief  Disables dynamically FMC_NAND ECC feature.
2243   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2244   *                the configuration information for NAND module.
2245   * @retval HAL status
2246   */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)2247 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2248 {
2249   /* Check the NAND controller state */
2250   if (hnand->State == HAL_NAND_STATE_BUSY)
2251   {
2252     return HAL_BUSY;
2253   }
2254   else if (hnand->State == HAL_NAND_STATE_READY)
2255   {
2256     /* Update the NAND state */
2257     hnand->State = HAL_NAND_STATE_BUSY;
2258 
2259     /* Disable ECC feature */
2260     (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2261 
2262     /* Update the NAND state */
2263     hnand->State = HAL_NAND_STATE_READY;
2264   }
2265   else
2266   {
2267     return HAL_ERROR;
2268   }
2269 
2270   return HAL_OK;
2271 }
2272 
2273 /**
2274   * @brief  Disables dynamically NAND ECC feature.
2275   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2276   *                the configuration information for NAND module.
2277   * @param  ECCval pointer to ECC value
2278   * @param  Timeout maximum timeout to wait
2279   * @retval HAL status
2280   */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)2281 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2282 {
2283   HAL_StatusTypeDef status;
2284 
2285   /* Check the NAND controller state */
2286   if (hnand->State == HAL_NAND_STATE_BUSY)
2287   {
2288     return HAL_BUSY;
2289   }
2290   else if (hnand->State == HAL_NAND_STATE_READY)
2291   {
2292     /* Update the NAND state */
2293     hnand->State = HAL_NAND_STATE_BUSY;
2294 
2295     /* Get NAND ECC value */
2296     status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2297 
2298     /* Update the NAND state */
2299     hnand->State = HAL_NAND_STATE_READY;
2300   }
2301   else
2302   {
2303     return HAL_ERROR;
2304   }
2305 
2306   return status;
2307 }
2308 
2309 /**
2310   * @}
2311   */
2312 
2313 
2314 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2315   *  @brief   Peripheral State functions
2316   *
2317 @verbatim
2318   ==============================================================================
2319                          ##### NAND State functions #####
2320   ==============================================================================
2321   [..]
2322     This subsection permits to get in run-time the status of the NAND controller
2323     and the data flow.
2324 
2325 @endverbatim
2326   * @{
2327   */
2328 
2329 /**
2330   * @brief  return the NAND state
2331   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2332   *                the configuration information for NAND module.
2333   * @retval HAL state
2334   */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)2335 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2336 {
2337   return hnand->State;
2338 }
2339 
2340 /**
2341   * @brief  NAND memory read status
2342   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2343   *                the configuration information for NAND module.
2344   * @retval NAND status
2345   */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)2346 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2347 {
2348   uint32_t data;
2349   uint32_t deviceaddress;
2350   UNUSED(hnand);
2351 
2352   /* Identify the device address */
2353 #if defined(FMC_Bank2_3)
2354   if (hnand->Init.NandBank == FMC_NAND_BANK2)
2355   {
2356     deviceaddress = NAND_DEVICE1;
2357   }
2358   else
2359   {
2360     deviceaddress = NAND_DEVICE2;
2361   }
2362 #else
2363   deviceaddress = NAND_DEVICE;
2364 #endif
2365 
2366   /* Send Read status operation command */
2367   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
2368 
2369   /* Read status register data */
2370   data = *(__IO uint8_t *)deviceaddress;
2371 
2372   /* Return the status */
2373   if ((data & NAND_ERROR) == NAND_ERROR)
2374   {
2375     return NAND_ERROR;
2376   }
2377   else if ((data & NAND_READY) == NAND_READY)
2378   {
2379     return NAND_READY;
2380   }
2381   else
2382   {
2383     return NAND_BUSY;
2384   }
2385 }
2386 
2387 /**
2388   * @}
2389   */
2390 
2391 /**
2392   * @}
2393   */
2394 
2395 /**
2396   * @}
2397   */
2398 
2399 #endif /* HAL_NAND_MODULE_ENABLED  */
2400 
2401 /**
2402   * @}
2403   */
2404 
2405 #endif /* FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3 */
2406