Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_nand.c
0004   * @author  MCD Application Team
0005   * @brief   NAND HAL module driver.
0006   *          This file provides a generic firmware to drive NAND memories mounted
0007   *          as external device.
0008   *
0009   ******************************************************************************
0010   * @attention
0011   *
0012   * Copyright (c) 2017 STMicroelectronics.
0013   * All rights reserved.
0014   *
0015   * This software is licensed under terms that can be found in the LICENSE file
0016   * in the root directory of this software component.
0017   * If no LICENSE file comes with this software, it is provided AS-IS.
0018   *
0019   ******************************************************************************
0020   @verbatim
0021   ==============================================================================
0022                          ##### How to use this driver #####
0023   ==============================================================================
0024     [..]
0025       This driver is a generic layered driver which contains a set of APIs used to
0026       control NAND flash memories. It uses the FMC layer functions to interface
0027       with NAND devices. This driver is used as follows:
0028 
0029       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
0030           with control and timing parameters for both common and attribute spaces.
0031 
0032       (+) Read NAND flash memory maker and device IDs using the function
0033           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
0034           structure declared by the function caller.
0035 
0036       (+) Access NAND flash memory by read/write operations using the functions
0037           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
0038           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
0039           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
0040           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
0041           to read/write page(s)/spare area(s). These functions use specific device
0042           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
0043           structure. The read/write address information is contained by the Nand_Address_Typedef
0044           structure passed as parameter.
0045 
0046       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
0047 
0048       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
0049           The erase block address information is contained in the Nand_Address_Typedef
0050           structure passed as parameter.
0051 
0052       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
0053 
0054       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
0055           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
0056           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
0057 
0058       (+) You can monitor the NAND device HAL state by calling the function
0059           HAL_NAND_GetState()
0060 
0061     [..]
0062       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
0063           If a NAND flash device contains different operations and/or implementations,
0064           it should be implemented separately.
0065 
0066     *** Callback registration ***
0067     =============================================
0068     [..]
0069       The compilation define  USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
0070       allows the user to configure dynamically the driver callbacks.
0071 
0072       Use Functions HAL_NAND_RegisterCallback() to register a user callback,
0073       it allows to register following callbacks:
0074         (+) MspInitCallback    : NAND MspInit.
0075         (+) MspDeInitCallback  : NAND MspDeInit.
0076       This function takes as parameters the HAL peripheral handle, the Callback ID
0077       and a pointer to the user callback function.
0078 
0079       Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default
0080       weak (overridden) function. It allows to reset following callbacks:
0081         (+) MspInitCallback    : NAND MspInit.
0082         (+) MspDeInitCallback  : NAND MspDeInit.
0083       This function) takes as parameters the HAL peripheral handle and the Callback ID.
0084 
0085       By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
0086       all callbacks are reset to the corresponding legacy weak (overridden) functions.
0087       Exception done for MspInit and MspDeInit callbacks that are respectively
0088       reset to the legacy weak (overridden) functions in the HAL_NAND_Init
0089       and  HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
0090       If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit
0091       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0092 
0093       Callbacks can be registered/unregistered in READY state only.
0094       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0095       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0096       during the Init/DeInit.
0097       In that case first register the MspInit/MspDeInit user callbacks
0098       using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit
0099       or HAL_NAND_Init function.
0100 
0101       When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
0102       not defined, the callback registering feature is not available
0103       and weak (overridden) callbacks are used.
0104 
0105   @endverbatim
0106   ******************************************************************************
0107   */
0108 
0109 /* Includes ------------------------------------------------------------------*/
0110 #include "stm32h7xx_hal.h"
0111 
0112 
0113 /** @addtogroup STM32H7xx_HAL_Driver
0114   * @{
0115   */
0116 
0117 #ifdef HAL_NAND_MODULE_ENABLED
0118 
0119 /** @defgroup NAND NAND
0120   * @ingroup RTEMSBSPsARMSTM32H7
0121   * @brief NAND HAL module driver
0122   * @{
0123   */
0124 
0125 /* Private typedef -----------------------------------------------------------*/
0126 /* Private Constants ------------------------------------------------------------*/
0127 /* Private macro -------------------------------------------------------------*/
0128 /* Private variables ---------------------------------------------------------*/
0129 /* Private function prototypes -----------------------------------------------*/
0130 /* Exported functions ---------------------------------------------------------*/
0131 
0132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
0133   * @ingroup RTEMSBSPsARMSTM32H7
0134   * @{
0135   */
0136 
0137 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
0138   * @ingroup RTEMSBSPsARMSTM32H7
0139   * @brief    Initialization and Configuration functions
0140   *
0141   @verbatim
0142   ==============================================================================
0143             ##### NAND Initialization and de-initialization functions #####
0144   ==============================================================================
0145   [..]
0146     This section provides functions allowing to initialize/de-initialize
0147     the NAND memory
0148 
0149 @endverbatim
0150   * @{
0151   */
0152 
0153 /**
0154   * @brief  Perform NAND memory Initialization sequence
0155   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0156   *                the configuration information for NAND module.
0157   * @param  ComSpace_Timing pointer to Common space timing structure
0158   * @param  AttSpace_Timing pointer to Attribute space timing structure
0159   * @retval HAL status
0160   */
0161 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
0162                                  FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
0163 {
0164   /* Check the NAND handle state */
0165   if (hnand == NULL)
0166   {
0167     return HAL_ERROR;
0168   }
0169 
0170   if (hnand->State == HAL_NAND_STATE_RESET)
0171   {
0172     /* Allocate lock resource and initialize it */
0173     hnand->Lock = HAL_UNLOCKED;
0174 
0175 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0176     if (hnand->MspInitCallback == NULL)
0177     {
0178       hnand->MspInitCallback = HAL_NAND_MspInit;
0179     }
0180     hnand->ItCallback = HAL_NAND_ITCallback;
0181 
0182     /* Init the low level hardware */
0183     hnand->MspInitCallback(hnand);
0184 #else
0185     /* Initialize the low level hardware (MSP) */
0186     HAL_NAND_MspInit(hnand);
0187 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0188   }
0189 
0190   /* Initialize NAND control Interface */
0191   (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
0192 
0193   /* Initialize NAND common space timing Interface */
0194   (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
0195 
0196   /* Initialize NAND attribute space timing Interface */
0197   (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
0198 
0199   /* Enable the NAND device */
0200   __FMC_NAND_ENABLE(hnand->Instance);
0201 
0202   /* Enable FMC Peripheral */
0203   __FMC_ENABLE();
0204   /* Update the NAND controller state */
0205   hnand->State = HAL_NAND_STATE_READY;
0206 
0207   return HAL_OK;
0208 }
0209 
0210 /**
0211   * @brief  Perform NAND memory De-Initialization sequence
0212   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0213   *                the configuration information for NAND module.
0214   * @retval HAL status
0215   */
0216 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
0217 {
0218 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0219   if (hnand->MspDeInitCallback == NULL)
0220   {
0221     hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
0222   }
0223 
0224   /* DeInit the low level hardware */
0225   hnand->MspDeInitCallback(hnand);
0226 #else
0227   /* Initialize the low level hardware (MSP) */
0228   HAL_NAND_MspDeInit(hnand);
0229 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0230 
0231   /* Configure the NAND registers with their reset values */
0232   (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
0233 
0234   /* Reset the NAND controller state */
0235   hnand->State = HAL_NAND_STATE_RESET;
0236 
0237   /* Release Lock */
0238   __HAL_UNLOCK(hnand);
0239 
0240   return HAL_OK;
0241 }
0242 
0243 /**
0244   * @brief  NAND MSP Init
0245   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0246   *                the configuration information for NAND module.
0247   * @retval None
0248   */
0249 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
0250 {
0251   /* Prevent unused argument(s) compilation warning */
0252   UNUSED(hnand);
0253 
0254   /* NOTE : This function Should not be modified, when the callback is needed,
0255             the HAL_NAND_MspInit could be implemented in the user file
0256    */
0257 }
0258 
0259 /**
0260   * @brief  NAND MSP DeInit
0261   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0262   *                the configuration information for NAND module.
0263   * @retval None
0264   */
0265 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
0266 {
0267   /* Prevent unused argument(s) compilation warning */
0268   UNUSED(hnand);
0269 
0270   /* NOTE : This function Should not be modified, when the callback is needed,
0271             the HAL_NAND_MspDeInit could be implemented in the user file
0272    */
0273 }
0274 
0275 
0276 /**
0277   * @brief  This function handles NAND device interrupt request.
0278   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0279   *                the configuration information for NAND module.
0280   * @retval HAL status
0281   */
0282 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
0283 {
0284   /* Check NAND interrupt Rising edge flag */
0285   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
0286   {
0287     /* NAND interrupt callback*/
0288 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0289     hnand->ItCallback(hnand);
0290 #else
0291     HAL_NAND_ITCallback(hnand);
0292 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0293 
0294     /* Clear NAND interrupt Rising edge pending bit */
0295     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
0296   }
0297 
0298   /* Check NAND interrupt Level flag */
0299   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
0300   {
0301     /* NAND interrupt callback*/
0302 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0303     hnand->ItCallback(hnand);
0304 #else
0305     HAL_NAND_ITCallback(hnand);
0306 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0307 
0308     /* Clear NAND interrupt Level pending bit */
0309     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
0310   }
0311 
0312   /* Check NAND interrupt Falling edge flag */
0313   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
0314   {
0315     /* NAND interrupt callback*/
0316 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0317     hnand->ItCallback(hnand);
0318 #else
0319     HAL_NAND_ITCallback(hnand);
0320 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0321 
0322     /* Clear NAND interrupt Falling edge pending bit */
0323     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
0324   }
0325 
0326   /* Check NAND interrupt FIFO empty flag */
0327   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
0328   {
0329     /* NAND interrupt callback*/
0330 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
0331     hnand->ItCallback(hnand);
0332 #else
0333     HAL_NAND_ITCallback(hnand);
0334 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
0335 
0336     /* Clear NAND interrupt FIFO empty pending bit */
0337     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
0338   }
0339 
0340 }
0341 
0342 /**
0343   * @brief  NAND interrupt feature callback
0344   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0345   *                the configuration information for NAND module.
0346   * @retval None
0347   */
0348 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
0349 {
0350   /* Prevent unused argument(s) compilation warning */
0351   UNUSED(hnand);
0352 
0353   /* NOTE : This function Should not be modified, when the callback is needed,
0354             the HAL_NAND_ITCallback could be implemented in the user file
0355    */
0356 }
0357 
0358 /**
0359   * @}
0360   */
0361 
0362 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
0363   * @ingroup RTEMSBSPsARMSTM32H7
0364   * @brief    Input Output and memory control functions
0365   *
0366   @verbatim
0367   ==============================================================================
0368                     ##### NAND Input and Output functions #####
0369   ==============================================================================
0370   [..]
0371     This section provides functions allowing to use and control the NAND
0372     memory
0373 
0374 @endverbatim
0375   * @{
0376   */
0377 
0378 /**
0379   * @brief  Read the NAND memory electronic signature
0380   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0381   *                the configuration information for NAND module.
0382   * @param  pNAND_ID NAND ID structure
0383   * @retval HAL status
0384   */
0385 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
0386 {
0387   __IO uint32_t data = 0;
0388   __IO uint32_t data1 = 0;
0389   uint32_t deviceaddress;
0390 
0391   /* Check the NAND controller state */
0392   if (hnand->State == HAL_NAND_STATE_BUSY)
0393   {
0394     return HAL_BUSY;
0395   }
0396   else if (hnand->State == HAL_NAND_STATE_READY)
0397   {
0398     /* Process Locked */
0399     __HAL_LOCK(hnand);
0400 
0401     /* Update the NAND controller state */
0402     hnand->State = HAL_NAND_STATE_BUSY;
0403 
0404     /* Identify the device address */
0405     deviceaddress = NAND_DEVICE;
0406 
0407     /* Send Read ID command sequence */
0408     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
0409     __DSB();
0410     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
0411     __DSB();
0412 
0413     /* Read the electronic signature from NAND flash */
0414     if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
0415     {
0416       data = *(__IO uint32_t *)deviceaddress;
0417 
0418       /* Return the data read */
0419       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
0420       pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
0421       pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
0422       pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
0423     }
0424     else
0425     {
0426       data = *(__IO uint32_t *)deviceaddress;
0427       data1 = *((__IO uint32_t *)deviceaddress + 4);
0428 
0429       /* Return the data read */
0430       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
0431       pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
0432       pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
0433       pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
0434     }
0435 
0436     /* Update the NAND controller state */
0437     hnand->State = HAL_NAND_STATE_READY;
0438 
0439     /* Process unlocked */
0440     __HAL_UNLOCK(hnand);
0441   }
0442   else
0443   {
0444     return HAL_ERROR;
0445   }
0446 
0447   return HAL_OK;
0448 }
0449 
0450 /**
0451   * @brief  NAND memory reset
0452   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0453   *                the configuration information for NAND module.
0454   * @retval HAL status
0455   */
0456 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
0457 {
0458   uint32_t deviceaddress;
0459 
0460   /* Check the NAND controller state */
0461   if (hnand->State == HAL_NAND_STATE_BUSY)
0462   {
0463     return HAL_BUSY;
0464   }
0465   else if (hnand->State == HAL_NAND_STATE_READY)
0466   {
0467     /* Process Locked */
0468     __HAL_LOCK(hnand);
0469 
0470     /* Update the NAND controller state */
0471     hnand->State = HAL_NAND_STATE_BUSY;
0472 
0473     /* Identify the device address */
0474     deviceaddress = NAND_DEVICE;
0475 
0476     /* Send NAND reset command */
0477     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
0478 
0479     /* Update the NAND controller state */
0480     hnand->State = HAL_NAND_STATE_READY;
0481 
0482     /* Process unlocked */
0483     __HAL_UNLOCK(hnand);
0484   }
0485   else
0486   {
0487     return HAL_ERROR;
0488   }
0489 
0490   return HAL_OK;
0491 
0492 }
0493 
0494 /**
0495   * @brief  Configure the device: Enter the physical parameters of the device
0496   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0497   *                the configuration information for NAND module.
0498   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
0499   * @retval HAL status
0500   */
0501 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
0502 {
0503   hnand->Config.PageSize           = pDeviceConfig->PageSize;
0504   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
0505   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
0506   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
0507   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
0508   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
0509   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
0510 
0511   return HAL_OK;
0512 }
0513 
0514 /**
0515   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
0516   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0517   *                the configuration information for NAND module.
0518   * @param  pAddress  pointer to NAND address structure
0519   * @param  pBuffer  pointer to destination read buffer
0520   * @param  NumPageToRead  number of pages to read from block
0521   * @retval HAL status
0522   */
0523 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
0524                                         uint8_t *pBuffer, uint32_t NumPageToRead)
0525 {
0526   uint32_t index;
0527   uint32_t tickstart;
0528   uint32_t deviceaddress;
0529   uint32_t numpagesread = 0U;
0530   uint32_t nandaddress;
0531   uint32_t nbpages = NumPageToRead;
0532   uint8_t *buff = pBuffer;
0533 
0534   /* Check the NAND controller state */
0535   if (hnand->State == HAL_NAND_STATE_BUSY)
0536   {
0537     return HAL_BUSY;
0538   }
0539   else if (hnand->State == HAL_NAND_STATE_READY)
0540   {
0541     /* Process Locked */
0542     __HAL_LOCK(hnand);
0543 
0544     /* Update the NAND controller state */
0545     hnand->State = HAL_NAND_STATE_BUSY;
0546 
0547     /* Identify the device address */
0548     deviceaddress = NAND_DEVICE;
0549 
0550     /* NAND raw address calculation */
0551     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
0552 
0553     /* Page(s) read loop */
0554     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
0555     {
0556       /* Send read page command sequence */
0557       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
0558       __DSB();
0559 
0560       /* Cards with page size <= 512 bytes */
0561       if ((hnand->Config.PageSize) <= 512U)
0562       {
0563         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0564         {
0565           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0566           __DSB();
0567           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0568           __DSB();
0569           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0570           __DSB();
0571         }
0572         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0573         {
0574           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0575           __DSB();
0576           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0577           __DSB();
0578           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0579           __DSB();
0580           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0581           __DSB();
0582         }
0583       }
0584       else /* (hnand->Config.PageSize) > 512 */
0585       {
0586         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0587         {
0588           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0589           __DSB();
0590           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0591           __DSB();
0592           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0593           __DSB();
0594           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0595           __DSB();
0596         }
0597         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0598         {
0599           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0600           __DSB();
0601           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0602           __DSB();
0603           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0604           __DSB();
0605           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0606           __DSB();
0607           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0608           __DSB();
0609         }
0610       }
0611 
0612       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
0613       __DSB();
0614 
0615 
0616       if (hnand->Config.ExtraCommandEnable == ENABLE)
0617       {
0618         /* Get tick */
0619         tickstart = HAL_GetTick();
0620 
0621         /* Read status until NAND is ready */
0622         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
0623         {
0624           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
0625           {
0626             /* Update the NAND controller state */
0627             hnand->State = HAL_NAND_STATE_ERROR;
0628 
0629             /* Process unlocked */
0630             __HAL_UNLOCK(hnand);
0631 
0632             return HAL_TIMEOUT;
0633           }
0634         }
0635 
0636         /* Go back to read mode */
0637         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
0638         __DSB();
0639       }
0640 
0641       /* Get Data into Buffer */
0642       for (index = 0U; index < hnand->Config.PageSize; index++)
0643       {
0644         *buff = *(uint8_t *)deviceaddress;
0645         buff++;
0646       }
0647 
0648       /* Increment read pages number */
0649       numpagesread++;
0650 
0651       /* Decrement pages to read */
0652       nbpages--;
0653 
0654       /* Increment the NAND address */
0655       nandaddress = (uint32_t)(nandaddress + 1U);
0656     }
0657 
0658     /* Update the NAND controller state */
0659     hnand->State = HAL_NAND_STATE_READY;
0660 
0661     /* Process unlocked */
0662     __HAL_UNLOCK(hnand);
0663   }
0664   else
0665   {
0666     return HAL_ERROR;
0667   }
0668 
0669   return HAL_OK;
0670 }
0671 
0672 /**
0673   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
0674   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0675   *                the configuration information for NAND module.
0676   * @param  pAddress  pointer to NAND address structure
0677   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
0678   * @param  NumPageToRead  number of pages to read from block
0679   * @retval HAL status
0680   */
0681 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
0682                                          uint16_t *pBuffer, uint32_t NumPageToRead)
0683 {
0684   uint32_t index;
0685   uint32_t tickstart;
0686   uint32_t deviceaddress;
0687   uint32_t numpagesread = 0U;
0688   uint32_t nandaddress;
0689   uint32_t nbpages = NumPageToRead;
0690   uint16_t *buff = pBuffer;
0691 
0692   /* Check the NAND controller state */
0693   if (hnand->State == HAL_NAND_STATE_BUSY)
0694   {
0695     return HAL_BUSY;
0696   }
0697   else if (hnand->State == HAL_NAND_STATE_READY)
0698   {
0699     /* Process Locked */
0700     __HAL_LOCK(hnand);
0701 
0702     /* Update the NAND controller state */
0703     hnand->State = HAL_NAND_STATE_BUSY;
0704 
0705     /* Identify the device address */
0706     deviceaddress = NAND_DEVICE;
0707 
0708     /* NAND raw address calculation */
0709     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
0710 
0711     /* Page(s) read loop */
0712     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
0713     {
0714       /* Send read page command sequence */
0715       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
0716       __DSB();
0717 
0718       /* Cards with page size <= 512 bytes */
0719       if ((hnand->Config.PageSize) <= 512U)
0720       {
0721         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0722         {
0723           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0724           __DSB();
0725           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0726           __DSB();
0727           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0728           __DSB();
0729         }
0730         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0731         {
0732           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0733           __DSB();
0734           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0735           __DSB();
0736           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0737           __DSB();
0738           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0739           __DSB();
0740         }
0741       }
0742       else /* (hnand->Config.PageSize) > 512 */
0743       {
0744         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0745         {
0746           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0747           __DSB();
0748           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0749           __DSB();
0750           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0751           __DSB();
0752           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0753           __DSB();
0754         }
0755         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0756         {
0757           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0758           __DSB();
0759           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0760           __DSB();
0761           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0762           __DSB();
0763           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0764           __DSB();
0765           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0766           __DSB();
0767         }
0768       }
0769 
0770       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
0771       __DSB();
0772 
0773       if (hnand->Config.ExtraCommandEnable == ENABLE)
0774       {
0775         /* Get tick */
0776         tickstart = HAL_GetTick();
0777 
0778         /* Read status until NAND is ready */
0779         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
0780         {
0781           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
0782           {
0783             /* Update the NAND controller state */
0784             hnand->State = HAL_NAND_STATE_ERROR;
0785 
0786             /* Process unlocked */
0787             __HAL_UNLOCK(hnand);
0788 
0789             return HAL_TIMEOUT;
0790           }
0791         }
0792 
0793         /* Go back to read mode */
0794         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
0795         __DSB();
0796       }
0797 
0798       /* Calculate PageSize */
0799       if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
0800       {
0801         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
0802       }
0803       else
0804       {
0805         /* Do nothing */
0806         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
0807       }
0808 
0809       /* Get Data into Buffer */
0810       for (index = 0U; index < hnand->Config.PageSize; index++)
0811       {
0812         *buff = *(uint16_t *)deviceaddress;
0813         buff++;
0814       }
0815 
0816       /* Increment read pages number */
0817       numpagesread++;
0818 
0819       /* Decrement pages to read */
0820       nbpages--;
0821 
0822       /* Increment the NAND address */
0823       nandaddress = (uint32_t)(nandaddress + 1U);
0824     }
0825 
0826     /* Update the NAND controller state */
0827     hnand->State = HAL_NAND_STATE_READY;
0828 
0829     /* Process unlocked */
0830     __HAL_UNLOCK(hnand);
0831   }
0832   else
0833   {
0834     return HAL_ERROR;
0835   }
0836 
0837   return HAL_OK;
0838 }
0839 
0840 /**
0841   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
0842   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0843   *                the configuration information for NAND module.
0844   * @param  pAddress  pointer to NAND address structure
0845   * @param  pBuffer  pointer to source buffer to write
0846   * @param  NumPageToWrite   number of pages to write to block
0847   * @retval HAL status
0848   */
0849 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
0850                                          const uint8_t *pBuffer, uint32_t NumPageToWrite)
0851 {
0852   uint32_t index;
0853   uint32_t tickstart;
0854   uint32_t deviceaddress;
0855   uint32_t numpageswritten = 0U;
0856   uint32_t nandaddress;
0857   uint32_t nbpages = NumPageToWrite;
0858   const uint8_t *buff = pBuffer;
0859 
0860   /* Check the NAND controller state */
0861   if (hnand->State == HAL_NAND_STATE_BUSY)
0862   {
0863     return HAL_BUSY;
0864   }
0865   else if (hnand->State == HAL_NAND_STATE_READY)
0866   {
0867     /* Process Locked */
0868     __HAL_LOCK(hnand);
0869 
0870     /* Update the NAND controller state */
0871     hnand->State = HAL_NAND_STATE_BUSY;
0872 
0873     /* Identify the device address */
0874     deviceaddress = NAND_DEVICE;
0875 
0876     /* NAND raw address calculation */
0877     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
0878 
0879     /* Page(s) write loop */
0880     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
0881     {
0882       /* Send write page command sequence */
0883       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
0884       __DSB();
0885       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
0886       __DSB();
0887 
0888       /* Cards with page size <= 512 bytes */
0889       if ((hnand->Config.PageSize) <= 512U)
0890       {
0891         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0892         {
0893           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0894           __DSB();
0895           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0896           __DSB();
0897           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0898           __DSB();
0899         }
0900         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0901         {
0902           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0903           __DSB();
0904           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0905           __DSB();
0906           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0907           __DSB();
0908           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0909           __DSB();
0910         }
0911       }
0912       else /* (hnand->Config.PageSize) > 512 */
0913       {
0914         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
0915         {
0916           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0917           __DSB();
0918           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0919           __DSB();
0920           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0921           __DSB();
0922           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0923           __DSB();
0924         }
0925         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
0926         {
0927           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0928           __DSB();
0929           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
0930           __DSB();
0931           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
0932           __DSB();
0933           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
0934           __DSB();
0935           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
0936           __DSB();
0937         }
0938       }
0939 
0940       /* Write data to memory */
0941       for (index = 0U; index < hnand->Config.PageSize; index++)
0942       {
0943         *(__IO uint8_t *)deviceaddress = *buff;
0944         buff++;
0945         __DSB();
0946       }
0947 
0948       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
0949       __DSB();
0950 
0951       /* Get tick */
0952       tickstart = HAL_GetTick();
0953 
0954       /* Read status until NAND is ready */
0955       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
0956       {
0957         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
0958         {
0959           /* Update the NAND controller state */
0960           hnand->State = HAL_NAND_STATE_ERROR;
0961 
0962           /* Process unlocked */
0963           __HAL_UNLOCK(hnand);
0964 
0965           return HAL_TIMEOUT;
0966         }
0967       }
0968 
0969       /* Increment written pages number */
0970       numpageswritten++;
0971 
0972       /* Decrement pages to write */
0973       nbpages--;
0974 
0975       /* Increment the NAND address */
0976       nandaddress = (uint32_t)(nandaddress + 1U);
0977     }
0978 
0979     /* Update the NAND controller state */
0980     hnand->State = HAL_NAND_STATE_READY;
0981 
0982     /* Process unlocked */
0983     __HAL_UNLOCK(hnand);
0984   }
0985   else
0986   {
0987     return HAL_ERROR;
0988   }
0989 
0990   return HAL_OK;
0991 }
0992 
0993 /**
0994   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
0995   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
0996   *                the configuration information for NAND module.
0997   * @param  pAddress  pointer to NAND address structure
0998   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
0999   * @param  NumPageToWrite   number of pages to write to block
1000   * @retval HAL status
1001   */
1002 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
1003                                           const uint16_t *pBuffer, uint32_t NumPageToWrite)
1004 {
1005   uint32_t index;
1006   uint32_t tickstart;
1007   uint32_t deviceaddress;
1008   uint32_t numpageswritten = 0U;
1009   uint32_t nandaddress;
1010   uint32_t nbpages = NumPageToWrite;
1011   const uint16_t *buff = pBuffer;
1012 
1013   /* Check the NAND controller state */
1014   if (hnand->State == HAL_NAND_STATE_BUSY)
1015   {
1016     return HAL_BUSY;
1017   }
1018   else if (hnand->State == HAL_NAND_STATE_READY)
1019   {
1020     /* Process Locked */
1021     __HAL_LOCK(hnand);
1022 
1023     /* Update the NAND controller state */
1024     hnand->State = HAL_NAND_STATE_BUSY;
1025 
1026     /* Identify the device address */
1027     deviceaddress = NAND_DEVICE;
1028 
1029     /* NAND raw address calculation */
1030     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1031 
1032     /* Page(s) write loop */
1033     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1034     {
1035       /* Send write page command sequence */
1036       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1037       __DSB();
1038       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1039       __DSB();
1040 
1041       /* Cards with page size <= 512 bytes */
1042       if ((hnand->Config.PageSize) <= 512U)
1043       {
1044         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1045         {
1046           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1047           __DSB();
1048           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1049           __DSB();
1050           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1051           __DSB();
1052         }
1053         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1054         {
1055           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1056           __DSB();
1057           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1058           __DSB();
1059           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1060           __DSB();
1061           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1062           __DSB();
1063         }
1064       }
1065       else /* (hnand->Config.PageSize) > 512 */
1066       {
1067         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1068         {
1069           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1070           __DSB();
1071           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1072           __DSB();
1073           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1074           __DSB();
1075           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1076           __DSB();
1077         }
1078         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1079         {
1080           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1081           __DSB();
1082           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1083           __DSB();
1084           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1085           __DSB();
1086           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1087           __DSB();
1088           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1089           __DSB();
1090         }
1091       }
1092 
1093       /* Calculate PageSize */
1094       if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
1095       {
1096         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
1097       }
1098       else
1099       {
1100         /* Do nothing */
1101         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
1102       }
1103 
1104       /* Write data to memory */
1105       for (index = 0U; index < hnand->Config.PageSize; index++)
1106       {
1107         *(__IO uint16_t *)deviceaddress = *buff;
1108         buff++;
1109         __DSB();
1110       }
1111 
1112       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1113       __DSB();
1114 
1115       /* Get tick */
1116       tickstart = HAL_GetTick();
1117 
1118       /* Read status until NAND is ready */
1119       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1120       {
1121         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1122         {
1123           /* Update the NAND controller state */
1124           hnand->State = HAL_NAND_STATE_ERROR;
1125 
1126           /* Process unlocked */
1127           __HAL_UNLOCK(hnand);
1128 
1129           return HAL_TIMEOUT;
1130         }
1131       }
1132 
1133       /* Increment written pages number */
1134       numpageswritten++;
1135 
1136       /* Decrement pages to write */
1137       nbpages--;
1138 
1139       /* Increment the NAND address */
1140       nandaddress = (uint32_t)(nandaddress + 1U);
1141     }
1142 
1143     /* Update the NAND controller state */
1144     hnand->State = HAL_NAND_STATE_READY;
1145 
1146     /* Process unlocked */
1147     __HAL_UNLOCK(hnand);
1148   }
1149   else
1150   {
1151     return HAL_ERROR;
1152   }
1153 
1154   return HAL_OK;
1155 }
1156 
1157 /**
1158   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
1159   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1160   *                the configuration information for NAND module.
1161   * @param  pAddress  pointer to NAND address structure
1162   * @param  pBuffer pointer to source buffer to write
1163   * @param  NumSpareAreaToRead Number of spare area to read
1164   * @retval HAL status
1165   */
1166 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
1167                                              uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1168 {
1169   uint32_t index;
1170   uint32_t tickstart;
1171   uint32_t deviceaddress;
1172   uint32_t numsparearearead = 0U;
1173   uint32_t nandaddress;
1174   uint32_t columnaddress;
1175   uint32_t nbspare = NumSpareAreaToRead;
1176   uint8_t *buff = pBuffer;
1177 
1178   /* Check the NAND controller state */
1179   if (hnand->State == HAL_NAND_STATE_BUSY)
1180   {
1181     return HAL_BUSY;
1182   }
1183   else if (hnand->State == HAL_NAND_STATE_READY)
1184   {
1185     /* Process Locked */
1186     __HAL_LOCK(hnand);
1187 
1188     /* Update the NAND controller state */
1189     hnand->State = HAL_NAND_STATE_BUSY;
1190 
1191     /* Identify the device address */
1192     deviceaddress = NAND_DEVICE;
1193 
1194     /* NAND raw address calculation */
1195     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1196 
1197     /* Column in page address */
1198     columnaddress = COLUMN_ADDRESS(hnand);
1199 
1200     /* Spare area(s) read loop */
1201     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1202     {
1203       /* Cards with page size <= 512 bytes */
1204       if ((hnand->Config.PageSize) <= 512U)
1205       {
1206         /* Send read spare area command sequence */
1207         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1208         __DSB();
1209 
1210         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1211         {
1212           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1213           __DSB();
1214           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1215           __DSB();
1216           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1217           __DSB();
1218         }
1219         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1220         {
1221           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1222           __DSB();
1223           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1224           __DSB();
1225           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1226           __DSB();
1227           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1228           __DSB();
1229         }
1230       }
1231       else /* (hnand->Config.PageSize) > 512 */
1232       {
1233         /* Send read spare area command sequence */
1234         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1235         __DSB();
1236 
1237         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1238         {
1239           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1240           __DSB();
1241           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1242           __DSB();
1243           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1244           __DSB();
1245           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1246           __DSB();
1247         }
1248         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1249         {
1250           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1251           __DSB();
1252           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1253           __DSB();
1254           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1255           __DSB();
1256           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1257           __DSB();
1258           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1259           __DSB();
1260         }
1261       }
1262 
1263       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1264       __DSB();
1265 
1266       if (hnand->Config.ExtraCommandEnable == ENABLE)
1267       {
1268         /* Get tick */
1269         tickstart = HAL_GetTick();
1270 
1271         /* Read status until NAND is ready */
1272         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1273         {
1274           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1275           {
1276             /* Update the NAND controller state */
1277             hnand->State = HAL_NAND_STATE_ERROR;
1278 
1279             /* Process unlocked */
1280             __HAL_UNLOCK(hnand);
1281 
1282             return HAL_TIMEOUT;
1283           }
1284         }
1285 
1286         /* Go back to read mode */
1287         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1288         __DSB();
1289       }
1290 
1291       /* Get Data into Buffer */
1292       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1293       {
1294         *buff = *(uint8_t *)deviceaddress;
1295         buff++;
1296       }
1297 
1298       /* Increment read spare areas number */
1299       numsparearearead++;
1300 
1301       /* Decrement spare areas to read */
1302       nbspare--;
1303 
1304       /* Increment the NAND address */
1305       nandaddress = (uint32_t)(nandaddress + 1U);
1306     }
1307 
1308     /* Update the NAND controller state */
1309     hnand->State = HAL_NAND_STATE_READY;
1310 
1311     /* Process unlocked */
1312     __HAL_UNLOCK(hnand);
1313   }
1314   else
1315   {
1316     return HAL_ERROR;
1317   }
1318 
1319   return HAL_OK;
1320 }
1321 
1322 /**
1323   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
1324   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1325   *                the configuration information for NAND module.
1326   * @param  pAddress  pointer to NAND address structure
1327   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1328   * @param  NumSpareAreaToRead Number of spare area to read
1329   * @retval HAL status
1330   */
1331 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
1332                                               uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1333 {
1334   uint32_t index;
1335   uint32_t tickstart;
1336   uint32_t deviceaddress;
1337   uint32_t numsparearearead = 0U;
1338   uint32_t nandaddress;
1339   uint32_t columnaddress;
1340   uint32_t nbspare = NumSpareAreaToRead;
1341   uint16_t *buff = pBuffer;
1342 
1343   /* Check the NAND controller state */
1344   if (hnand->State == HAL_NAND_STATE_BUSY)
1345   {
1346     return HAL_BUSY;
1347   }
1348   else if (hnand->State == HAL_NAND_STATE_READY)
1349   {
1350     /* Process Locked */
1351     __HAL_LOCK(hnand);
1352 
1353     /* Update the NAND controller state */
1354     hnand->State = HAL_NAND_STATE_BUSY;
1355 
1356     /* Identify the device address */
1357     deviceaddress = NAND_DEVICE;
1358 
1359     /* NAND raw address calculation */
1360     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1361 
1362     /* Column in page address */
1363     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1364 
1365     /* Spare area(s) read loop */
1366     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1367     {
1368       /* Cards with page size <= 512 bytes */
1369       if ((hnand->Config.PageSize) <= 512U)
1370       {
1371         /* Send read spare area command sequence */
1372         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1373         __DSB();
1374 
1375         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1376         {
1377           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1378           __DSB();
1379           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1380           __DSB();
1381           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1382           __DSB();
1383         }
1384         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1385         {
1386           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1387           __DSB();
1388           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1389           __DSB();
1390           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1391           __DSB();
1392           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1393           __DSB();
1394         }
1395       }
1396       else /* (hnand->Config.PageSize) > 512 */
1397       {
1398         /* Send read spare area command sequence */
1399         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1400         __DSB();
1401 
1402         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1403         {
1404           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1405           __DSB();
1406           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1407           __DSB();
1408           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1409           __DSB();
1410           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1411           __DSB();
1412         }
1413         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1414         {
1415           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1416           __DSB();
1417           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1418           __DSB();
1419           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1420           __DSB();
1421           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1422           __DSB();
1423           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1424           __DSB();
1425         }
1426       }
1427 
1428       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1429       __DSB();
1430 
1431       if (hnand->Config.ExtraCommandEnable == ENABLE)
1432       {
1433         /* Get tick */
1434         tickstart = HAL_GetTick();
1435 
1436         /* Read status until NAND is ready */
1437         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1438         {
1439           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1440           {
1441             /* Update the NAND controller state */
1442             hnand->State = HAL_NAND_STATE_ERROR;
1443 
1444             /* Process unlocked */
1445             __HAL_UNLOCK(hnand);
1446 
1447             return HAL_TIMEOUT;
1448           }
1449         }
1450 
1451         /* Go back to read mode */
1452         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1453         __DSB();
1454       }
1455 
1456       /* Get Data into Buffer */
1457       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1458       {
1459         *buff = *(uint16_t *)deviceaddress;
1460         buff++;
1461       }
1462 
1463       /* Increment read spare areas number */
1464       numsparearearead++;
1465 
1466       /* Decrement spare areas to read */
1467       nbspare--;
1468 
1469       /* Increment the NAND address */
1470       nandaddress = (uint32_t)(nandaddress + 1U);
1471     }
1472 
1473     /* Update the NAND controller state */
1474     hnand->State = HAL_NAND_STATE_READY;
1475 
1476     /* Process unlocked */
1477     __HAL_UNLOCK(hnand);
1478   }
1479   else
1480   {
1481     return HAL_ERROR;
1482   }
1483 
1484   return HAL_OK;
1485 }
1486 
1487 /**
1488   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
1489   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1490   *                the configuration information for NAND module.
1491   * @param  pAddress  pointer to NAND address structure
1492   * @param  pBuffer  pointer to source buffer to write
1493   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1494   * @retval HAL status
1495   */
1496 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
1497                                               const uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1498 {
1499   uint32_t index;
1500   uint32_t tickstart;
1501   uint32_t deviceaddress;
1502   uint32_t numspareareawritten = 0U;
1503   uint32_t nandaddress;
1504   uint32_t columnaddress;
1505   uint32_t nbspare = NumSpareAreaTowrite;
1506   const uint8_t *buff = pBuffer;
1507 
1508   /* Check the NAND controller state */
1509   if (hnand->State == HAL_NAND_STATE_BUSY)
1510   {
1511     return HAL_BUSY;
1512   }
1513   else if (hnand->State == HAL_NAND_STATE_READY)
1514   {
1515     /* Process Locked */
1516     __HAL_LOCK(hnand);
1517 
1518     /* Update the NAND controller state */
1519     hnand->State = HAL_NAND_STATE_BUSY;
1520 
1521     /* Identify the device address */
1522     deviceaddress = NAND_DEVICE;
1523 
1524     /* Page address calculation */
1525     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1526 
1527     /* Column in page address */
1528     columnaddress = COLUMN_ADDRESS(hnand);
1529 
1530     /* Spare area(s) write loop */
1531     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1532     {
1533       /* Cards with page size <= 512 bytes */
1534       if ((hnand->Config.PageSize) <= 512U)
1535       {
1536         /* Send write Spare area command sequence */
1537         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1538         __DSB();
1539         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1540         __DSB();
1541 
1542         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1543         {
1544           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1545           __DSB();
1546           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1547           __DSB();
1548           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1549           __DSB();
1550         }
1551         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1552         {
1553           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1554           __DSB();
1555           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1556           __DSB();
1557           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1558           __DSB();
1559           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1560           __DSB();
1561         }
1562       }
1563       else /* (hnand->Config.PageSize) > 512 */
1564       {
1565         /* Send write Spare area command sequence */
1566         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1567         __DSB();
1568         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1569         __DSB();
1570 
1571         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1572         {
1573           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1574           __DSB();
1575           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1576           __DSB();
1577           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1578           __DSB();
1579           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1580           __DSB();
1581         }
1582         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1583         {
1584           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1585           __DSB();
1586           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1587           __DSB();
1588           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1589           __DSB();
1590           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1591           __DSB();
1592           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1593           __DSB();
1594         }
1595       }
1596 
1597       /* Write data to memory */
1598       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1599       {
1600         *(__IO uint8_t *)deviceaddress = *buff;
1601         buff++;
1602         __DSB();
1603       }
1604 
1605       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1606       __DSB();
1607 
1608       /* Get tick */
1609       tickstart = HAL_GetTick();
1610 
1611       /* Read status until NAND is ready */
1612       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1613       {
1614         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1615         {
1616           /* Update the NAND controller state */
1617           hnand->State = HAL_NAND_STATE_ERROR;
1618 
1619           /* Process unlocked */
1620           __HAL_UNLOCK(hnand);
1621 
1622           return HAL_TIMEOUT;
1623         }
1624       }
1625 
1626       /* Increment written spare areas number */
1627       numspareareawritten++;
1628 
1629       /* Decrement spare areas to write */
1630       nbspare--;
1631 
1632       /* Increment the NAND address */
1633       nandaddress = (uint32_t)(nandaddress + 1U);
1634     }
1635 
1636     /* Update the NAND controller state */
1637     hnand->State = HAL_NAND_STATE_READY;
1638 
1639     /* Process unlocked */
1640     __HAL_UNLOCK(hnand);
1641   }
1642   else
1643   {
1644     return HAL_ERROR;
1645   }
1646 
1647   return HAL_OK;
1648 }
1649 
1650 /**
1651   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
1652   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1653   *                the configuration information for NAND module.
1654   * @param  pAddress  pointer to NAND address structure
1655   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
1656   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1657   * @retval HAL status
1658   */
1659 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress,
1660                                                const uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1661 {
1662   uint32_t index;
1663   uint32_t tickstart;
1664   uint32_t deviceaddress;
1665   uint32_t numspareareawritten = 0U;
1666   uint32_t nandaddress;
1667   uint32_t columnaddress;
1668   uint32_t nbspare = NumSpareAreaTowrite;
1669   const uint16_t *buff = pBuffer;
1670 
1671   /* Check the NAND controller state */
1672   if (hnand->State == HAL_NAND_STATE_BUSY)
1673   {
1674     return HAL_BUSY;
1675   }
1676   else if (hnand->State == HAL_NAND_STATE_READY)
1677   {
1678     /* Process Locked */
1679     __HAL_LOCK(hnand);
1680 
1681     /* Update the NAND controller state */
1682     hnand->State = HAL_NAND_STATE_BUSY;
1683 
1684     /* Identify the device address */
1685     deviceaddress = NAND_DEVICE;
1686 
1687     /* NAND raw address calculation */
1688     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1689 
1690     /* Column in page address */
1691     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1692 
1693     /* Spare area(s) write loop */
1694     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1695     {
1696       /* Cards with page size <= 512 bytes */
1697       if ((hnand->Config.PageSize) <= 512U)
1698       {
1699         /* Send write Spare area command sequence */
1700         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1701         __DSB();
1702         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1703         __DSB();
1704 
1705         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1706         {
1707           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1708           __DSB();
1709           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1710           __DSB();
1711           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1712           __DSB();
1713         }
1714         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1715         {
1716           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1717           __DSB();
1718           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1719           __DSB();
1720           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1721           __DSB();
1722           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1723           __DSB();
1724         }
1725       }
1726       else /* (hnand->Config.PageSize) > 512 */
1727       {
1728         /* Send write Spare area command sequence */
1729         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1730         __DSB();
1731         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1732         __DSB();
1733 
1734         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1735         {
1736           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1737           __DSB();
1738           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1739           __DSB();
1740           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1741           __DSB();
1742           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1743           __DSB();
1744         }
1745         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1746         {
1747           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1748           __DSB();
1749           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1750           __DSB();
1751           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1752           __DSB();
1753           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1754           __DSB();
1755           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1756           __DSB();
1757         }
1758       }
1759 
1760       /* Write data to memory */
1761       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1762       {
1763         *(__IO uint16_t *)deviceaddress = *buff;
1764         buff++;
1765         __DSB();
1766       }
1767 
1768       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1769       __DSB();
1770 
1771       /* Get tick */
1772       tickstart = HAL_GetTick();
1773 
1774       /* Read status until NAND is ready */
1775       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1776       {
1777         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1778         {
1779           /* Update the NAND controller state */
1780           hnand->State = HAL_NAND_STATE_ERROR;
1781 
1782           /* Process unlocked */
1783           __HAL_UNLOCK(hnand);
1784 
1785           return HAL_TIMEOUT;
1786         }
1787       }
1788 
1789       /* Increment written spare areas number */
1790       numspareareawritten++;
1791 
1792       /* Decrement spare areas to write */
1793       nbspare--;
1794 
1795       /* Increment the NAND address */
1796       nandaddress = (uint32_t)(nandaddress + 1U);
1797     }
1798 
1799     /* Update the NAND controller state */
1800     hnand->State = HAL_NAND_STATE_READY;
1801 
1802     /* Process unlocked */
1803     __HAL_UNLOCK(hnand);
1804   }
1805   else
1806   {
1807     return HAL_ERROR;
1808   }
1809 
1810   return HAL_OK;
1811 }
1812 
1813 /**
1814   * @brief  NAND memory Block erase
1815   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1816   *                the configuration information for NAND module.
1817   * @param  pAddress  pointer to NAND address structure
1818   * @retval HAL status
1819   */
1820 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress)
1821 {
1822   uint32_t deviceaddress;
1823 
1824   /* Check the NAND controller state */
1825   if (hnand->State == HAL_NAND_STATE_BUSY)
1826   {
1827     return HAL_BUSY;
1828   }
1829   else if (hnand->State == HAL_NAND_STATE_READY)
1830   {
1831     /* Process Locked */
1832     __HAL_LOCK(hnand);
1833 
1834     /* Update the NAND controller state */
1835     hnand->State = HAL_NAND_STATE_BUSY;
1836 
1837     /* Identify the device address */
1838     deviceaddress = NAND_DEVICE;
1839 
1840     /* Send Erase block command sequence */
1841     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
1842     __DSB();
1843     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1844     __DSB();
1845     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1846     __DSB();
1847     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1848     __DSB();
1849 
1850     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
1851     __DSB();
1852 
1853     /* Update the NAND controller state */
1854     hnand->State = HAL_NAND_STATE_READY;
1855 
1856     /* Process unlocked */
1857     __HAL_UNLOCK(hnand);
1858   }
1859   else
1860   {
1861     return HAL_ERROR;
1862   }
1863 
1864   return HAL_OK;
1865 }
1866 
1867 /**
1868   * @brief  Increment the NAND memory address
1869   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1870   *                the configuration information for NAND module.
1871   * @param pAddress pointer to NAND address structure
1872   * @retval The new status of the increment address operation. It can be:
1873   *           - NAND_VALID_ADDRESS: When the new address is valid address
1874   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
1875   */
1876 uint32_t HAL_NAND_Address_Inc(const NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1877 {
1878   uint32_t status = NAND_VALID_ADDRESS;
1879 
1880   /* Increment page address */
1881   pAddress->Page++;
1882 
1883   /* Check NAND address is valid */
1884   if (pAddress->Page == hnand->Config.BlockSize)
1885   {
1886     pAddress->Page = 0;
1887     pAddress->Block++;
1888 
1889     if (pAddress->Block == hnand->Config.PlaneSize)
1890     {
1891       pAddress->Block = 0;
1892       pAddress->Plane++;
1893 
1894       if (pAddress->Plane == (hnand->Config.PlaneNbr))
1895       {
1896         status = NAND_INVALID_ADDRESS;
1897       }
1898     }
1899   }
1900 
1901   return (status);
1902 }
1903 
1904 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1905 /**
1906   * @brief  Register a User NAND Callback
1907   *         To be used to override the weak predefined callback
1908   * @param hnand : NAND handle
1909   * @param CallbackId : ID of the callback to be registered
1910   *        This parameter can be one of the following values:
1911   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1912   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1913   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1914   * @param pCallback : pointer to the Callback function
1915   * @retval status
1916   */
1917 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
1918                                             pNAND_CallbackTypeDef pCallback)
1919 {
1920   HAL_StatusTypeDef status = HAL_OK;
1921 
1922   if (pCallback == NULL)
1923   {
1924     return HAL_ERROR;
1925   }
1926 
1927   if (hnand->State == HAL_NAND_STATE_READY)
1928   {
1929     switch (CallbackId)
1930     {
1931       case HAL_NAND_MSP_INIT_CB_ID :
1932         hnand->MspInitCallback = pCallback;
1933         break;
1934       case HAL_NAND_MSP_DEINIT_CB_ID :
1935         hnand->MspDeInitCallback = pCallback;
1936         break;
1937       case HAL_NAND_IT_CB_ID :
1938         hnand->ItCallback = pCallback;
1939         break;
1940       default :
1941         /* update return status */
1942         status =  HAL_ERROR;
1943         break;
1944     }
1945   }
1946   else if (hnand->State == HAL_NAND_STATE_RESET)
1947   {
1948     switch (CallbackId)
1949     {
1950       case HAL_NAND_MSP_INIT_CB_ID :
1951         hnand->MspInitCallback = pCallback;
1952         break;
1953       case HAL_NAND_MSP_DEINIT_CB_ID :
1954         hnand->MspDeInitCallback = pCallback;
1955         break;
1956       default :
1957         /* update return status */
1958         status =  HAL_ERROR;
1959         break;
1960     }
1961   }
1962   else
1963   {
1964     /* update return status */
1965     status =  HAL_ERROR;
1966   }
1967 
1968   return status;
1969 }
1970 
1971 /**
1972   * @brief  Unregister a User NAND Callback
1973   *         NAND Callback is redirected to the weak predefined callback
1974   * @param hnand : NAND handle
1975   * @param CallbackId : ID of the callback to be unregistered
1976   *        This parameter can be one of the following values:
1977   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1978   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1979   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1980   * @retval status
1981   */
1982 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1983 {
1984   HAL_StatusTypeDef status = HAL_OK;
1985 
1986   if (hnand->State == HAL_NAND_STATE_READY)
1987   {
1988     switch (CallbackId)
1989     {
1990       case HAL_NAND_MSP_INIT_CB_ID :
1991         hnand->MspInitCallback = HAL_NAND_MspInit;
1992         break;
1993       case HAL_NAND_MSP_DEINIT_CB_ID :
1994         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1995         break;
1996       case HAL_NAND_IT_CB_ID :
1997         hnand->ItCallback = HAL_NAND_ITCallback;
1998         break;
1999       default :
2000         /* update return status */
2001         status =  HAL_ERROR;
2002         break;
2003     }
2004   }
2005   else if (hnand->State == HAL_NAND_STATE_RESET)
2006   {
2007     switch (CallbackId)
2008     {
2009       case HAL_NAND_MSP_INIT_CB_ID :
2010         hnand->MspInitCallback = HAL_NAND_MspInit;
2011         break;
2012       case HAL_NAND_MSP_DEINIT_CB_ID :
2013         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
2014         break;
2015       default :
2016         /* update return status */
2017         status =  HAL_ERROR;
2018         break;
2019     }
2020   }
2021   else
2022   {
2023     /* update return status */
2024     status =  HAL_ERROR;
2025   }
2026 
2027   return status;
2028 }
2029 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
2030 
2031 /**
2032   * @}
2033   */
2034 
2035 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
2036   * @ingroup RTEMSBSPsARMSTM32H7
2037   *  @brief   management functions
2038   *
2039 @verbatim
2040   ==============================================================================
2041                          ##### NAND Control functions #####
2042   ==============================================================================
2043   [..]
2044     This subsection provides a set of functions allowing to control dynamically
2045     the NAND interface.
2046 
2047 @endverbatim
2048   * @{
2049   */
2050 
2051 
2052 /**
2053   * @brief  Enables dynamically NAND ECC feature.
2054   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2055   *                the configuration information for NAND module.
2056   * @retval HAL status
2057   */
2058 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2059 {
2060   /* Check the NAND controller state */
2061   if (hnand->State == HAL_NAND_STATE_BUSY)
2062   {
2063     return HAL_BUSY;
2064   }
2065   else if (hnand->State == HAL_NAND_STATE_READY)
2066   {
2067     /* Update the NAND state */
2068     hnand->State = HAL_NAND_STATE_BUSY;
2069 
2070     /* Enable ECC feature */
2071     (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2072 
2073     /* Update the NAND state */
2074     hnand->State = HAL_NAND_STATE_READY;
2075   }
2076   else
2077   {
2078     return HAL_ERROR;
2079   }
2080 
2081   return HAL_OK;
2082 }
2083 
2084 /**
2085   * @brief  Disables dynamically FMC_NAND ECC feature.
2086   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2087   *                the configuration information for NAND module.
2088   * @retval HAL status
2089   */
2090 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2091 {
2092   /* Check the NAND controller state */
2093   if (hnand->State == HAL_NAND_STATE_BUSY)
2094   {
2095     return HAL_BUSY;
2096   }
2097   else if (hnand->State == HAL_NAND_STATE_READY)
2098   {
2099     /* Update the NAND state */
2100     hnand->State = HAL_NAND_STATE_BUSY;
2101 
2102     /* Disable ECC feature */
2103     (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2104 
2105     /* Update the NAND state */
2106     hnand->State = HAL_NAND_STATE_READY;
2107   }
2108   else
2109   {
2110     return HAL_ERROR;
2111   }
2112 
2113   return HAL_OK;
2114 }
2115 
2116 /**
2117   * @brief  Disables dynamically NAND ECC feature.
2118   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2119   *                the configuration information for NAND module.
2120   * @param  ECCval pointer to ECC value
2121   * @param  Timeout maximum timeout to wait
2122   * @retval HAL status
2123   */
2124 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2125 {
2126   HAL_StatusTypeDef status;
2127 
2128   /* Check the NAND controller state */
2129   if (hnand->State == HAL_NAND_STATE_BUSY)
2130   {
2131     return HAL_BUSY;
2132   }
2133   else if (hnand->State == HAL_NAND_STATE_READY)
2134   {
2135     /* Update the NAND state */
2136     hnand->State = HAL_NAND_STATE_BUSY;
2137 
2138     /* Get NAND ECC value */
2139     status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2140 
2141     /* Update the NAND state */
2142     hnand->State = HAL_NAND_STATE_READY;
2143   }
2144   else
2145   {
2146     return HAL_ERROR;
2147   }
2148 
2149   return status;
2150 }
2151 
2152 /**
2153   * @}
2154   */
2155 
2156 
2157 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2158   * @ingroup RTEMSBSPsARMSTM32H7
2159   *  @brief   Peripheral State functions
2160   *
2161 @verbatim
2162   ==============================================================================
2163                          ##### NAND State functions #####
2164   ==============================================================================
2165   [..]
2166     This subsection permits to get in run-time the status of the NAND controller
2167     and the data flow.
2168 
2169 @endverbatim
2170   * @{
2171   */
2172 
2173 /**
2174   * @brief  return the NAND state
2175   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2176   *                the configuration information for NAND module.
2177   * @retval HAL state
2178   */
2179 HAL_NAND_StateTypeDef HAL_NAND_GetState(const NAND_HandleTypeDef *hnand)
2180 {
2181   return hnand->State;
2182 }
2183 
2184 /**
2185   * @brief  NAND memory read status
2186   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2187   *                the configuration information for NAND module.
2188   * @retval NAND status
2189   */
2190 uint32_t HAL_NAND_Read_Status(const NAND_HandleTypeDef *hnand)
2191 {
2192   uint32_t data;
2193   uint32_t deviceaddress;
2194   UNUSED(hnand);
2195 
2196   /* Identify the device address */
2197   deviceaddress = NAND_DEVICE;
2198 
2199   /* Send Read status operation command */
2200   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
2201 
2202   /* Read status register data */
2203   data = *(__IO uint8_t *)deviceaddress;
2204 
2205   /* Return the status */
2206   if ((data & NAND_ERROR) == NAND_ERROR)
2207   {
2208     return NAND_ERROR;
2209   }
2210   else if ((data & NAND_READY) == NAND_READY)
2211   {
2212     return NAND_READY;
2213   }
2214   else
2215   {
2216     return NAND_BUSY;
2217   }
2218 }
2219 
2220 /**
2221   * @}
2222   */
2223 
2224 /**
2225   * @}
2226   */
2227 
2228 /**
2229   * @}
2230   */
2231 
2232 #endif /* HAL_NAND_MODULE_ENABLED  */
2233 
2234 /**
2235   * @}
2236   */
2237