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