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