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