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