STM32L486xx HAL User Manual
stm32l4xx_hal_nand.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_nand.c
00004   * @author  MCD Application Team
00005   * @brief   NAND HAL module driver.
00006   *          This file provides a generic firmware to drive NAND memories mounted
00007   *          as external device.
00008   *
00009   @verbatim
00010   ==============================================================================
00011                          ##### How to use this driver #####
00012   ==============================================================================
00013     [..]
00014       This driver is a generic layered driver which contains a set of APIs used to
00015       control NAND flash memories. It uses the FMC layer functions to interface
00016       with NAND devices. This driver is used as follows:
00017 
00018       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
00019           with control and timing parameters for both common and attribute spaces.
00020 
00021       (+) Read NAND flash memory maker and device IDs using the function
00022           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
00023           structure declared by the function caller.
00024 
00025       (+) Access NAND flash memory by read/write operations using the functions
00026           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
00027           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
00028           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
00029           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
00030           to read/write page(s)/spare area(s). These functions use specific device
00031           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
00032           structure. The read/write address information is contained by the Nand_Address_Typedef
00033           structure passed as parameter.
00034 
00035       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
00036 
00037       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
00038           The erase block address information is contained in the Nand_Address_Typedef
00039           structure passed as parameter.
00040 
00041       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
00042 
00043       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
00044           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
00045           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
00046 
00047       (+) You can monitor the NAND device HAL state by calling the function
00048           HAL_NAND_GetState()
00049 
00050     [..]
00051       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
00052           If a NAND flash device contains different operations and/or implementations,
00053           it should be implemented separately.
00054 
00055   @endverbatim
00056   ******************************************************************************
00057   * @attention
00058   *
00059   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00060   *
00061   * Redistribution and use in source and binary forms, with or without modification,
00062   * are permitted provided that the following conditions are met:
00063   *   1. Redistributions of source code must retain the above copyright notice,
00064   *      this list of conditions and the following disclaimer.
00065   *   2. Redistributions in binary form must reproduce the above copyright notice,
00066   *      this list of conditions and the following disclaimer in the documentation
00067   *      and/or other materials provided with the distribution.
00068   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00069   *      may be used to endorse or promote products derived from this software
00070   *      without specific prior written permission.
00071   *
00072   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00073   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00074   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00075   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00076   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00077   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00078   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00079   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00080   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00081   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00082   *
00083   ******************************************************************************
00084   */
00085 
00086 /* Includes ------------------------------------------------------------------*/
00087 #include "stm32l4xx_hal.h"
00088 
00089 #if defined(FMC_BANK3)
00090 
00091 /** @addtogroup STM32L4xx_HAL_Driver
00092   * @{
00093   */
00094 
00095 #ifdef HAL_NAND_MODULE_ENABLED
00096 
00097 /** @defgroup NAND NAND
00098   * @brief NAND HAL module driver
00099   * @{
00100   */
00101 
00102 /* Private typedef -----------------------------------------------------------*/
00103 /* Private Constants ------------------------------------------------------------*/
00104 /* Private macro -------------------------------------------------------------*/
00105 /* Private variables ---------------------------------------------------------*/
00106 /* Private function prototypes -----------------------------------------------*/
00107 /* Exported functions ---------------------------------------------------------*/
00108 
00109 /** @defgroup NAND_Exported_Functions NAND Exported Functions
00110   * @{
00111   */
00112 
00113 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
00114   * @brief    Initialization and Configuration functions
00115   *
00116   @verbatim
00117   ==============================================================================
00118             ##### NAND Initialization and de-initialization functions #####
00119   ==============================================================================
00120   [..]
00121     This section provides functions allowing to initialize/de-initialize
00122     the NAND memory
00123 
00124 @endverbatim
00125   * @{
00126   */
00127 
00128 /**
00129   * @brief  Perform NAND memory Initialization sequence
00130   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00131   *                the configuration information for NAND module.
00132   * @param  ComSpace_Timing pointer to Common space timing structure
00133   * @param  AttSpace_Timing pointer to Attribute space timing structure
00134   * @retval HAL status
00135   */
00136 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
00137 {
00138   /* Check the NAND handle state */
00139   if(hnand == NULL)
00140   {
00141      return HAL_ERROR;
00142   }
00143 
00144   if(hnand->State == HAL_NAND_STATE_RESET)
00145   {
00146     /* Allocate lock resource and initialize it */
00147     hnand->Lock = HAL_UNLOCKED;
00148     /* Initialize the low level hardware (MSP) */
00149     HAL_NAND_MspInit(hnand);
00150   }
00151 
00152   /* Initialize NAND control Interface */
00153   FMC_NAND_Init(hnand->Instance, &(hnand->Init));
00154 
00155   /* Initialize NAND common space timing Interface */
00156   FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
00157 
00158   /* Initialize NAND attribute space timing Interface */
00159   FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
00160 
00161   /* Enable the NAND device */
00162   __FMC_NAND_ENABLE(hnand->Instance);
00163 
00164   /* Update the NAND controller state */
00165   hnand->State = HAL_NAND_STATE_READY;
00166 
00167   return HAL_OK;
00168 }
00169 
00170 /**
00171   * @brief  Perform NAND memory De-Initialization sequence
00172   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00173   *                the configuration information for NAND module.
00174   * @retval HAL status
00175   */
00176 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
00177 {
00178   /* Initialize the low level hardware (MSP) */
00179   HAL_NAND_MspDeInit(hnand);
00180 
00181   /* Configure the NAND registers with their reset values */
00182   FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
00183 
00184   /* Reset the NAND controller state */
00185   hnand->State = HAL_NAND_STATE_RESET;
00186 
00187   /* Release Lock */
00188   __HAL_UNLOCK(hnand);
00189 
00190   return HAL_OK;
00191 }
00192 
00193 /**
00194   * @brief  Initialize the NAND MSP
00195   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00196   *                the configuration information for NAND module.
00197   * @retval None
00198   */
00199 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
00200 {
00201   /* Prevent unused argument(s) compilation warning */
00202   UNUSED(hnand);
00203 
00204   /* NOTE : This function should not be modified, when the callback is needed,
00205             the HAL_NAND_MspInit could be implemented in the user file
00206    */
00207 }
00208 
00209 /**
00210   * @brief  DeInitialize the NAND MSP
00211   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00212   *                the configuration information for NAND module.
00213   * @retval None
00214   */
00215 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
00216 {
00217   /* Prevent unused argument(s) compilation warning */
00218   UNUSED(hnand);
00219 
00220   /* NOTE : This function should not be modified, when the callback is needed,
00221             the HAL_NAND_MspDeInit could be implemented in the user file
00222    */
00223 }
00224 
00225 
00226 /**
00227   * @brief  This function handles NAND device interrupt request.
00228   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00229   *                the configuration information for NAND module.
00230   * @retval HAL status
00231 */
00232 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
00233 {
00234   /* Check NAND interrupt Rising edge flag */
00235   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
00236   {
00237     /* NAND interrupt callback*/
00238     HAL_NAND_ITCallback(hnand);
00239 
00240     /* Clear NAND interrupt Rising edge pending bit */
00241     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
00242   }
00243 
00244   /* Check NAND interrupt Level flag */
00245   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
00246   {
00247     /* NAND interrupt callback*/
00248     HAL_NAND_ITCallback(hnand);
00249 
00250     /* Clear NAND interrupt Level pending bit */
00251     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
00252   }
00253 
00254   /* Check NAND interrupt Falling edge flag */
00255   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
00256   {
00257     /* NAND interrupt callback*/
00258     HAL_NAND_ITCallback(hnand);
00259 
00260     /* Clear NAND interrupt Falling edge pending bit */
00261     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
00262   }
00263 
00264   /* Check NAND interrupt FIFO empty flag */
00265   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
00266   {
00267     /* NAND interrupt callback*/
00268     HAL_NAND_ITCallback(hnand);
00269 
00270     /* Clear NAND interrupt FIFO empty pending bit */
00271     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
00272   }
00273 
00274 }
00275 
00276 /**
00277   * @brief  NAND interrupt feature callback
00278   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00279   *                the configuration information for NAND module.
00280   * @retval None
00281   */
00282 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
00283 {
00284   /* Prevent unused argument(s) compilation warning */
00285   UNUSED(hnand);
00286 
00287   /* NOTE : This function should not be modified, when the callback is needed,
00288             the HAL_NAND_ITCallback could be implemented in the user file
00289    */
00290 }
00291 
00292 /**
00293   * @}
00294   */
00295 
00296 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
00297   * @brief    Input Output and memory control functions
00298   *
00299   @verbatim
00300   ==============================================================================
00301                     ##### NAND Input and Output functions #####
00302   ==============================================================================
00303   [..]
00304     This section provides functions allowing to use and control the NAND
00305     memory
00306 
00307 @endverbatim
00308   * @{
00309   */
00310 
00311 /**
00312   * @brief  Read the NAND memory electronic signature
00313   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00314   *                the configuration information for NAND module.
00315   * @param  pNAND_ID NAND ID structure
00316   * @retval HAL status
00317   */
00318 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
00319 {
00320   __IO uint32_t data = 0;
00321   __IO uint32_t data1 = 0;
00322   uint32_t deviceAddress = 0;
00323 
00324   /* Process Locked */
00325   __HAL_LOCK(hnand);
00326 
00327   /* Check the NAND controller state */
00328   if(hnand->State == HAL_NAND_STATE_BUSY)
00329   {
00330      return HAL_BUSY;
00331   }
00332 
00333   /* Identify the device address */
00334   deviceAddress = NAND_DEVICE;
00335 
00336   /* Update the NAND controller state */
00337   hnand->State = HAL_NAND_STATE_BUSY;
00338 
00339   /* Send Read ID command sequence */
00340   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_READID;
00341   __DSB();
00342   *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00343   __DSB();
00344 
00345   /* Read the electronic signature from NAND flash */
00346   if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
00347   {
00348     data = *(__IO uint32_t *)deviceAddress;
00349 
00350     /* Return the data read */
00351     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
00352     pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
00353     pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
00354     pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
00355   }
00356   else
00357   {
00358     data = *(__IO uint32_t *)deviceAddress;
00359     data1 = *((__IO uint32_t *)deviceAddress + 4);
00360 
00361     /* Return the data read */
00362     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
00363     pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
00364     pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
00365     pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
00366   }
00367 
00368   /* Update the NAND controller state */
00369   hnand->State = HAL_NAND_STATE_READY;
00370 
00371   /* Process unlocked */
00372   __HAL_UNLOCK(hnand);
00373 
00374   return HAL_OK;
00375 }
00376 
00377 /**
00378   * @brief  NAND memory reset
00379   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00380   *                the configuration information for NAND module.
00381   * @retval HAL status
00382   */
00383 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
00384 {
00385   uint32_t deviceAddress = 0;
00386 
00387   /* Process Locked */
00388   __HAL_LOCK(hnand);
00389 
00390   /* Check the NAND controller state */
00391   if(hnand->State == HAL_NAND_STATE_BUSY)
00392   {
00393      return HAL_BUSY;
00394   }
00395 
00396   /* Identify the device address */
00397   deviceAddress = NAND_DEVICE;
00398 
00399   /* Update the NAND controller state */
00400   hnand->State = HAL_NAND_STATE_BUSY;
00401 
00402   /* Send NAND reset command */
00403   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
00404 
00405   /* Update the NAND controller state */
00406   hnand->State = HAL_NAND_STATE_READY;
00407 
00408   /* Process unlocked */
00409   __HAL_UNLOCK(hnand);
00410 
00411   return HAL_OK;
00412 
00413 }
00414 
00415 /**
00416   * @brief  Configure the device: Enter the physical parameters of the device
00417   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00418   *                the configuration information for NAND module.
00419   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
00420   * @retval HAL status
00421   */
00422 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
00423 {
00424   hnand->Config.PageSize           = pDeviceConfig->PageSize;
00425   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
00426   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
00427   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
00428   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
00429   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
00430   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
00431 
00432   return HAL_OK;
00433 }
00434 
00435 
00436 /**
00437   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
00438   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00439   *                the configuration information for NAND module.
00440   * @param  pAddress  pointer to NAND address structure
00441   * @param  pBuffer  pointer to destination read buffer
00442   * @param  NumPageToRead  number of pages to read from block
00443   * @retval HAL status
00444   */
00445 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
00446 {
00447   __IO uint32_t index  = 0;
00448   uint32_t tickstart = 0U;
00449   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
00450 
00451   /* Process Locked */
00452   __HAL_LOCK(hnand);
00453 
00454   /* Check the NAND controller state */
00455   if(hnand->State == HAL_NAND_STATE_BUSY)
00456   {
00457      return HAL_BUSY;
00458   }
00459 
00460   /* Identify the device address */
00461   deviceAddress = NAND_DEVICE;
00462 
00463   /* Update the NAND controller state */
00464   hnand->State = HAL_NAND_STATE_BUSY;
00465 
00466   /* NAND raw address calculation */
00467   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
00468 
00469   /* Page(s) read loop */
00470   while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00471   {
00472     /* update the buffer size */
00473     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
00474 
00475     /* Send read page command sequence */
00476     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
00477     __DSB();
00478 
00479     /* Cards with page size <= 512 bytes */
00480     if ((hnand->Config.PageSize) <= 512)
00481     {
00482       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00483       {
00484         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00485         __DSB();
00486         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00487         __DSB();
00488         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00489         __DSB();
00490       }
00491       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00492       {
00493         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00494         __DSB();
00495         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00496         __DSB();
00497         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00498         __DSB();
00499         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00500         __DSB();
00501       }
00502     }
00503     else /* (hnand->Config.PageSize) > 512 */
00504     {
00505       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00506       {
00507         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00508         __DSB();
00509         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00510         __DSB();
00511         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00512         __DSB();
00513         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00514         __DSB();
00515       }
00516       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00517       {
00518         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00519         __DSB();
00520         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00521         __DSB();
00522         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00523         __DSB();
00524         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00525         __DSB();
00526         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00527         __DSB();
00528       }
00529     }
00530 
00531     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
00532     __DSB();
00533 
00534 
00535     if (hnand->Config.ExtraCommandEnable == ENABLE)
00536     {
00537       /* Get tick */
00538       tickstart = HAL_GetTick();
00539 
00540       /* Read status until NAND is ready */
00541       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
00542       {
00543         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
00544         {
00545           return HAL_TIMEOUT;
00546         }
00547       }
00548 
00549       /* Go back to read mode */
00550       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
00551       __DSB();
00552     }
00553 
00554     /* Get Data into Buffer */
00555     for(; index < size; index++)
00556     {
00557       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
00558     }
00559 
00560     /* Increment read pages number */
00561     numPagesRead++;
00562 
00563     /* Decrement pages to read */
00564     NumPageToRead--;
00565 
00566     /* Increment the NAND address */
00567     nandAddress = (uint32_t)(nandAddress + 1);
00568   }
00569 
00570   /* Update the NAND controller state */
00571   hnand->State = HAL_NAND_STATE_READY;
00572 
00573   /* Process unlocked */
00574   __HAL_UNLOCK(hnand);
00575 
00576   return HAL_OK;
00577 }
00578 
00579 /**
00580   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
00581   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00582   *                the configuration information for NAND module.
00583   * @param  pAddress  pointer to NAND address structure
00584   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
00585   * @param  NumPageToRead  number of pages to read from block
00586   * @retval HAL status
00587   */
00588 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
00589 {
00590   __IO uint32_t index  = 0;
00591   uint32_t tickstart = 0;
00592   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
00593 
00594   /* Process Locked */
00595   __HAL_LOCK(hnand);
00596 
00597   /* Check the NAND controller state */
00598   if (hnand->State == HAL_NAND_STATE_BUSY)
00599   {
00600     return HAL_BUSY;
00601   }
00602 
00603   /* Identify the device address */
00604   deviceAddress = NAND_DEVICE;
00605 
00606   /* Update the NAND controller state */
00607   hnand->State = HAL_NAND_STATE_BUSY;
00608 
00609   /* NAND raw address calculation */
00610   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
00611 
00612   /* Page(s) read loop */
00613   while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00614   {
00615     /* update the buffer size */
00616     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
00617 
00618     /* Send read page command sequence */
00619     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
00620     __DSB();
00621 
00622     /* Cards with page size <= 512 bytes */
00623     if ((hnand->Config.PageSize) <= 512)
00624     {
00625       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00626       {
00627         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00628         __DSB();
00629         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00630         __DSB();
00631         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00632         __DSB();
00633       }
00634       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00635       {
00636         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00637         __DSB();
00638         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00639         __DSB();
00640         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00641         __DSB();
00642         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00643         __DSB();
00644       }
00645     }
00646     else /* (hnand->Config.PageSize) > 512 */
00647     {
00648       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00649       {
00650         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00651         __DSB();
00652         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00653         __DSB();
00654         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00655         __DSB();
00656         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00657         __DSB();
00658       }
00659       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00660       {
00661         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00662         __DSB();
00663         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00664         __DSB();
00665         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00666         __DSB();
00667         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00668         __DSB();
00669         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00670         __DSB();
00671       }
00672     }
00673 
00674     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
00675     __DSB();
00676 
00677     if (hnand->Config.ExtraCommandEnable == ENABLE)
00678     {
00679       /* Get tick */
00680       tickstart = HAL_GetTick();
00681 
00682       /* Read status until NAND is ready */
00683       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
00684       {
00685         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
00686         {
00687           return HAL_TIMEOUT;
00688         }
00689       }
00690 
00691       /* Go back to read mode */
00692       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
00693       __DSB();
00694     }
00695 
00696     /* Get Data into Buffer */
00697     for (; index < size; index++)
00698     {
00699       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
00700     }
00701 
00702     /* Increment read pages number */
00703     numPagesRead++;
00704 
00705     /* Decrement pages to read */
00706     NumPageToRead--;
00707 
00708     /* Increment the NAND address */
00709     nandAddress = (uint32_t)(nandAddress + 1);
00710   }
00711 
00712   /* Update the NAND controller state */
00713   hnand->State = HAL_NAND_STATE_READY;
00714 
00715   /* Process unlocked */
00716   __HAL_UNLOCK(hnand);
00717 
00718   return HAL_OK;
00719 }
00720 
00721 /**
00722   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
00723   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00724   *                the configuration information for NAND module.
00725   * @param  pAddress  pointer to NAND address structure
00726   * @param  pBuffer  pointer to source buffer to write
00727   * @param  NumPageToWrite   number of pages to write to block
00728   * @retval HAL status
00729   */
00730 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
00731 {
00732   __IO uint32_t index = 0;
00733   uint32_t tickstart = 0;
00734   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
00735 
00736   /* Process Locked */
00737   __HAL_LOCK(hnand);
00738 
00739   /* Check the NAND controller state */
00740   if(hnand->State == HAL_NAND_STATE_BUSY)
00741   {
00742      return HAL_BUSY;
00743   }
00744 
00745   /* Identify the device address */
00746   deviceAddress = NAND_DEVICE;
00747 
00748   /* Update the NAND controller state */
00749   hnand->State = HAL_NAND_STATE_BUSY;
00750 
00751   /* NAND raw address calculation */
00752   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
00753 
00754   /* Page(s) write loop */
00755   while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00756   {
00757     /* update the buffer size */
00758     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
00759 
00760     /* Send write page command sequence */
00761     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
00762     __DSB();
00763     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
00764     __DSB();
00765 
00766     /* Cards with page size <= 512 bytes */
00767     if ((hnand->Config.PageSize) <= 512)
00768     {
00769       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00770       {
00771         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00772         __DSB();
00773         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00774         __DSB();
00775         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00776         __DSB();
00777       }
00778       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00779       {
00780         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00781         __DSB();
00782         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00783         __DSB();
00784         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00785         __DSB();
00786         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00787         __DSB();
00788       }
00789     }
00790     else /* (hnand->Config.PageSize) > 512 */
00791     {
00792       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00793       {
00794         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00795         __DSB();
00796         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00797         __DSB();
00798         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00799         __DSB();
00800         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00801         __DSB();
00802       }
00803       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00804       {
00805         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00806         __DSB();
00807         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00808         __DSB();
00809         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00810         __DSB();
00811         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00812         __DSB();
00813         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00814         __DSB();
00815       }
00816     }
00817 
00818     /* Write data to memory */
00819     for (; index < size; index++)
00820     {
00821       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
00822       __DSB();
00823     }
00824 
00825     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
00826     __DSB();
00827 
00828     /* Get tick */
00829     tickstart = HAL_GetTick();
00830 
00831     /* Read status until NAND is ready */
00832     while (HAL_NAND_Read_Status(hnand) != NAND_READY)
00833     {
00834       if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
00835       {
00836         return HAL_TIMEOUT;
00837       }
00838     }
00839 
00840     /* Increment written pages number */
00841     numPagesWritten++;
00842 
00843     /* Decrement pages to write */
00844     NumPageToWrite--;
00845 
00846     /* Increment the NAND address */
00847     nandAddress = (uint32_t)(nandAddress + 1);
00848   }
00849 
00850   /* Update the NAND controller state */
00851   hnand->State = HAL_NAND_STATE_READY;
00852 
00853   /* Process unlocked */
00854   __HAL_UNLOCK(hnand);
00855 
00856   return HAL_OK;
00857 }
00858 
00859 /**
00860   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
00861   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
00862   *                the configuration information for NAND module.
00863   * @param  pAddress  pointer to NAND address structure
00864   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
00865   * @param  NumPageToWrite   number of pages to write to block
00866   * @retval HAL status
00867   */
00868 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
00869 {
00870   __IO uint32_t index = 0;
00871   uint32_t tickstart = 0;
00872   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
00873 
00874   /* Process Locked */
00875   __HAL_LOCK(hnand);
00876 
00877   /* Check the NAND controller state */
00878   if (hnand->State == HAL_NAND_STATE_BUSY)
00879   {
00880     return HAL_BUSY;
00881   }
00882 
00883   /* Identify the device address */
00884   deviceAddress = NAND_DEVICE;
00885 
00886   /* Update the NAND controller state */
00887   hnand->State = HAL_NAND_STATE_BUSY;
00888 
00889   /* NAND raw address calculation */
00890   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
00891 
00892   /* Page(s) write loop */
00893   while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
00894   {
00895     /* update the buffer size */
00896     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
00897 
00898     /* Send write page command sequence */
00899     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
00900     __DSB();
00901     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
00902     __DSB();
00903 
00904     /* Cards with page size <= 512 bytes */
00905     if ((hnand->Config.PageSize) <= 512)
00906     {
00907       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00908       {
00909         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00910         __DSB();
00911         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00912         __DSB();
00913         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00914         __DSB();
00915       }
00916       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00917       {
00918         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00919         __DSB();
00920         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00921         __DSB();
00922         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00923         __DSB();
00924         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00925         __DSB();
00926       }
00927     }
00928     else /* (hnand->Config.PageSize) > 512 */
00929     {
00930       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
00931       {
00932         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00933         __DSB();
00934         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00935         __DSB();
00936         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00937         __DSB();
00938         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00939         __DSB();
00940       }
00941       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
00942       {
00943         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00944         __DSB();
00945         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
00946         __DSB();
00947         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
00948         __DSB();
00949         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
00950         __DSB();
00951         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
00952         __DSB();
00953       }
00954     }
00955 
00956     /* Write data to memory */
00957     for(; index < size; index++)
00958     {
00959       *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
00960       __DSB();
00961     }
00962 
00963     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
00964     __DSB();
00965 
00966     /* Get tick */
00967     tickstart = HAL_GetTick();
00968 
00969     /* Read status until NAND is ready */
00970     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
00971     {
00972       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
00973       {
00974         return HAL_TIMEOUT;
00975       }
00976     }
00977 
00978     /* Increment written pages number */
00979     numPagesWritten++;
00980 
00981     /* Decrement pages to write */
00982     NumPageToWrite--;
00983 
00984     /* Increment the NAND address */
00985     nandAddress = (uint32_t)(nandAddress + 1);
00986   }
00987 
00988   /* Update the NAND controller state */
00989   hnand->State = HAL_NAND_STATE_READY;
00990 
00991   /* Process unlocked */
00992   __HAL_UNLOCK(hnand);
00993 
00994   return HAL_OK;
00995 }
00996 
00997 /**
00998   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
00999   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01000   *                the configuration information for NAND module.
01001   * @param  pAddress  pointer to NAND address structure
01002   * @param  pBuffer pointer to source buffer to write
01003   * @param  NumSpareAreaToRead Number of spare area to read
01004   * @retval HAL status
01005 */
01006 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
01007 {
01008   __IO uint32_t index   = 0;
01009   uint32_t tickstart = 0U;
01010   uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
01011 
01012   /* Process Locked */
01013   __HAL_LOCK(hnand);
01014 
01015   /* Check the NAND controller state */
01016   if (hnand->State == HAL_NAND_STATE_BUSY)
01017   {
01018     return HAL_BUSY;
01019   }
01020 
01021   /* Identify the device address */
01022   deviceAddress = NAND_DEVICE;
01023 
01024   /* Update the NAND controller state */
01025   hnand->State = HAL_NAND_STATE_BUSY;
01026 
01027   /* NAND raw address calculation */
01028   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
01029 
01030   /* Column in page address */
01031   columnAddress = COLUMN_ADDRESS(hnand);
01032 
01033   /* Spare area(s) read loop */
01034   while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01035   {
01036     /* update the buffer size */
01037     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
01038 
01039     /* Cards with page size <= 512 bytes */
01040     if ((hnand->Config.PageSize) <= 512)
01041     {
01042       /* Send read spare area command sequence */
01043       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
01044       __DSB();
01045 
01046       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01047       {
01048         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01049         __DSB();
01050         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01051         __DSB();
01052         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01053         __DSB();
01054       }
01055       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01056       {
01057         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01058         __DSB();
01059         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01060         __DSB();
01061         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01062         __DSB();
01063         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01064         __DSB();
01065       }
01066     }
01067     else /* (hnand->Config.PageSize) > 512 */
01068     {
01069       /* Send read spare area command sequence */
01070       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
01071       __DSB();
01072 
01073       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01074       {
01075         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01076         __DSB();
01077         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01078         __DSB();
01079         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01080         __DSB();
01081         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01082         __DSB();
01083       }
01084       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01085       {
01086         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01087         __DSB();
01088         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01089         __DSB();
01090         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01091         __DSB();
01092         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01093         __DSB();
01094         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01095         __DSB();
01096       }
01097     }
01098 
01099     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
01100     __DSB();
01101 
01102     if (hnand->Config.ExtraCommandEnable == ENABLE)
01103     {
01104       /* Get tick */
01105       tickstart = HAL_GetTick();
01106 
01107       /* Read status until NAND is ready */
01108       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01109       {
01110         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01111         {
01112           return HAL_TIMEOUT;
01113         }
01114       }
01115 
01116       /* Go back to read mode */
01117       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
01118       __DSB();
01119     }
01120 
01121     /* Get Data into Buffer */
01122     for (; index < size; index++)
01123     {
01124       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
01125     }
01126 
01127     /* Increment read spare areas number */
01128     numSpareAreaRead++;
01129 
01130     /* Decrement spare areas to read */
01131     NumSpareAreaToRead--;
01132 
01133     /* Increment the NAND address */
01134     nandAddress = (uint32_t)(nandAddress + 1);
01135   }
01136 
01137   /* Update the NAND controller state */
01138   hnand->State = HAL_NAND_STATE_READY;
01139 
01140   /* Process unlocked */
01141   __HAL_UNLOCK(hnand);
01142 
01143   return HAL_OK;
01144 }
01145 
01146 /**
01147   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
01148   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01149   *                the configuration information for NAND module.
01150   * @param  pAddress  pointer to NAND address structure
01151   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
01152   * @param  NumSpareAreaToRead Number of spare area to read
01153   * @retval HAL status
01154 */
01155 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
01156 {
01157   __IO uint32_t index = 0;
01158   uint32_t tickstart = 0U;
01159   uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
01160 
01161   /* Process Locked */
01162   __HAL_LOCK(hnand);
01163 
01164   /* Check the NAND controller state */
01165   if(hnand->State == HAL_NAND_STATE_BUSY)
01166   {
01167      return HAL_BUSY;
01168   }
01169 
01170   /* Identify the device address */
01171   deviceAddress = NAND_DEVICE;
01172 
01173   /* Update the NAND controller state */
01174   hnand->State = HAL_NAND_STATE_BUSY;
01175 
01176   /* NAND raw address calculation */
01177   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
01178 
01179   /* Column in page address */
01180   columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
01181 
01182   /* Spare area(s) read loop */
01183   while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01184   {
01185     /* update the buffer size */
01186     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
01187 
01188     /* Cards with page size <= 512 bytes */
01189     if ((hnand->Config.PageSize) <= 512)
01190     {
01191       /* Send read spare area command sequence */
01192       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
01193       __DSB();
01194 
01195       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01196       {
01197         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01198         __DSB();
01199         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01200         __DSB();
01201         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01202         __DSB();
01203       }
01204       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01205       {
01206         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01207         __DSB();
01208         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01209         __DSB();
01210         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01211         __DSB();
01212         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01213         __DSB();
01214       }
01215     }
01216     else /* (hnand->Config.PageSize) > 512 */
01217     {
01218       /* Send read spare area command sequence */
01219       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
01220       __DSB();
01221 
01222       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01223       {
01224         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01225         __DSB();
01226         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01227         __DSB();
01228         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01229         __DSB();
01230         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01231         __DSB();
01232       }
01233       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
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         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01244         __DSB();
01245       }
01246     }
01247 
01248     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
01249     __DSB();
01250 
01251     if (hnand->Config.ExtraCommandEnable == ENABLE)
01252     {
01253       /* Get tick */
01254       tickstart = HAL_GetTick();
01255 
01256       /* Read status until NAND is ready */
01257       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01258       {
01259         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01260         {
01261           return HAL_TIMEOUT;
01262         }
01263       }
01264 
01265       /* Go back to read mode */
01266       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
01267       __DSB();
01268     }
01269 
01270     /* Get Data into Buffer */
01271     for ( ;index < size; index++)
01272     {
01273       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
01274     }
01275 
01276     /* Increment read spare areas number */
01277     numSpareAreaRead++;
01278 
01279     /* Decrement spare areas to read */
01280     NumSpareAreaToRead--;
01281 
01282     /* Increment the NAND address */
01283     nandAddress = (uint32_t)(nandAddress + 1);
01284   }
01285 
01286   /* Update the NAND controller state */
01287   hnand->State = HAL_NAND_STATE_READY;
01288 
01289   /* Process unlocked */
01290   __HAL_UNLOCK(hnand);
01291 
01292   return HAL_OK;
01293 }
01294 
01295 /**
01296   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
01297   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01298   *                the configuration information for NAND module.
01299   * @param  pAddress  pointer to NAND address structure
01300   * @param  pBuffer  pointer to source buffer to write
01301   * @param  NumSpareAreaTowrite   number of spare areas to write to block
01302   * @retval HAL status
01303   */
01304 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
01305 {
01306   __IO uint32_t index = 0;
01307   uint32_t tickstart = 0;
01308   uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
01309 
01310   /* Process Locked */
01311   __HAL_LOCK(hnand);
01312 
01313   /* Check the NAND controller state */
01314   if(hnand->State == HAL_NAND_STATE_BUSY)
01315   {
01316      return HAL_BUSY;
01317   }
01318 
01319   /* Identify the device address */
01320   deviceAddress = NAND_DEVICE;
01321 
01322   /* Update the FMC_NAND controller state */
01323   hnand->State = HAL_NAND_STATE_BUSY;
01324 
01325   /* Page address calculation */
01326   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
01327 
01328   /* Column in page address */
01329   columnAddress = COLUMN_ADDRESS(hnand);
01330 
01331   /* Spare area(s) write loop */
01332   while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01333   {
01334     /* update the buffer size */
01335     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
01336 
01337     /* Cards with page size <= 512 bytes */
01338     if ((hnand->Config.PageSize) <= 512)
01339     {
01340       /* Send write Spare area command sequence */
01341       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
01342       __DSB();
01343       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
01344       __DSB();
01345 
01346       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01347       {
01348         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01349         __DSB();
01350         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01351         __DSB();
01352         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01353         __DSB();
01354       }
01355       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01356       {
01357         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01358         __DSB();
01359         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01360         __DSB();
01361         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01362         __DSB();
01363         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01364         __DSB();
01365       }
01366     }
01367     else /* (hnand->Config.PageSize) > 512 */
01368     {
01369       /* Send write Spare area command sequence */
01370       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
01371       __DSB();
01372       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
01373       __DSB();
01374 
01375       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01376       {
01377         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01378         __DSB();
01379         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01380         __DSB();
01381         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01382         __DSB();
01383         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01384         __DSB();
01385       }
01386       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01387       {
01388         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01389         __DSB();
01390         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01391         __DSB();
01392         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01393         __DSB();
01394         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01395         __DSB();
01396         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01397         __DSB();
01398       }
01399     }
01400 
01401     /* Write data to memory */
01402     for(; index < size; index++)
01403     {
01404       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
01405       __DSB();
01406     }
01407 
01408     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01409     __DSB();
01410 
01411     /* Get tick */
01412     tickstart = HAL_GetTick();
01413 
01414     /* Read status until NAND is ready */
01415     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
01416     {
01417       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
01418       {
01419         return HAL_TIMEOUT;
01420       }
01421     }
01422 
01423     /* Increment written spare areas number */
01424     numSpareAreaWritten++;
01425 
01426     /* Decrement spare areas to write */
01427     NumSpareAreaTowrite--;
01428 
01429     /* Increment the NAND address */
01430     nandAddress = (uint32_t)(nandAddress + 1);
01431   }
01432 
01433   /* Update the NAND controller state */
01434   hnand->State = HAL_NAND_STATE_READY;
01435 
01436   /* Process unlocked */
01437   __HAL_UNLOCK(hnand);
01438 
01439   return HAL_OK;
01440 }
01441 
01442 /**
01443   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
01444   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01445   *                the configuration information for NAND module.
01446   * @param  pAddress  pointer to NAND address structure
01447   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
01448   * @param  NumSpareAreaTowrite   number of spare areas to write to block
01449   * @retval HAL status
01450   */
01451 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
01452 {
01453   __IO uint32_t index = 0;
01454   uint32_t tickstart = 0;
01455   uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
01456 
01457   /* Process Locked */
01458   __HAL_LOCK(hnand);
01459 
01460   /* Check the NAND controller state */
01461   if (hnand->State == HAL_NAND_STATE_BUSY)
01462   {
01463     return HAL_BUSY;
01464   }
01465 
01466   /* Identify the device address */
01467   deviceAddress = NAND_DEVICE;
01468 
01469   /* Update the FMC_NAND controller state */
01470   hnand->State = HAL_NAND_STATE_BUSY;
01471 
01472   /* NAND raw address calculation */
01473   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
01474 
01475   /* Column in page address */
01476   columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
01477 
01478   /* Spare area(s) write loop */
01479   while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
01480   {
01481     /* update the buffer size */
01482     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
01483 
01484     /* Cards with page size <= 512 bytes */
01485     if ((hnand->Config.PageSize) <= 512)
01486     {
01487       /* Send write Spare area command sequence */
01488       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
01489       __DSB();
01490       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
01491       __DSB();
01492 
01493       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01494       {
01495         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01496         __DSB();
01497         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01498         __DSB();
01499         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01500         __DSB();
01501       }
01502       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01503       {
01504         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
01505         __DSB();
01506         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01507         __DSB();
01508         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01509         __DSB();
01510         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01511         __DSB();
01512       }
01513     }
01514     else /* (hnand->Config.PageSize) > 512 */
01515     {
01516       /* Send write Spare area command sequence */
01517       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
01518       __DSB();
01519       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
01520       __DSB();
01521 
01522       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
01523       {
01524         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01525         __DSB();
01526         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01527         __DSB();
01528         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01529         __DSB();
01530         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01531         __DSB();
01532       }
01533       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
01534       {
01535         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
01536         __DSB();
01537         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
01538         __DSB();
01539         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
01540         __DSB();
01541         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
01542         __DSB();
01543         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
01544         __DSB();
01545       }
01546     }
01547 
01548     /* Write data to memory */
01549     for (; index < size; index++)
01550     {
01551       *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
01552       __DSB();
01553     }
01554 
01555     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
01556     __DSB();
01557 
01558     /* Get tick */
01559     tickstart = HAL_GetTick();
01560 
01561     /* Read status until NAND is ready */
01562     while (HAL_NAND_Read_Status(hnand) != NAND_READY)
01563     {
01564       if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
01565       {
01566         return HAL_TIMEOUT;
01567       }
01568     }
01569 
01570     /* Increment written spare areas number */
01571     numSpareAreaWritten++;
01572 
01573     /* Decrement spare areas to write */
01574     NumSpareAreaTowrite--;
01575 
01576     /* Increment the NAND address */
01577     nandAddress = (uint32_t)(nandAddress + 1);
01578   }
01579 
01580   /* Update the NAND controller state */
01581   hnand->State = HAL_NAND_STATE_READY;
01582 
01583   /* Process unlocked */
01584   __HAL_UNLOCK(hnand);
01585 
01586   return HAL_OK;
01587 }
01588 
01589 /**
01590   * @brief  NAND memory Block erase
01591   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01592   *                the configuration information for NAND module.
01593   * @param  pAddress  pointer to NAND address structure
01594   * @retval HAL status
01595   */
01596 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
01597 {
01598   uint32_t DeviceAddress = 0;
01599 
01600   /* Process Locked */
01601   __HAL_LOCK(hnand);
01602 
01603   /* Check the NAND controller state */
01604   if(hnand->State == HAL_NAND_STATE_BUSY)
01605   {
01606      return HAL_BUSY;
01607   }
01608 
01609   /* Identify the device address */
01610   DeviceAddress = NAND_DEVICE;
01611 
01612   /* Update the NAND controller state */
01613   hnand->State = HAL_NAND_STATE_BUSY;
01614 
01615   /* Send Erase block command sequence */
01616   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
01617   __DSB();
01618   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01619   __DSB();
01620   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01621   __DSB();
01622   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
01623   __DSB();
01624 
01625   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
01626   __DSB();
01627 
01628   /* Update the NAND controller state */
01629   hnand->State = HAL_NAND_STATE_READY;
01630 
01631   /* Process unlocked */
01632   __HAL_UNLOCK(hnand);
01633 
01634   return HAL_OK;
01635 }
01636 
01637 /**
01638   * @brief  Increment the NAND memory address
01639   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01640   *                the configuration information for NAND module.
01641   * @param pAddress pointer to NAND address structure
01642   * @retval The new status of the increment address operation. It can be:
01643   *           - NAND_VALID_ADDRESS: When the new address is valid address
01644   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
01645   */
01646 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
01647 {
01648   uint32_t status = NAND_VALID_ADDRESS;
01649 
01650   /* Increment page address */
01651   pAddress->Page++;
01652 
01653   /* Check NAND address is valid */
01654   if (pAddress->Page == hnand->Config.BlockSize)
01655   {
01656     pAddress->Page = 0;
01657     pAddress->Block++;
01658 
01659     if (pAddress->Block == hnand->Config.PlaneSize)
01660     {
01661       pAddress->Block = 0;
01662       pAddress->Plane++;
01663 
01664       if (pAddress->Plane == (hnand->Config.PlaneNbr))
01665       {
01666         status = NAND_INVALID_ADDRESS;
01667       }
01668     }
01669   }
01670 
01671   return (status);
01672 }
01673 /**
01674   * @}
01675   */
01676 
01677 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
01678  *  @brief   management functions
01679  *
01680 @verbatim
01681   ==============================================================================
01682                          ##### NAND Control functions #####
01683   ==============================================================================
01684   [..]
01685     This subsection provides a set of functions allowing to control dynamically
01686     the NAND interface.
01687 
01688 @endverbatim
01689   * @{
01690   */
01691 
01692 
01693 /**
01694   * @brief  Enable dynamically NAND ECC feature.
01695   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01696   *                the configuration information for NAND module.
01697   * @retval HAL status
01698   */
01699 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
01700 {
01701   /* Check the NAND controller state */
01702   if(hnand->State == HAL_NAND_STATE_BUSY)
01703   {
01704      return HAL_BUSY;
01705   }
01706 
01707   /* Update the NAND state */
01708   hnand->State = HAL_NAND_STATE_BUSY;
01709 
01710   /* Enable ECC feature */
01711   FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
01712 
01713   /* Update the NAND state */
01714   hnand->State = HAL_NAND_STATE_READY;
01715 
01716   return HAL_OK;
01717 }
01718 
01719 /**
01720   * @brief  Disable dynamically NAND ECC feature
01721   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01722   *                the configuration information for NAND module.
01723   * @retval HAL status
01724   */
01725 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
01726 {
01727   /* Check the NAND controller state */
01728   if(hnand->State == HAL_NAND_STATE_BUSY)
01729   {
01730      return HAL_BUSY;
01731   }
01732 
01733   /* Update the NAND state */
01734   hnand->State = HAL_NAND_STATE_BUSY;
01735 
01736   /* Disable ECC feature */
01737   FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
01738 
01739   /* Update the NAND state */
01740   hnand->State = HAL_NAND_STATE_READY;
01741 
01742   return HAL_OK;
01743 }
01744 
01745 /**
01746   * @brief  Get NAND ECC value
01747   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01748   *                the configuration information for NAND module.
01749   * @param  ECCval pointer to ECC value
01750   * @param  Timeout maximum timeout to wait
01751   * @retval HAL status
01752   */
01753 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
01754 {
01755   HAL_StatusTypeDef status = HAL_OK;
01756 
01757   /* Check the NAND controller state */
01758   if(hnand->State == HAL_NAND_STATE_BUSY)
01759   {
01760      return HAL_BUSY;
01761   }
01762 
01763   /* Update the NAND state */
01764   hnand->State = HAL_NAND_STATE_BUSY;
01765 
01766   /* Get NAND ECC value */
01767   status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
01768 
01769   /* Update the NAND state */
01770   hnand->State = HAL_NAND_STATE_READY;
01771 
01772   return status;
01773 }
01774 
01775 /**
01776   * @}
01777   */
01778 
01779 
01780 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
01781  *  @brief   Peripheral State functions
01782  *
01783 @verbatim
01784   ==============================================================================
01785                          ##### NAND State functions #####
01786   ==============================================================================
01787   [..]
01788     This subsection permits to get in run-time the status of the NAND controller
01789     and the data flow.
01790 
01791 @endverbatim
01792   * @{
01793   */
01794 
01795 /**
01796   * @brief  Return the NAND state
01797   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01798   *                the configuration information for NAND module.
01799   * @retval HAL state
01800   */
01801 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
01802 {
01803   /* Return NAND handle state */
01804   return hnand->State;
01805 }
01806 
01807 /**
01808   * @brief  NAND memory read status
01809   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
01810   *                the configuration information for NAND module.
01811   * @retval NAND status
01812   */
01813 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
01814 {
01815   uint32_t data = 0;
01816   uint32_t DeviceAddress = 0;
01817 
01818   /* Identify the device address */
01819   DeviceAddress = NAND_DEVICE;
01820 
01821   /* Send Read status operation command */
01822   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
01823 
01824   /* Read status register data */
01825   data = *(__IO uint8_t *)DeviceAddress;
01826 
01827   /* Return the status */
01828   if ((data & NAND_ERROR) == NAND_ERROR)
01829   {
01830     return NAND_ERROR;
01831   }
01832   else if ((data & NAND_READY) == NAND_READY)
01833   {
01834     return NAND_READY;
01835   }
01836 
01837   return NAND_BUSY;
01838 }
01839 
01840 /**
01841   * @}
01842   */
01843 
01844 /**
01845   * @}
01846   */
01847 
01848 /**
01849   * @}
01850   */
01851 
01852 #endif /* HAL_NAND_MODULE_ENABLED  */
01853 
01854 /**
01855   * @}
01856   */
01857 
01858 #endif /* FMC_BANK3 */
01859 
01860 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/