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