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