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