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