STM32F479xx HAL User Manual
stm32f4xx_hal_nand.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_nand.c
00004   * @author  MCD Application Team
00005   * @brief   NAND HAL module driver.
00006   *          This file provides a generic firmware to drive NAND memories mounted
00007   *          as external device.
00008   *
00009   @verbatim
00010   ==============================================================================
00011                          ##### How to use this driver #####
00012   ==============================================================================
00013     [..]
00014       This driver is a generic layered driver which contains a set of APIs used to
00015       control NAND flash memories. It uses the FMC/FSMC layer functions to interface
00016       with NAND devices. This driver is used as follows:
00017 
00018       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
00019           with control and timing parameters for both common and attribute spaces.
00020 
00021       (+) Read NAND flash memory maker and device IDs using the function
00022           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
00023           structure declared by the function caller.
00024 
00025       (+) Access NAND flash memory by read/write operations using the functions
00026           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
00027           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
00028           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
00029           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
00030           to read/write page(s)/spare area(s). These functions use specific device
00031           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
00032           structure. The read/write address information is contained by the Nand_Address_Typedef
00033           structure passed as parameter.
00034 
00035       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
00036 
00037       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
00038           The erase block address information is contained in the Nand_Address_Typedef
00039           structure passed as parameter.
00040 
00041       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
00042 
00043       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
00044           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
00045           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
00046 
00047       (+) You can monitor the NAND device HAL state by calling the function
00048           HAL_NAND_GetState()
00049 
00050     [..]
00051       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
00052           If a NAND flash device contains different operations and/or implementations,
00053           it should be implemented separately.
00054 
00055     *** Callback registration ***
00056     =============================================
00057     [..]
00058       The compilation define  USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
00059       allows the user to configure dynamically the driver callbacks.
00060 
00061       Use Functions HAL_NAND_RegisterCallback() to register a user callback,
00062       it allows to register following callbacks:
00063         (+) MspInitCallback    : NAND MspInit.
00064         (+) MspDeInitCallback  : NAND MspDeInit.
00065       This function takes as parameters the HAL peripheral handle, the Callback ID
00066       and a pointer to the user callback function.
00067 
00068       Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default
00069       weak (surcharged) function. It allows to reset following callbacks:
00070         (+) MspInitCallback    : NAND MspInit.
00071         (+) MspDeInitCallback  : NAND MspDeInit.
00072       This function) takes as parameters the HAL peripheral handle and the Callback ID.
00073 
00074       By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
00075       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00076       Exception done for MspInit and MspDeInit callbacks that are respectively
00077       reset to the legacy weak (surcharged) functions in the HAL_NAND_Init
00078       and  HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
00079       If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit
00080       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00081 
00082       Callbacks can be registered/unregistered in READY state only.
00083       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00084       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00085       during the Init/DeInit.
00086       In that case first register the MspInit/MspDeInit user callbacks
00087       using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit
00088       or HAL_NAND_Init function.
00089 
00090       When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
00091       not defined, the callback registering feature is not available
00092       and weak (surcharged) callbacks are used.
00093 
00094   @endverbatim
00095   ******************************************************************************
00096   * @attention
00097   *
00098   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00099   * All rights reserved.</center></h2>
00100   *
00101   * This software component is licensed by ST under BSD 3-Clause license,
00102   * the "License"; You may not use this file except in compliance with the
00103   * License. You may obtain a copy of the License at:
00104   *                       opensource.org/licenses/BSD-3-Clause
00105   *
00106   ******************************************************************************
00107   */
00108 
00109 /* Includes ------------------------------------------------------------------*/
00110 #include "stm32f4xx_hal.h"
00111 
00112 #if defined(FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00113 
00114 /** @addtogroup STM32F4xx_HAL_Driver
00115   * @{
00116   */
00117 
00118 #ifdef HAL_NAND_MODULE_ENABLED
00119 
00120 /** @defgroup NAND NAND
00121   * @brief NAND HAL module driver
00122   * @{
00123   */
00124 
00125 /* Private typedef -----------------------------------------------------------*/
00126 /* Private Constants ------------------------------------------------------------*/
00127 /* Private macro -------------------------------------------------------------*/
00128 /* Private variables ---------------------------------------------------------*/
00129 /* Private function prototypes -----------------------------------------------*/
00130 /* Exported functions ---------------------------------------------------------*/
00131 
00132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
00133   * @{
00134   */
00135 
00136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
00137   * @brief    Initialization and Configuration functions
00138   *
00139   @verbatim
00140   ==============================================================================
00141             ##### NAND Initialization and de-initialization functions #####
00142   ==============================================================================
00143   [..]
00144     This section provides functions allowing to initialize/de-initialize
00145     the NAND memory
00146 
00147 @endverbatim
00148   * @{
00149   */
00150 
00151 /**
00152   * @brief  Perform NAND memory Initialization sequence
00153   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00154   *                the configuration information for NAND module.
00155   * @param  ComSpace_Timing pointer to Common space timing structure
00156   * @param  AttSpace_Timing pointer to Attribute space timing structure
00157   * @retval HAL status
00158   */
00159 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
00160                                  FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
00161 {
00162   /* Check the NAND handle state */
00163   if (hnand == NULL)
00164   {
00165     return HAL_ERROR;
00166   }
00167 
00168   if (hnand->State == HAL_NAND_STATE_RESET)
00169   {
00170     /* Allocate lock resource and initialize it */
00171     hnand->Lock = HAL_UNLOCKED;
00172 
00173 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00174     if (hnand->MspInitCallback == NULL)
00175     {
00176       hnand->MspInitCallback = HAL_NAND_MspInit;
00177     }
00178     hnand->ItCallback = HAL_NAND_ITCallback;
00179 
00180     /* Init the low level hardware */
00181     hnand->MspInitCallback(hnand);
00182 #else
00183     /* Initialize the low level hardware (MSP) */
00184     HAL_NAND_MspInit(hnand);
00185 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00186   }
00187 
00188   /* Initialize NAND control Interface */
00189   (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
00190 
00191   /* Initialize NAND common space timing Interface */
00192   (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
00193 
00194   /* Initialize NAND attribute space timing Interface */
00195   (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
00196 
00197   /* Enable the NAND device */
00198 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00199   __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
00200 #else
00201   __FMC_NAND_ENABLE(hnand->Instance);
00202 #endif
00203 
00204   /* Update the NAND controller state */
00205   hnand->State = HAL_NAND_STATE_READY;
00206 
00207   return HAL_OK;
00208 }
00209 
00210 /**
00211   * @brief  Perform NAND memory De-Initialization sequence
00212   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00213   *                the configuration information for NAND module.
00214   * @retval HAL status
00215   */
00216 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
00217 {
00218 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00219   if (hnand->MspDeInitCallback == NULL)
00220   {
00221     hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
00222   }
00223 
00224   /* DeInit the low level hardware */
00225   hnand->MspDeInitCallback(hnand);
00226 #else
00227   /* Initialize the low level hardware (MSP) */
00228   HAL_NAND_MspDeInit(hnand);
00229 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00230 
00231   /* Configure the NAND registers with their reset values */
00232   (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
00233 
00234   /* Reset the NAND controller state */
00235   hnand->State = HAL_NAND_STATE_RESET;
00236 
00237   /* Release Lock */
00238   __HAL_UNLOCK(hnand);
00239 
00240   return HAL_OK;
00241 }
00242 
00243 /**
00244   * @brief  NAND MSP Init
00245   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00246   *                the configuration information for NAND module.
00247   * @retval None
00248   */
00249 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
00250 {
00251   /* Prevent unused argument(s) compilation warning */
00252   UNUSED(hnand);
00253 
00254   /* NOTE : This function Should not be modified, when the callback is needed,
00255             the HAL_NAND_MspInit could be implemented in the user file
00256    */
00257 }
00258 
00259 /**
00260   * @brief  NAND MSP DeInit
00261   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00262   *                the configuration information for NAND module.
00263   * @retval None
00264   */
00265 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
00266 {
00267   /* Prevent unused argument(s) compilation warning */
00268   UNUSED(hnand);
00269 
00270   /* NOTE : This function Should not be modified, when the callback is needed,
00271             the HAL_NAND_MspDeInit could be implemented in the user file
00272    */
00273 }
00274 
00275 
00276 /**
00277   * @brief  This function handles NAND device interrupt request.
00278   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00279   *                the configuration information for NAND module.
00280   * @retval HAL status
00281   */
00282 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
00283 {
00284   /* Check NAND interrupt Rising edge flag */
00285   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
00286   {
00287     /* NAND interrupt callback*/
00288 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00289     hnand->ItCallback(hnand);
00290 #else
00291     HAL_NAND_ITCallback(hnand);
00292 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00293 
00294     /* Clear NAND interrupt Rising edge pending bit */
00295 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00296     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
00297 #else
00298     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
00299 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
00300   }
00301 
00302   /* Check NAND interrupt Level flag */
00303   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
00304   {
00305     /* NAND interrupt callback*/
00306 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00307     hnand->ItCallback(hnand);
00308 #else
00309     HAL_NAND_ITCallback(hnand);
00310 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00311 
00312     /* Clear NAND interrupt Level pending bit */
00313 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00314     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
00315 #else
00316     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
00317 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
00318   }
00319 
00320   /* Check NAND interrupt Falling edge flag */
00321   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
00322   {
00323     /* NAND interrupt callback*/
00324 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00325     hnand->ItCallback(hnand);
00326 #else
00327     HAL_NAND_ITCallback(hnand);
00328 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00329 
00330     /* Clear NAND interrupt Falling edge pending bit */
00331 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00332     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
00333 #else
00334     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
00335 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
00336   }
00337 
00338   /* Check NAND interrupt FIFO empty flag */
00339   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
00340   {
00341     /* NAND interrupt callback*/
00342 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
00343     hnand->ItCallback(hnand);
00344 #else
00345     HAL_NAND_ITCallback(hnand);
00346 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
00347 
00348     /* Clear NAND interrupt FIFO empty pending bit */
00349 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3)
00350     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
00351 #else
00352     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
00353 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */
00354   }
00355 
00356 }
00357 
00358 /**
00359   * @brief  NAND interrupt feature callback
00360   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00361   *                the configuration information for NAND module.
00362   * @retval None
00363   */
00364 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
00365 {
00366   /* Prevent unused argument(s) compilation warning */
00367   UNUSED(hnand);
00368 
00369   /* NOTE : This function Should not be modified, when the callback is needed,
00370             the HAL_NAND_ITCallback could be implemented in the user file
00371    */
00372 }
00373 
00374 /**
00375   * @}
00376   */
00377 
00378 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
00379   * @brief    Input Output and memory control functions
00380   *
00381   @verbatim
00382   ==============================================================================
00383                     ##### NAND Input and Output functions #####
00384   ==============================================================================
00385   [..]
00386     This section provides functions allowing to use and control the NAND
00387     memory
00388 
00389 @endverbatim
00390   * @{
00391   */
00392 
00393 /**
00394   * @brief  Read the NAND memory electronic signature
00395   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00396   *                the configuration information for NAND module.
00397   * @param  pNAND_ID NAND ID structure
00398   * @retval HAL status
00399   */
00400 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
00401 {
00402   __IO uint32_t data = 0;
00403   __IO uint32_t data1 = 0;
00404   uint32_t deviceaddress;
00405 
00406   /* Check the NAND controller state */
00407   if (hnand->State == HAL_NAND_STATE_BUSY)
00408   {
00409     return HAL_BUSY;
00410   }
00411   else if (hnand->State == HAL_NAND_STATE_READY)
00412   {
00413     /* Process Locked */
00414     __HAL_LOCK(hnand);
00415 
00416     /* Update the NAND controller state */
00417     hnand->State = HAL_NAND_STATE_BUSY;
00418 
00419     /* Identify the device address */
00420 #if defined(FMC_Bank2_3)
00421     if (hnand->Init.NandBank == FMC_NAND_BANK2)
00422     {
00423       deviceaddress = NAND_DEVICE1;
00424     }
00425     else
00426     {
00427       deviceaddress = NAND_DEVICE2;
00428     }
00429 #else
00430     deviceaddress = NAND_DEVICE;
00431 #endif
00432 
00433     /* Send Read ID command sequence */
00434     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
00435     __DSB();
00436     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
00437     __DSB();
00438 
00439     /* Read the electronic signature from NAND flash */
00440 #ifdef FSMC_PCR2_PWID
00441     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
00442 #else /* FMC_PCR2_PWID is defined */
00443     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
00444 #endif
00445     {
00446       data = *(__IO uint32_t *)deviceaddress;
00447 
00448       /* Return the data read */
00449       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
00450       pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
00451       pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
00452       pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
00453     }
00454     else
00455     {
00456       data = *(__IO uint32_t *)deviceaddress;
00457       data1 = *((__IO uint32_t *)deviceaddress + 4);
00458 
00459       /* Return the data read */
00460       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
00461       pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
00462       pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
00463       pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
00464     }
00465 
00466     /* Update the NAND controller state */
00467     hnand->State = HAL_NAND_STATE_READY;
00468 
00469     /* Process unlocked */
00470     __HAL_UNLOCK(hnand);
00471   }
00472   else
00473   {
00474     return HAL_ERROR;
00475   }
00476 
00477   return HAL_OK;
00478 }
00479 
00480 /**
00481   * @brief  NAND memory reset
00482   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00483   *                the configuration information for NAND module.
00484   * @retval HAL status
00485   */
00486 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
00487 {
00488   uint32_t deviceaddress;
00489 
00490   /* Check the NAND controller state */
00491   if (hnand->State == HAL_NAND_STATE_BUSY)
00492   {
00493     return HAL_BUSY;
00494   }
00495   else if (hnand->State == HAL_NAND_STATE_READY)
00496   {
00497     /* Process Locked */
00498     __HAL_LOCK(hnand);
00499 
00500     /* Update the NAND controller state */
00501     hnand->State = HAL_NAND_STATE_BUSY;
00502 
00503     /* Identify the device address */
00504 #if defined(FMC_Bank2_3)
00505     if (hnand->Init.NandBank == FMC_NAND_BANK2)
00506     {
00507       deviceaddress = NAND_DEVICE1;
00508     }
00509     else
00510     {
00511       deviceaddress = NAND_DEVICE2;
00512     }
00513 #else
00514     deviceaddress = NAND_DEVICE;
00515 #endif
00516 
00517     /* Send NAND reset command */
00518     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
00519 
00520     /* Update the NAND controller state */
00521     hnand->State = HAL_NAND_STATE_READY;
00522 
00523     /* Process unlocked */
00524     __HAL_UNLOCK(hnand);
00525   }
00526   else
00527   {
00528     return HAL_ERROR;
00529   }
00530 
00531   return HAL_OK;
00532 
00533 }
00534 
00535 /**
00536   * @brief  Configure the device: Enter the physical parameters of the device
00537   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00538   *                the configuration information for NAND module.
00539   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
00540   * @retval HAL status
00541   */
00542 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
00543 {
00544   hnand->Config.PageSize           = pDeviceConfig->PageSize;
00545   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
00546   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
00547   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
00548   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
00549   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
00550   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
00551 
00552   return HAL_OK;
00553 }
00554 
00555 /**
00556   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
00557   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00558   *                the configuration information for NAND module.
00559   * @param  pAddress  pointer to NAND address structure
00560   * @param  pBuffer  pointer to destination read buffer
00561   * @param  NumPageToRead  number of pages to read from block
00562   * @retval HAL status
00563   */
00564 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
00565                                         uint32_t NumPageToRead)
00566 {
00567   uint32_t index;
00568   uint32_t tickstart;
00569   uint32_t deviceaddress;
00570   uint32_t numpagesread = 0U;
00571   uint32_t nandaddress;
00572   uint32_t nbpages = NumPageToRead;
00573   uint8_t *buff = pBuffer;
00574 
00575   /* Check the NAND controller state */
00576   if (hnand->State == HAL_NAND_STATE_BUSY)
00577   {
00578     return HAL_BUSY;
00579   }
00580   else if (hnand->State == HAL_NAND_STATE_READY)
00581   {
00582     /* Process Locked */
00583     __HAL_LOCK(hnand);
00584 
00585     /* Update the NAND controller state */
00586     hnand->State = HAL_NAND_STATE_BUSY;
00587 
00588     /* Identify the device address */
00589 #if defined(FMC_Bank2_3)
00590     if (hnand->Init.NandBank == FMC_NAND_BANK2)
00591     {
00592       deviceaddress = NAND_DEVICE1;
00593     }
00594     else
00595     {
00596       deviceaddress = NAND_DEVICE2;
00597     }
00598 #else
00599     deviceaddress = NAND_DEVICE;
00600 #endif
00601 
00602     /* NAND raw address calculation */
00603     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
00604 
00605     /* Page(s) read loop */
00606     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00607     {
00608       /* Send read page command sequence */
00609       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
00610       __DSB();
00611 
00612       /* Cards with page size <= 512 bytes */
00613       if ((hnand->Config.PageSize) <= 512U)
00614       {
00615         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00616         {
00617           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00618           __DSB();
00619           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00620           __DSB();
00621           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00622           __DSB();
00623         }
00624         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00625         {
00626           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00627           __DSB();
00628           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00629           __DSB();
00630           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00631           __DSB();
00632           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
00633           __DSB();
00634         }
00635       }
00636       else /* (hnand->Config.PageSize) > 512 */
00637       {
00638         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00639         {
00640           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00641           __DSB();
00642           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00643           __DSB();
00644           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00645           __DSB();
00646           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00647           __DSB();
00648         }
00649         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00650         {
00651           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00652           __DSB();
00653           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00654           __DSB();
00655           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00656           __DSB();
00657           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00658           __DSB();
00659           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
00660           __DSB();
00661         }
00662       }
00663 
00664       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
00665       __DSB();
00666 
00667 
00668       if (hnand->Config.ExtraCommandEnable == ENABLE)
00669       {
00670         /* Get tick */
00671         tickstart = HAL_GetTick();
00672 
00673         /* Read status until NAND is ready */
00674         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
00675         {
00676           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
00677           {
00678             /* Update the NAND controller state */
00679             hnand->State = HAL_NAND_STATE_ERROR;
00680 
00681             /* Process unlocked */
00682             __HAL_UNLOCK(hnand);
00683 
00684             return HAL_TIMEOUT;
00685           }
00686         }
00687 
00688         /* Go back to read mode */
00689         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
00690         __DSB();
00691       }
00692 
00693       /* Get Data into Buffer */
00694       for (index = 0U; index < hnand->Config.PageSize; index++)
00695       {
00696         *buff = *(uint8_t *)deviceaddress;
00697         buff++;
00698       }
00699 
00700       /* Increment read pages number */
00701       numpagesread++;
00702 
00703       /* Decrement pages to read */
00704       nbpages--;
00705 
00706       /* Increment the NAND address */
00707       nandaddress = (uint32_t)(nandaddress + 1U);
00708     }
00709 
00710     /* Update the NAND controller state */
00711     hnand->State = HAL_NAND_STATE_READY;
00712 
00713     /* Process unlocked */
00714     __HAL_UNLOCK(hnand);
00715   }
00716   else
00717   {
00718     return HAL_ERROR;
00719   }
00720 
00721   return HAL_OK;
00722 }
00723 
00724 /**
00725   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
00726   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00727   *                the configuration information for NAND module.
00728   * @param  pAddress  pointer to NAND address structure
00729   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
00730   * @param  NumPageToRead  number of pages to read from block
00731   * @retval HAL status
00732   */
00733 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
00734                                          uint32_t NumPageToRead)
00735 {
00736   uint32_t index;
00737   uint32_t tickstart;
00738   uint32_t deviceaddress;
00739   uint32_t numpagesread = 0U;
00740   uint32_t nandaddress;
00741   uint32_t nbpages = NumPageToRead;
00742   uint16_t *buff = pBuffer;
00743 
00744   /* Check the NAND controller state */
00745   if (hnand->State == HAL_NAND_STATE_BUSY)
00746   {
00747     return HAL_BUSY;
00748   }
00749   else if (hnand->State == HAL_NAND_STATE_READY)
00750   {
00751     /* Process Locked */
00752     __HAL_LOCK(hnand);
00753 
00754     /* Update the NAND controller state */
00755     hnand->State = HAL_NAND_STATE_BUSY;
00756 
00757     /* Identify the device address */
00758 #if defined(FMC_Bank2_3)
00759     if (hnand->Init.NandBank == FMC_NAND_BANK2)
00760     {
00761       deviceaddress = NAND_DEVICE1;
00762     }
00763     else
00764     {
00765       deviceaddress = NAND_DEVICE2;
00766     }
00767 #else
00768     deviceaddress = NAND_DEVICE;
00769 #endif
00770 
00771     /* NAND raw address calculation */
00772     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
00773 
00774     /* Page(s) read loop */
00775     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00776     {
00777       /* Send read page command sequence */
00778       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
00779       __DSB();
00780 
00781       /* Cards with page size <= 512 bytes */
00782       if ((hnand->Config.PageSize) <= 512U)
00783       {
00784         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00785         {
00786           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00787           __DSB();
00788           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00789           __DSB();
00790           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00791           __DSB();
00792         }
00793         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00794         {
00795           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00796           __DSB();
00797           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00798           __DSB();
00799           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00800           __DSB();
00801           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
00802           __DSB();
00803         }
00804       }
00805       else /* (hnand->Config.PageSize) > 512 */
00806       {
00807         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00808         {
00809           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00810           __DSB();
00811           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00812           __DSB();
00813           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00814           __DSB();
00815           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00816           __DSB();
00817         }
00818         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00819         {
00820           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00821           __DSB();
00822           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00823           __DSB();
00824           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00825           __DSB();
00826           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00827           __DSB();
00828           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
00829           __DSB();
00830         }
00831       }
00832 
00833       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
00834       __DSB();
00835 
00836       if (hnand->Config.ExtraCommandEnable == ENABLE)
00837       {
00838         /* Get tick */
00839         tickstart = HAL_GetTick();
00840 
00841         /* Read status until NAND is ready */
00842         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
00843         {
00844           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
00845           {
00846             /* Update the NAND controller state */
00847             hnand->State = HAL_NAND_STATE_ERROR;
00848 
00849             /* Process unlocked */
00850             __HAL_UNLOCK(hnand);
00851 
00852             return HAL_TIMEOUT;
00853           }
00854         }
00855 
00856         /* Go back to read mode */
00857         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
00858         __DSB();
00859       }
00860 
00861       /* Calculate PageSize */
00862 #if defined(FSMC_PCR2_PWID)
00863     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
00864 #else
00865     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
00866 #endif /* FSMC_PCR2_PWID */
00867       {
00868         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
00869       }
00870       else
00871       {
00872         /* Do nothing */
00873         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
00874       }
00875 
00876       /* Get Data into Buffer */
00877       for (index = 0U; index < hnand->Config.PageSize; index++)
00878       {
00879         *buff = *(uint16_t *)deviceaddress;
00880         buff++;
00881       }
00882 
00883       /* Increment read pages number */
00884       numpagesread++;
00885 
00886       /* Decrement pages to read */
00887       nbpages--;
00888 
00889       /* Increment the NAND address */
00890       nandaddress = (uint32_t)(nandaddress + 1U);
00891     }
00892 
00893     /* Update the NAND controller state */
00894     hnand->State = HAL_NAND_STATE_READY;
00895 
00896     /* Process unlocked */
00897     __HAL_UNLOCK(hnand);
00898   }
00899   else
00900   {
00901     return HAL_ERROR;
00902   }
00903 
00904   return HAL_OK;
00905 }
00906 
00907 /**
00908   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
00909   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00910   *                the configuration information for NAND module.
00911   * @param  pAddress  pointer to NAND address structure
00912   * @param  pBuffer  pointer to source buffer to write
00913   * @param  NumPageToWrite   number of pages to write to block
00914   * @retval HAL status
00915   */
00916 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
00917                                          uint32_t NumPageToWrite)
00918 {
00919   uint32_t index;
00920   uint32_t tickstart;
00921   uint32_t deviceaddress;
00922   uint32_t numpageswritten = 0U;
00923   uint32_t nandaddress;
00924   uint32_t nbpages = NumPageToWrite;
00925   uint8_t *buff = pBuffer;
00926 
00927   /* Check the NAND controller state */
00928   if (hnand->State == HAL_NAND_STATE_BUSY)
00929   {
00930     return HAL_BUSY;
00931   }
00932   else if (hnand->State == HAL_NAND_STATE_READY)
00933   {
00934     /* Process Locked */
00935     __HAL_LOCK(hnand);
00936 
00937     /* Update the NAND controller state */
00938     hnand->State = HAL_NAND_STATE_BUSY;
00939 
00940     /* Identify the device address */
00941 #if defined(FMC_Bank2_3)
00942     if (hnand->Init.NandBank == FMC_NAND_BANK2)
00943     {
00944       deviceaddress = NAND_DEVICE1;
00945     }
00946     else
00947     {
00948       deviceaddress = NAND_DEVICE2;
00949     }
00950 #else
00951     deviceaddress = NAND_DEVICE;
00952 #endif
00953 
00954     /* NAND raw address calculation */
00955     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
00956 
00957     /* Page(s) write loop */
00958     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00959     {
00960       /* Send write page command sequence */
00961       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
00962       __DSB();
00963       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
00964       __DSB();
00965 
00966       /* Cards with page size <= 512 bytes */
00967       if ((hnand->Config.PageSize) <= 512U)
00968       {
00969         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00970         {
00971           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00972           __DSB();
00973           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00974           __DSB();
00975           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00976           __DSB();
00977         }
00978         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00979         {
00980           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00981           __DSB();
00982           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00983           __DSB();
00984           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
00985           __DSB();
00986           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
00987           __DSB();
00988         }
00989       }
00990       else /* (hnand->Config.PageSize) > 512 */
00991       {
00992         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
00993         {
00994           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00995           __DSB();
00996           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
00997           __DSB();
00998           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
00999           __DSB();
01000           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01001           __DSB();
01002         }
01003         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01004         {
01005           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01006           __DSB();
01007           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01008           __DSB();
01009           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01010           __DSB();
01011           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01012           __DSB();
01013           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01014           __DSB();
01015         }
01016       }
01017 
01018       /* Write data to memory */
01019       for (index = 0U; index < hnand->Config.PageSize; index++)
01020       {
01021         *(__IO uint8_t *)deviceaddress = *buff;
01022         buff++;
01023         __DSB();
01024       }
01025 
01026       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01027       __DSB();
01028 
01029       /* Get tick */
01030       tickstart = HAL_GetTick();
01031 
01032       /* Read status until NAND is ready */
01033       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01034       {
01035         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01036         {
01037           /* Update the NAND controller state */
01038           hnand->State = HAL_NAND_STATE_ERROR;
01039 
01040           /* Process unlocked */
01041           __HAL_UNLOCK(hnand);
01042 
01043           return HAL_TIMEOUT;
01044         }
01045       }
01046 
01047       /* Increment written pages number */
01048       numpageswritten++;
01049 
01050       /* Decrement pages to write */
01051       nbpages--;
01052 
01053       /* Increment the NAND address */
01054       nandaddress = (uint32_t)(nandaddress + 1U);
01055     }
01056 
01057     /* Update the NAND controller state */
01058     hnand->State = HAL_NAND_STATE_READY;
01059 
01060     /* Process unlocked */
01061     __HAL_UNLOCK(hnand);
01062   }
01063   else
01064   {
01065     return HAL_ERROR;
01066   }
01067 
01068   return HAL_OK;
01069 }
01070 
01071 /**
01072   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
01073   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01074   *                the configuration information for NAND module.
01075   * @param  pAddress  pointer to NAND address structure
01076   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
01077   * @param  NumPageToWrite   number of pages to write to block
01078   * @retval HAL status
01079   */
01080 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
01081                                           uint32_t NumPageToWrite)
01082 {
01083   uint32_t index;
01084   uint32_t tickstart;
01085   uint32_t deviceaddress;
01086   uint32_t numpageswritten = 0U;
01087   uint32_t nandaddress;
01088   uint32_t nbpages = NumPageToWrite;
01089   uint16_t *buff = pBuffer;
01090 
01091   /* Check the NAND controller state */
01092   if (hnand->State == HAL_NAND_STATE_BUSY)
01093   {
01094     return HAL_BUSY;
01095   }
01096   else if (hnand->State == HAL_NAND_STATE_READY)
01097   {
01098     /* Process Locked */
01099     __HAL_LOCK(hnand);
01100 
01101     /* Update the NAND controller state */
01102     hnand->State = HAL_NAND_STATE_BUSY;
01103 
01104     /* Identify the device address */
01105 #if defined(FMC_Bank2_3)
01106     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01107     {
01108       deviceaddress = NAND_DEVICE1;
01109     }
01110     else
01111     {
01112       deviceaddress = NAND_DEVICE2;
01113     }
01114 #else
01115     deviceaddress = NAND_DEVICE;
01116 #endif
01117 
01118     /* NAND raw address calculation */
01119     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
01120 
01121     /* Page(s) write loop */
01122     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01123     {
01124       /* Send write page command sequence */
01125       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
01126       __DSB();
01127       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
01128       __DSB();
01129 
01130       /* Cards with page size <= 512 bytes */
01131       if ((hnand->Config.PageSize) <= 512U)
01132       {
01133         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01134         {
01135           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01136           __DSB();
01137           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01138           __DSB();
01139           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01140           __DSB();
01141         }
01142         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01143         {
01144           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01145           __DSB();
01146           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01147           __DSB();
01148           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01149           __DSB();
01150           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01151           __DSB();
01152         }
01153       }
01154       else /* (hnand->Config.PageSize) > 512 */
01155       {
01156         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01157         {
01158           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01159           __DSB();
01160           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01161           __DSB();
01162           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01163           __DSB();
01164           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01165           __DSB();
01166         }
01167         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01168         {
01169           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01170           __DSB();
01171           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01172           __DSB();
01173           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01174           __DSB();
01175           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01176           __DSB();
01177           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01178           __DSB();
01179         }
01180       }
01181 
01182       /* Calculate PageSize */
01183 #if defined(FSMC_PCR2_PWID)
01184     if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
01185 #else
01186     if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
01187 #endif /* FSMC_PCR2_PWID */
01188       {
01189         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
01190       }
01191       else
01192       {
01193         /* Do nothing */
01194         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
01195       }
01196 
01197       /* Write data to memory */
01198       for (index = 0U; index < hnand->Config.PageSize; index++)
01199       {
01200         *(__IO uint16_t *)deviceaddress = *buff;
01201         buff++;
01202         __DSB();
01203       }
01204 
01205       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01206       __DSB();
01207 
01208       /* Get tick */
01209       tickstart = HAL_GetTick();
01210 
01211       /* Read status until NAND is ready */
01212       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01213       {
01214         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01215         {
01216           /* Update the NAND controller state */
01217           hnand->State = HAL_NAND_STATE_ERROR;
01218 
01219           /* Process unlocked */
01220           __HAL_UNLOCK(hnand);
01221 
01222           return HAL_TIMEOUT;
01223         }
01224       }
01225 
01226       /* Increment written pages number */
01227       numpageswritten++;
01228 
01229       /* Decrement pages to write */
01230       nbpages--;
01231 
01232       /* Increment the NAND address */
01233       nandaddress = (uint32_t)(nandaddress + 1U);
01234     }
01235 
01236     /* Update the NAND controller state */
01237     hnand->State = HAL_NAND_STATE_READY;
01238 
01239     /* Process unlocked */
01240     __HAL_UNLOCK(hnand);
01241   }
01242   else
01243   {
01244     return HAL_ERROR;
01245   }
01246 
01247   return HAL_OK;
01248 }
01249 
01250 /**
01251   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
01252   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01253   *                the configuration information for NAND module.
01254   * @param  pAddress  pointer to NAND address structure
01255   * @param  pBuffer pointer to source buffer to write
01256   * @param  NumSpareAreaToRead Number of spare area to read
01257   * @retval HAL status
01258   */
01259 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
01260                                              uint32_t NumSpareAreaToRead)
01261 {
01262   uint32_t index;
01263   uint32_t tickstart;
01264   uint32_t deviceaddress;
01265   uint32_t numsparearearead = 0U;
01266   uint32_t nandaddress;
01267   uint32_t columnaddress;
01268   uint32_t nbspare = NumSpareAreaToRead;
01269   uint8_t *buff = pBuffer;
01270 
01271   /* Check the NAND controller state */
01272   if (hnand->State == HAL_NAND_STATE_BUSY)
01273   {
01274     return HAL_BUSY;
01275   }
01276   else if (hnand->State == HAL_NAND_STATE_READY)
01277   {
01278     /* Process Locked */
01279     __HAL_LOCK(hnand);
01280 
01281     /* Update the NAND controller state */
01282     hnand->State = HAL_NAND_STATE_BUSY;
01283 
01284     /* Identify the device address */
01285 #if defined(FMC_Bank2_3)
01286     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01287     {
01288       deviceaddress = NAND_DEVICE1;
01289     }
01290     else
01291     {
01292       deviceaddress = NAND_DEVICE2;
01293     }
01294 #else
01295     deviceaddress = NAND_DEVICE;
01296 #endif
01297 
01298     /* NAND raw address calculation */
01299     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
01300 
01301     /* Column in page address */
01302     columnaddress = COLUMN_ADDRESS(hnand);
01303 
01304     /* Spare area(s) read loop */
01305     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01306     {
01307       /* Cards with page size <= 512 bytes */
01308       if ((hnand->Config.PageSize) <= 512U)
01309       {
01310         /* Send read spare area command sequence */
01311         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
01312         __DSB();
01313 
01314         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01315         {
01316           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01317           __DSB();
01318           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01319           __DSB();
01320           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01321           __DSB();
01322         }
01323         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01324         {
01325           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01326           __DSB();
01327           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01328           __DSB();
01329           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01330           __DSB();
01331           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01332           __DSB();
01333         }
01334       }
01335       else /* (hnand->Config.PageSize) > 512 */
01336       {
01337         /* Send read spare area command sequence */
01338         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
01339         __DSB();
01340 
01341         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01342         {
01343           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01344           __DSB();
01345           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01346           __DSB();
01347           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01348           __DSB();
01349           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01350           __DSB();
01351         }
01352         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01353         {
01354           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01355           __DSB();
01356           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01357           __DSB();
01358           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01359           __DSB();
01360           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01361           __DSB();
01362           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01363           __DSB();
01364         }
01365       }
01366 
01367       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
01368       __DSB();
01369 
01370       if (hnand->Config.ExtraCommandEnable == ENABLE)
01371       {
01372         /* Get tick */
01373         tickstart = HAL_GetTick();
01374 
01375         /* Read status until NAND is ready */
01376         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01377         {
01378           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01379           {
01380             /* Update the NAND controller state */
01381             hnand->State = HAL_NAND_STATE_ERROR;
01382 
01383             /* Process unlocked */
01384             __HAL_UNLOCK(hnand);
01385 
01386             return HAL_TIMEOUT;
01387           }
01388         }
01389 
01390         /* Go back to read mode */
01391         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
01392         __DSB();
01393       }
01394 
01395       /* Get Data into Buffer */
01396       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
01397       {
01398         *buff = *(uint8_t *)deviceaddress;
01399         buff++;
01400       }
01401 
01402       /* Increment read spare areas number */
01403       numsparearearead++;
01404 
01405       /* Decrement spare areas to read */
01406       nbspare--;
01407 
01408       /* Increment the NAND address */
01409       nandaddress = (uint32_t)(nandaddress + 1U);
01410     }
01411 
01412     /* Update the NAND controller state */
01413     hnand->State = HAL_NAND_STATE_READY;
01414 
01415     /* Process unlocked */
01416     __HAL_UNLOCK(hnand);
01417   }
01418   else
01419   {
01420     return HAL_ERROR;
01421   }
01422 
01423   return HAL_OK;
01424 }
01425 
01426 /**
01427   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
01428   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01429   *                the configuration information for NAND module.
01430   * @param  pAddress  pointer to NAND address structure
01431   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
01432   * @param  NumSpareAreaToRead Number of spare area to read
01433   * @retval HAL status
01434   */
01435 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
01436                                               uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
01437 {
01438   uint32_t index;
01439   uint32_t tickstart;
01440   uint32_t deviceaddress;
01441   uint32_t numsparearearead = 0U;
01442   uint32_t nandaddress;
01443   uint32_t columnaddress;
01444   uint32_t nbspare = NumSpareAreaToRead;
01445   uint16_t *buff = pBuffer;
01446 
01447   /* Check the NAND controller state */
01448   if (hnand->State == HAL_NAND_STATE_BUSY)
01449   {
01450     return HAL_BUSY;
01451   }
01452   else if (hnand->State == HAL_NAND_STATE_READY)
01453   {
01454     /* Process Locked */
01455     __HAL_LOCK(hnand);
01456 
01457     /* Update the NAND controller state */
01458     hnand->State = HAL_NAND_STATE_BUSY;
01459 
01460     /* Identify the device address */
01461 #if defined(FMC_Bank2_3)
01462     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01463     {
01464       deviceaddress = NAND_DEVICE1;
01465     }
01466     else
01467     {
01468       deviceaddress = NAND_DEVICE2;
01469     }
01470 #else
01471     deviceaddress = NAND_DEVICE;
01472 #endif
01473 
01474     /* NAND raw address calculation */
01475     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
01476 
01477     /* Column in page address */
01478     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
01479 
01480     /* Spare area(s) read loop */
01481     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01482     {
01483       /* Cards with page size <= 512 bytes */
01484       if ((hnand->Config.PageSize) <= 512U)
01485       {
01486         /* Send read spare area command sequence */
01487         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
01488         __DSB();
01489 
01490         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01491         {
01492           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01493           __DSB();
01494           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01495           __DSB();
01496           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01497           __DSB();
01498         }
01499         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01500         {
01501           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01502           __DSB();
01503           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01504           __DSB();
01505           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01506           __DSB();
01507           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01508           __DSB();
01509         }
01510       }
01511       else /* (hnand->Config.PageSize) > 512 */
01512       {
01513         /* Send read spare area command sequence */
01514         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
01515         __DSB();
01516 
01517         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01518         {
01519           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01520           __DSB();
01521           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01522           __DSB();
01523           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01524           __DSB();
01525           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01526           __DSB();
01527         }
01528         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01529         {
01530           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01531           __DSB();
01532           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01533           __DSB();
01534           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01535           __DSB();
01536           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01537           __DSB();
01538           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01539           __DSB();
01540         }
01541       }
01542 
01543       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
01544       __DSB();
01545 
01546       if (hnand->Config.ExtraCommandEnable == ENABLE)
01547       {
01548         /* Get tick */
01549         tickstart = HAL_GetTick();
01550 
01551         /* Read status until NAND is ready */
01552         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01553         {
01554           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01555           {
01556             /* Update the NAND controller state */
01557             hnand->State = HAL_NAND_STATE_ERROR;
01558 
01559             /* Process unlocked */
01560             __HAL_UNLOCK(hnand);
01561 
01562             return HAL_TIMEOUT;
01563           }
01564         }
01565 
01566         /* Go back to read mode */
01567         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
01568         __DSB();
01569       }
01570 
01571       /* Get Data into Buffer */
01572       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
01573       {
01574         *buff = *(uint16_t *)deviceaddress;
01575         buff++;
01576       }
01577 
01578       /* Increment read spare areas number */
01579       numsparearearead++;
01580 
01581       /* Decrement spare areas to read */
01582       nbspare--;
01583 
01584       /* Increment the NAND address */
01585       nandaddress = (uint32_t)(nandaddress + 1U);
01586     }
01587 
01588     /* Update the NAND controller state */
01589     hnand->State = HAL_NAND_STATE_READY;
01590 
01591     /* Process unlocked */
01592     __HAL_UNLOCK(hnand);
01593   }
01594   else
01595   {
01596     return HAL_ERROR;
01597   }
01598 
01599   return HAL_OK;
01600 }
01601 
01602 /**
01603   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
01604   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01605   *                the configuration information for NAND module.
01606   * @param  pAddress  pointer to NAND address structure
01607   * @param  pBuffer  pointer to source buffer to write
01608   * @param  NumSpareAreaTowrite   number of spare areas to write to block
01609   * @retval HAL status
01610   */
01611 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
01612                                               uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
01613 {
01614   uint32_t index;
01615   uint32_t tickstart;
01616   uint32_t deviceaddress;
01617   uint32_t numspareareawritten = 0U;
01618   uint32_t nandaddress;
01619   uint32_t columnaddress;
01620   uint32_t nbspare = NumSpareAreaTowrite;
01621   uint8_t *buff = pBuffer;
01622 
01623   /* Check the NAND controller state */
01624   if (hnand->State == HAL_NAND_STATE_BUSY)
01625   {
01626     return HAL_BUSY;
01627   }
01628   else if (hnand->State == HAL_NAND_STATE_READY)
01629   {
01630     /* Process Locked */
01631     __HAL_LOCK(hnand);
01632 
01633     /* Update the NAND controller state */
01634     hnand->State = HAL_NAND_STATE_BUSY;
01635 
01636     /* Identify the device address */
01637 #if defined(FMC_Bank2_3)
01638     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01639     {
01640       deviceaddress = NAND_DEVICE1;
01641     }
01642     else
01643     {
01644       deviceaddress = NAND_DEVICE2;
01645     }
01646 #else
01647     deviceaddress = NAND_DEVICE;
01648 #endif
01649 
01650     /* Page address calculation */
01651     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
01652 
01653     /* Column in page address */
01654     columnaddress = COLUMN_ADDRESS(hnand);
01655 
01656     /* Spare area(s) write loop */
01657     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01658     {
01659       /* Cards with page size <= 512 bytes */
01660       if ((hnand->Config.PageSize) <= 512U)
01661       {
01662         /* Send write Spare area command sequence */
01663         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
01664         __DSB();
01665         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
01666         __DSB();
01667 
01668         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01669         {
01670           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01671           __DSB();
01672           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01673           __DSB();
01674           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01675           __DSB();
01676         }
01677         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01678         {
01679           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01680           __DSB();
01681           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01682           __DSB();
01683           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01684           __DSB();
01685           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01686           __DSB();
01687         }
01688       }
01689       else /* (hnand->Config.PageSize) > 512 */
01690       {
01691         /* Send write Spare area command sequence */
01692         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
01693         __DSB();
01694         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
01695         __DSB();
01696 
01697         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01698         {
01699           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01700           __DSB();
01701           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01702           __DSB();
01703           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01704           __DSB();
01705           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01706           __DSB();
01707         }
01708         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01709         {
01710           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01711           __DSB();
01712           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01713           __DSB();
01714           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01715           __DSB();
01716           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01717           __DSB();
01718           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01719           __DSB();
01720         }
01721       }
01722 
01723       /* Write data to memory */
01724       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
01725       {
01726         *(__IO uint8_t *)deviceaddress = *buff;
01727         buff++;
01728         __DSB();
01729       }
01730 
01731       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01732       __DSB();
01733 
01734       /* Get tick */
01735       tickstart = HAL_GetTick();
01736 
01737       /* Read status until NAND is ready */
01738       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01739       {
01740         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01741         {
01742           /* Update the NAND controller state */
01743           hnand->State = HAL_NAND_STATE_ERROR;
01744 
01745           /* Process unlocked */
01746           __HAL_UNLOCK(hnand);
01747 
01748           return HAL_TIMEOUT;
01749         }
01750       }
01751 
01752       /* Increment written spare areas number */
01753       numspareareawritten++;
01754 
01755       /* Decrement spare areas to write */
01756       nbspare--;
01757 
01758       /* Increment the NAND address */
01759       nandaddress = (uint32_t)(nandaddress + 1U);
01760     }
01761 
01762     /* Update the NAND controller state */
01763     hnand->State = HAL_NAND_STATE_READY;
01764 
01765     /* Process unlocked */
01766     __HAL_UNLOCK(hnand);
01767   }
01768   else
01769   {
01770     return HAL_ERROR;
01771   }
01772 
01773   return HAL_OK;
01774 }
01775 
01776 /**
01777   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
01778   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01779   *                the configuration information for NAND module.
01780   * @param  pAddress  pointer to NAND address structure
01781   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
01782   * @param  NumSpareAreaTowrite   number of spare areas to write to block
01783   * @retval HAL status
01784   */
01785 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
01786                                                uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
01787 {
01788   uint32_t index;
01789   uint32_t tickstart;
01790   uint32_t deviceaddress;
01791   uint32_t numspareareawritten = 0U;
01792   uint32_t nandaddress;
01793   uint32_t columnaddress;
01794   uint32_t nbspare = NumSpareAreaTowrite;
01795   uint16_t *buff = pBuffer;
01796 
01797   /* Check the NAND controller state */
01798   if (hnand->State == HAL_NAND_STATE_BUSY)
01799   {
01800     return HAL_BUSY;
01801   }
01802   else if (hnand->State == HAL_NAND_STATE_READY)
01803   {
01804     /* Process Locked */
01805     __HAL_LOCK(hnand);
01806 
01807     /* Update the NAND controller state */
01808     hnand->State = HAL_NAND_STATE_BUSY;
01809 
01810     /* Identify the device address */
01811 #if defined(FMC_Bank2_3)
01812     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01813     {
01814       deviceaddress = NAND_DEVICE1;
01815     }
01816     else
01817     {
01818       deviceaddress = NAND_DEVICE2;
01819     }
01820 #else
01821     deviceaddress = NAND_DEVICE;
01822 #endif
01823 
01824     /* NAND raw address calculation */
01825     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
01826 
01827     /* Column in page address */
01828     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
01829 
01830     /* Spare area(s) write loop */
01831     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01832     {
01833       /* Cards with page size <= 512 bytes */
01834       if ((hnand->Config.PageSize) <= 512U)
01835       {
01836         /* Send write Spare area command sequence */
01837         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
01838         __DSB();
01839         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
01840         __DSB();
01841 
01842         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01843         {
01844           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01845           __DSB();
01846           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01847           __DSB();
01848           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01849           __DSB();
01850         }
01851         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01852         {
01853           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
01854           __DSB();
01855           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01856           __DSB();
01857           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01858           __DSB();
01859           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01860           __DSB();
01861         }
01862       }
01863       else /* (hnand->Config.PageSize) > 512 */
01864       {
01865         /* Send write Spare area command sequence */
01866         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
01867         __DSB();
01868         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
01869         __DSB();
01870 
01871         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
01872         {
01873           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01874           __DSB();
01875           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01876           __DSB();
01877           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01878           __DSB();
01879           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01880           __DSB();
01881         }
01882         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01883         {
01884           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
01885           __DSB();
01886           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
01887           __DSB();
01888           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
01889           __DSB();
01890           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
01891           __DSB();
01892           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
01893           __DSB();
01894         }
01895       }
01896 
01897       /* Write data to memory */
01898       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
01899       {
01900         *(__IO uint16_t *)deviceaddress = *buff;
01901         buff++;
01902         __DSB();
01903       }
01904 
01905       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01906       __DSB();
01907 
01908       /* Get tick */
01909       tickstart = HAL_GetTick();
01910 
01911       /* Read status until NAND is ready */
01912       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01913       {
01914         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01915         {
01916           /* Update the NAND controller state */
01917           hnand->State = HAL_NAND_STATE_ERROR;
01918 
01919           /* Process unlocked */
01920           __HAL_UNLOCK(hnand);
01921 
01922           return HAL_TIMEOUT;
01923         }
01924       }
01925 
01926       /* Increment written spare areas number */
01927       numspareareawritten++;
01928 
01929       /* Decrement spare areas to write */
01930       nbspare--;
01931 
01932       /* Increment the NAND address */
01933       nandaddress = (uint32_t)(nandaddress + 1U);
01934     }
01935 
01936     /* Update the NAND controller state */
01937     hnand->State = HAL_NAND_STATE_READY;
01938 
01939     /* Process unlocked */
01940     __HAL_UNLOCK(hnand);
01941   }
01942   else
01943   {
01944     return HAL_ERROR;
01945   }
01946 
01947   return HAL_OK;
01948 }
01949 
01950 /**
01951   * @brief  NAND memory Block erase
01952   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01953   *                the configuration information for NAND module.
01954   * @param  pAddress  pointer to NAND address structure
01955   * @retval HAL status
01956   */
01957 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
01958 {
01959   uint32_t deviceaddress;
01960 
01961   /* Check the NAND controller state */
01962   if (hnand->State == HAL_NAND_STATE_BUSY)
01963   {
01964     return HAL_BUSY;
01965   }
01966   else if (hnand->State == HAL_NAND_STATE_READY)
01967   {
01968     /* Process Locked */
01969     __HAL_LOCK(hnand);
01970 
01971     /* Update the NAND controller state */
01972     hnand->State = HAL_NAND_STATE_BUSY;
01973 
01974     /* Identify the device address */
01975 #if defined(FMC_Bank2_3)
01976     if (hnand->Init.NandBank == FMC_NAND_BANK2)
01977     {
01978       deviceaddress = NAND_DEVICE1;
01979     }
01980     else
01981     {
01982       deviceaddress = NAND_DEVICE2;
01983     }
01984 #else
01985     deviceaddress = NAND_DEVICE;
01986 #endif
01987 
01988     /* Send Erase block command sequence */
01989     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
01990     __DSB();
01991     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01992     __DSB();
01993     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01994     __DSB();
01995     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01996     __DSB();
01997 
01998     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
01999     __DSB();
02000 
02001     /* Update the NAND controller state */
02002     hnand->State = HAL_NAND_STATE_READY;
02003 
02004     /* Process unlocked */
02005     __HAL_UNLOCK(hnand);
02006   }
02007   else
02008   {
02009     return HAL_ERROR;
02010   }
02011 
02012   return HAL_OK;
02013 }
02014 
02015 /**
02016   * @brief  Increment the NAND memory address
02017   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02018   *                the configuration information for NAND module.
02019   * @param pAddress pointer to NAND address structure
02020   * @retval The new status of the increment address operation. It can be:
02021   *           - NAND_VALID_ADDRESS: When the new address is valid address
02022   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
02023   */
02024 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
02025 {
02026   uint32_t status = NAND_VALID_ADDRESS;
02027 
02028   /* Increment page address */
02029   pAddress->Page++;
02030 
02031   /* Check NAND address is valid */
02032   if (pAddress->Page == hnand->Config.BlockSize)
02033   {
02034     pAddress->Page = 0;
02035     pAddress->Block++;
02036 
02037     if (pAddress->Block == hnand->Config.PlaneSize)
02038     {
02039       pAddress->Block = 0;
02040       pAddress->Plane++;
02041 
02042       if (pAddress->Plane == (hnand->Config.PlaneNbr))
02043       {
02044         status = NAND_INVALID_ADDRESS;
02045       }
02046     }
02047   }
02048 
02049   return (status);
02050 }
02051 
02052 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
02053 /**
02054   * @brief  Register a User NAND Callback
02055   *         To be used instead of the weak (surcharged) predefined callback
02056   * @param hnand : NAND handle
02057   * @param CallbackId : ID of the callback to be registered
02058   *        This parameter can be one of the following values:
02059   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
02060   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
02061   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
02062   * @param pCallback : pointer to the Callback function
02063   * @retval status
02064   */
02065 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
02066                                             pNAND_CallbackTypeDef pCallback)
02067 {
02068   HAL_StatusTypeDef status = HAL_OK;
02069 
02070   if (pCallback == NULL)
02071   {
02072     return HAL_ERROR;
02073   }
02074 
02075   /* Process locked */
02076   __HAL_LOCK(hnand);
02077 
02078   if (hnand->State == HAL_NAND_STATE_READY)
02079   {
02080     switch (CallbackId)
02081     {
02082       case HAL_NAND_MSP_INIT_CB_ID :
02083         hnand->MspInitCallback = pCallback;
02084         break;
02085       case HAL_NAND_MSP_DEINIT_CB_ID :
02086         hnand->MspDeInitCallback = pCallback;
02087         break;
02088       case HAL_NAND_IT_CB_ID :
02089         hnand->ItCallback = pCallback;
02090         break;
02091       default :
02092         /* update return status */
02093         status =  HAL_ERROR;
02094         break;
02095     }
02096   }
02097   else if (hnand->State == HAL_NAND_STATE_RESET)
02098   {
02099     switch (CallbackId)
02100     {
02101       case HAL_NAND_MSP_INIT_CB_ID :
02102         hnand->MspInitCallback = pCallback;
02103         break;
02104       case HAL_NAND_MSP_DEINIT_CB_ID :
02105         hnand->MspDeInitCallback = pCallback;
02106         break;
02107       default :
02108         /* update return status */
02109         status =  HAL_ERROR;
02110         break;
02111     }
02112   }
02113   else
02114   {
02115     /* update return status */
02116     status =  HAL_ERROR;
02117   }
02118 
02119   /* Release Lock */
02120   __HAL_UNLOCK(hnand);
02121   return status;
02122 }
02123 
02124 /**
02125   * @brief  Unregister a User NAND Callback
02126   *         NAND Callback is redirected to the weak (surcharged) predefined callback
02127   * @param hnand : NAND handle
02128   * @param CallbackId : ID of the callback to be unregistered
02129   *        This parameter can be one of the following values:
02130   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
02131   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
02132   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
02133   * @retval status
02134   */
02135 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
02136 {
02137   HAL_StatusTypeDef status = HAL_OK;
02138 
02139   /* Process locked */
02140   __HAL_LOCK(hnand);
02141 
02142   if (hnand->State == HAL_NAND_STATE_READY)
02143   {
02144     switch (CallbackId)
02145     {
02146       case HAL_NAND_MSP_INIT_CB_ID :
02147         hnand->MspInitCallback = HAL_NAND_MspInit;
02148         break;
02149       case HAL_NAND_MSP_DEINIT_CB_ID :
02150         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
02151         break;
02152       case HAL_NAND_IT_CB_ID :
02153         hnand->ItCallback = HAL_NAND_ITCallback;
02154         break;
02155       default :
02156         /* update return status */
02157         status =  HAL_ERROR;
02158         break;
02159     }
02160   }
02161   else if (hnand->State == HAL_NAND_STATE_RESET)
02162   {
02163     switch (CallbackId)
02164     {
02165       case HAL_NAND_MSP_INIT_CB_ID :
02166         hnand->MspInitCallback = HAL_NAND_MspInit;
02167         break;
02168       case HAL_NAND_MSP_DEINIT_CB_ID :
02169         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
02170         break;
02171       default :
02172         /* update return status */
02173         status =  HAL_ERROR;
02174         break;
02175     }
02176   }
02177   else
02178   {
02179     /* update return status */
02180     status =  HAL_ERROR;
02181   }
02182 
02183   /* Release Lock */
02184   __HAL_UNLOCK(hnand);
02185   return status;
02186 }
02187 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
02188 
02189 /**
02190   * @}
02191   */
02192 
02193 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
02194   *  @brief   management functions
02195   *
02196 @verbatim
02197   ==============================================================================
02198                          ##### NAND Control functions #####
02199   ==============================================================================
02200   [..]
02201     This subsection provides a set of functions allowing to control dynamically
02202     the NAND interface.
02203 
02204 @endverbatim
02205   * @{
02206   */
02207 
02208 
02209 /**
02210   * @brief  Enables dynamically NAND ECC feature.
02211   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02212   *                the configuration information for NAND module.
02213   * @retval HAL status
02214   */
02215 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
02216 {
02217   /* Check the NAND controller state */
02218   if (hnand->State == HAL_NAND_STATE_BUSY)
02219   {
02220     return HAL_BUSY;
02221   }
02222   else if (hnand->State == HAL_NAND_STATE_READY)
02223   {
02224     /* Update the NAND state */
02225     hnand->State = HAL_NAND_STATE_BUSY;
02226 
02227     /* Enable ECC feature */
02228     (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
02229 
02230     /* Update the NAND state */
02231     hnand->State = HAL_NAND_STATE_READY;
02232   }
02233   else
02234   {
02235     return HAL_ERROR;
02236   }
02237 
02238   return HAL_OK;
02239 }
02240 
02241 /**
02242   * @brief  Disables dynamically FMC_NAND ECC feature.
02243   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02244   *                the configuration information for NAND module.
02245   * @retval HAL status
02246   */
02247 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
02248 {
02249   /* Check the NAND controller state */
02250   if (hnand->State == HAL_NAND_STATE_BUSY)
02251   {
02252     return HAL_BUSY;
02253   }
02254   else if (hnand->State == HAL_NAND_STATE_READY)
02255   {
02256     /* Update the NAND state */
02257     hnand->State = HAL_NAND_STATE_BUSY;
02258 
02259     /* Disable ECC feature */
02260     (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
02261 
02262     /* Update the NAND state */
02263     hnand->State = HAL_NAND_STATE_READY;
02264   }
02265   else
02266   {
02267     return HAL_ERROR;
02268   }
02269 
02270   return HAL_OK;
02271 }
02272 
02273 /**
02274   * @brief  Disables dynamically NAND ECC feature.
02275   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02276   *                the configuration information for NAND module.
02277   * @param  ECCval pointer to ECC value
02278   * @param  Timeout maximum timeout to wait
02279   * @retval HAL status
02280   */
02281 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
02282 {
02283   HAL_StatusTypeDef status;
02284 
02285   /* Check the NAND controller state */
02286   if (hnand->State == HAL_NAND_STATE_BUSY)
02287   {
02288     return HAL_BUSY;
02289   }
02290   else if (hnand->State == HAL_NAND_STATE_READY)
02291   {
02292     /* Update the NAND state */
02293     hnand->State = HAL_NAND_STATE_BUSY;
02294 
02295     /* Get NAND ECC value */
02296     status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
02297 
02298     /* Update the NAND state */
02299     hnand->State = HAL_NAND_STATE_READY;
02300   }
02301   else
02302   {
02303     return HAL_ERROR;
02304   }
02305 
02306   return status;
02307 }
02308 
02309 /**
02310   * @}
02311   */
02312 
02313 
02314 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
02315   *  @brief   Peripheral State functions
02316   *
02317 @verbatim
02318   ==============================================================================
02319                          ##### NAND State functions #####
02320   ==============================================================================
02321   [..]
02322     This subsection permits to get in run-time the status of the NAND controller
02323     and the data flow.
02324 
02325 @endverbatim
02326   * @{
02327   */
02328 
02329 /**
02330   * @brief  return the NAND state
02331   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02332   *                the configuration information for NAND module.
02333   * @retval HAL state
02334   */
02335 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
02336 {
02337   return hnand->State;
02338 }
02339 
02340 /**
02341   * @brief  NAND memory read status
02342   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
02343   *                the configuration information for NAND module.
02344   * @retval NAND status
02345   */
02346 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
02347 {
02348   uint32_t data;
02349   uint32_t deviceaddress;
02350   UNUSED(hnand);
02351 
02352   /* Identify the device address */
02353 #if defined(FMC_Bank2_3)
02354   if (hnand->Init.NandBank == FMC_NAND_BANK2)
02355   {
02356     deviceaddress = NAND_DEVICE1;
02357   }
02358   else
02359   {
02360     deviceaddress = NAND_DEVICE2;
02361   }
02362 #else
02363   deviceaddress = NAND_DEVICE;
02364 #endif
02365 
02366   /* Send Read status operation command */
02367   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
02368 
02369   /* Read status register data */
02370   data = *(__IO uint8_t *)deviceaddress;
02371 
02372   /* Return the status */
02373   if ((data & NAND_ERROR) == NAND_ERROR)
02374   {
02375     return NAND_ERROR;
02376   }
02377   else if ((data & NAND_READY) == NAND_READY)
02378   {
02379     return NAND_READY;
02380   }
02381   else
02382   {
02383     return NAND_BUSY;
02384   }
02385 }
02386 
02387 /**
02388   * @}
02389   */
02390 
02391 /**
02392   * @}
02393   */
02394 
02395 /**
02396   * @}
02397   */
02398 
02399 #endif /* HAL_NAND_MODULE_ENABLED  */
02400 
02401 /**
02402   * @}
02403   */
02404 
02405 #endif /* FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3 */
02406 
02407 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/