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