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