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