Subversion Repositories DashDisplay

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_nand.c
  4.   * @author  MCD Application Team
  5.   * @version V1.0.1
  6.   * @date    31-July-2015
  7.   * @brief   NAND HAL module driver.
  8.   *          This file provides a generic firmware to drive NAND memories mounted
  9.   *          as external device.
  10.   *        
  11.   @verbatim
  12.   ==============================================================================
  13.                          ##### How to use this driver #####
  14.   ==============================================================================    
  15.     [..]
  16.       This driver is a generic layered driver which contains a set of APIs used to
  17.       control NAND flash memories. It uses the FSMC/FSMC layer functions to interface
  18.       with NAND devices. This driver is used as follows:
  19.    
  20.       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
  21.           with control and timing parameters for both common and attribute spaces.
  22.            
  23.       (+) Read NAND flash memory maker and device IDs using the function
  24.           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
  25.           structure declared by the function caller.
  26.        
  27.       (+) Access NAND flash memory by read/write operations using the functions
  28.           HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
  29.           to read/write page(s)/spare area(s). These functions use specific device
  30.           information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
  31.           structure. The read/write address information is contained by the Nand_Address_Typedef
  32.           structure passed as parameter.
  33.        
  34.       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
  35.        
  36.       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
  37.           The erase block address information is contained in the Nand_Address_Typedef
  38.           structure passed as parameter.
  39.    
  40.       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
  41.        
  42.       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
  43.           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
  44.           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
  45.        
  46.       (+) You can monitor the NAND device HAL state by calling the function
  47.           HAL_NAND_GetState()  
  48.  
  49.     [..]
  50.       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
  51.           If a NAND flash device contains different operations and/or implementations,
  52.           it should be implemented separately.
  53.  
  54.   @endverbatim
  55.   ******************************************************************************
  56.   * @attention
  57.   *
  58.   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  59.   *
  60.   * Redistribution and use in source and binary forms, with or without modification,
  61.   * are permitted provided that the following conditions are met:
  62.   *   1. Redistributions of source code must retain the above copyright notice,
  63.   *      this list of conditions and the following disclaimer.
  64.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  65.   *      this list of conditions and the following disclaimer in the documentation
  66.   *      and/or other materials provided with the distribution.
  67.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  68.   *      may be used to endorse or promote products derived from this software
  69.   *      without specific prior written permission.
  70.   *
  71.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  72.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  73.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  75.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  76.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  77.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  78.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  79.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  80.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  81.   *
  82.   ******************************************************************************
  83.   */
  84.  
  85. /* Includes ------------------------------------------------------------------*/
  86. #include "stm32f1xx_hal.h"
  87.  
  88. /** @addtogroup STM32F1xx_HAL_Driver
  89.   * @{
  90.   */
  91.  
  92. #ifdef HAL_NAND_MODULE_ENABLED
  93.  
  94. #if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
  95.  
  96. /** @defgroup NAND NAND
  97.   * @brief NAND HAL module driver
  98.   * @{
  99.   */
  100.  
  101. /* Private typedef -----------------------------------------------------------*/
  102. /* Private define ------------------------------------------------------------*/
  103. /** @defgroup NAND_Private_Constants NAND Private Constants
  104.   * @{
  105.   */
  106.  
  107. /**
  108.   * @}
  109.   */
  110.  
  111. /* Private macro -------------------------------------------------------------*/    
  112. /** @defgroup NAND_Private_Macros NAND Private Macros
  113.   * @{
  114.   */
  115.  
  116. /**
  117.   * @}
  118.   */
  119.  
  120. /* Private variables ---------------------------------------------------------*/
  121. /* Private function prototypes -----------------------------------------------*/
  122. /** @defgroup NAND_Private_Functions NAND Private Functions
  123.   * @{
  124.   */
  125. static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address);
  126. /**
  127.   * @}
  128.   */
  129.  
  130. /* Exported functions ---------------------------------------------------------*/
  131.  
  132. /** @defgroup NAND_Exported_Functions NAND Exported Functions
  133.   * @{
  134.   */
  135.    
  136. /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
  137.   * @brief    Initialization and Configuration functions
  138.   *
  139.   @verbatim    
  140.   ==============================================================================
  141.             ##### NAND Initialization and de-initialization functions #####
  142.   ==============================================================================
  143.   [..]  
  144.     This section provides functions allowing to initialize/de-initialize
  145.     the NAND memory
  146.  
  147. @endverbatim
  148.   * @{
  149.   */
  150.    
  151. /**
  152.   * @brief  Perform NAND memory Initialization sequence
  153.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  154.   *                the configuration information for NAND module.
  155.   * @param  ComSpace_Timing: pointer to Common space timing structure
  156.   * @param  AttSpace_Timing: pointer to Attribute space timing structure
  157.   * @retval HAL status
  158.   */
  159. HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  160. {
  161.   /* Check the NAND handle state */
  162.   if(hnand == NULL)
  163.   {
  164.      return HAL_ERROR;
  165.   }
  166.  
  167.   if(hnand->State == HAL_NAND_STATE_RESET)
  168.   {
  169.     /* Allocate lock resource and initialize it */
  170.     hnand->Lock = HAL_UNLOCKED;
  171.    
  172.     /* Initialize the low level hardware (MSP) */
  173.     HAL_NAND_MspInit(hnand);
  174.   }
  175.  
  176.   /* Initialize NAND control Interface */
  177.   FSMC_NAND_Init(hnand->Instance, &(hnand->Init));
  178.  
  179.   /* Initialize NAND common space timing Interface */  
  180.   FSMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  181.  
  182.   /* Initialize NAND attribute space timing Interface */  
  183.   FSMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  184.  
  185.   /* Enable the NAND device */
  186.   __FSMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
  187.  
  188.   /* Update the NAND controller state */
  189.   hnand->State = HAL_NAND_STATE_READY;
  190.  
  191.   return HAL_OK;
  192. }
  193.  
  194. /**
  195.   * @brief  Perform NAND memory De-Initialization sequence
  196.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  197.   *                the configuration information for NAND module.
  198.   * @retval HAL status
  199.   */
  200. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)  
  201. {
  202.   /* Initialize the low level hardware (MSP) */
  203.   HAL_NAND_MspDeInit(hnand);
  204.  
  205.   /* Configure the NAND registers with their reset values */
  206.   FSMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
  207.  
  208.   /* Reset the NAND controller state */
  209.   hnand->State = HAL_NAND_STATE_RESET;
  210.  
  211.   /* Release Lock */
  212.   __HAL_UNLOCK(hnand);
  213.  
  214.   return HAL_OK;
  215. }
  216.  
  217. /**
  218.   * @brief  NAND MSP Init
  219.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  220.   *                the configuration information for NAND module.
  221.   * @retval None
  222.   */
  223. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  224. {
  225.   /* NOTE : This function Should not be modified, when the callback is needed,
  226.             the HAL_NAND_MspInit could be implemented in the user file
  227.    */
  228. }
  229.  
  230. /**
  231.   * @brief  NAND MSP DeInit
  232.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  233.   *                the configuration information for NAND module.
  234.   * @retval None
  235.   */
  236. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  237. {
  238.   /* NOTE : This function Should not be modified, when the callback is needed,
  239.             the HAL_NAND_MspDeInit could be implemented in the user file
  240.    */
  241. }
  242.  
  243.  
  244. /**
  245.   * @brief  This function handles NAND device interrupt request.
  246.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  247.   *                the configuration information for NAND module.
  248.   * @retval HAL status
  249. */
  250. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  251. {
  252.   /* Check NAND interrupt Rising edge flag */
  253.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
  254.   {
  255.     /* NAND interrupt callback*/
  256.     HAL_NAND_ITCallback(hnand);
  257.  
  258.     /* Clear NAND interrupt Rising edge pending bit */
  259.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
  260.   }
  261.  
  262.   /* Check NAND interrupt Level flag */
  263.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
  264.   {
  265.     /* NAND interrupt callback*/
  266.     HAL_NAND_ITCallback(hnand);
  267.  
  268.     /* Clear NAND interrupt Level pending bit */
  269.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
  270.   }
  271.  
  272.   /* Check NAND interrupt Falling edge flag */
  273.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
  274.   {
  275.     /* NAND interrupt callback*/
  276.     HAL_NAND_ITCallback(hnand);
  277.  
  278.     /* Clear NAND interrupt Falling edge pending bit */
  279.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
  280.   }
  281.  
  282.   /* Check NAND interrupt FIFO empty flag */
  283.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
  284.   {
  285.     /* NAND interrupt callback*/
  286.     HAL_NAND_ITCallback(hnand);
  287.  
  288.     /* Clear NAND interrupt FIFO empty pending bit */
  289.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
  290.   }  
  291.  
  292. }
  293.  
  294. /**
  295.   * @brief  NAND interrupt feature callback
  296.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  297.   *                the configuration information for NAND module.
  298.   * @retval None
  299.   */
  300. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  301. {
  302.   /* NOTE : This function Should not be modified, when the callback is needed,
  303.             the HAL_NAND_ITCallback could be implemented in the user file
  304.    */
  305. }
  306.  
  307. /**
  308.   * @}
  309.   */
  310.  
  311. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  312.   * @brief    Input Output and memory control functions
  313.   *
  314.   @verbatim    
  315.   ==============================================================================
  316.                     ##### NAND Input and Output functions #####
  317.   ==============================================================================
  318.   [..]  
  319.     This section provides functions allowing to use and control the NAND
  320.     memory
  321.  
  322. @endverbatim
  323.   * @{
  324.   */
  325.  
  326. /**
  327.   * @brief  Read the NAND memory electronic signature
  328.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  329.   *                the configuration information for NAND module.
  330.   * @param  pNAND_ID: NAND ID structure
  331.   * @retval HAL status
  332.   */
  333. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  334. {
  335.   __IO uint32_t data = 0;
  336.   uint32_t deviceaddress = 0;
  337.  
  338.   /* Process Locked */
  339.   __HAL_LOCK(hnand);  
  340.  
  341.   /* Check the NAND controller state */
  342.   if(hnand->State == HAL_NAND_STATE_BUSY)
  343.   {
  344.      return HAL_BUSY;
  345.   }
  346.  
  347.   /* Identify the device address */
  348.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  349.   {
  350.     deviceaddress = NAND_DEVICE1;
  351.   }
  352.   else
  353.   {
  354.     deviceaddress = NAND_DEVICE2;
  355.   }
  356.  
  357.   /* Update the NAND controller state */
  358.   hnand->State = HAL_NAND_STATE_BUSY;
  359.  
  360.   /* Send Read ID command sequence */  
  361.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
  362.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  363.  
  364.   /* Read the electronic signature from NAND flash */  
  365.   data = *(__IO uint32_t *)deviceaddress;
  366.  
  367.   /* Return the data read */
  368.   pNAND_ID->Maker_Id   = ADDR_1st_CYCLE(data);
  369.   pNAND_ID->Device_Id  = ADDR_2nd_CYCLE(data);
  370.   pNAND_ID->Third_Id   = ADDR_3rd_CYCLE(data);
  371.   pNAND_ID->Fourth_Id  = ADDR_4th_CYCLE(data);
  372.  
  373.   /* Update the NAND controller state */
  374.   hnand->State = HAL_NAND_STATE_READY;
  375.  
  376.   /* Process unlocked */
  377.   __HAL_UNLOCK(hnand);  
  378.    
  379.   return HAL_OK;
  380. }
  381.  
  382. /**
  383.   * @brief  NAND memory reset
  384.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  385.   *                the configuration information for NAND module.
  386.   * @retval HAL status
  387.   */
  388. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  389. {
  390.   uint32_t deviceaddress = 0;
  391.  
  392.   /* Process Locked */
  393.   __HAL_LOCK(hnand);
  394.    
  395.   /* Check the NAND controller state */
  396.   if(hnand->State == HAL_NAND_STATE_BUSY)
  397.   {
  398.      return HAL_BUSY;
  399.   }
  400.  
  401.   /* Identify the device address */  
  402.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  403.   {
  404.     deviceaddress = NAND_DEVICE1;
  405.   }
  406.   else
  407.   {
  408.     deviceaddress = NAND_DEVICE2;
  409.   }  
  410.  
  411.   /* Update the NAND controller state */  
  412.   hnand->State = HAL_NAND_STATE_BUSY;
  413.  
  414.   /* Send NAND reset command */  
  415.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
  416.    
  417.  
  418.   /* Update the NAND controller state */  
  419.   hnand->State = HAL_NAND_STATE_READY;
  420.  
  421.   /* Process unlocked */
  422.   __HAL_UNLOCK(hnand);    
  423.  
  424.   return HAL_OK;
  425.  
  426. }
  427.  
  428. /**
  429.   * @brief  Read Page(s) from NAND memory block
  430.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  431.   *                the configuration information for NAND module.
  432.   * @param  pAddress : pointer to NAND address structure
  433.   * @param  pBuffer : pointer to destination read buffer
  434.   * @param  NumPageToRead : number of pages to read from block
  435.   * @retval HAL status
  436.   */
  437. HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  438. {  
  439.   __IO uint32_t index  = 0;
  440.   uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
  441.   NAND_AddressTypeDef nandaddress;
  442.   uint32_t addressoffset = 0;
  443.  
  444.   /* Process Locked */
  445.   __HAL_LOCK(hnand);
  446.  
  447.   /* Check the NAND controller state */
  448.   if(hnand->State == HAL_NAND_STATE_BUSY)
  449.   {
  450.      return HAL_BUSY;
  451.   }
  452.  
  453.   /* Identify the device address */
  454.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  455.   {
  456.     deviceaddress = NAND_DEVICE1;
  457.   }
  458.   else
  459.   {
  460.     deviceaddress = NAND_DEVICE2;
  461.   }
  462.  
  463.   /* Update the NAND controller state */
  464.   hnand->State = HAL_NAND_STATE_BUSY;
  465.  
  466.   /* Save the content of pAddress as it will be modified */
  467.   nandaddress.Block     = pAddress->Block;
  468.   nandaddress.Page      = pAddress->Page;
  469.   nandaddress.Zone      = pAddress->Zone;
  470.  
  471.   /* Page(s) read loop */  
  472.   while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))  
  473.   {    
  474.     /* update the buffer size */
  475.     size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
  476.    
  477.     /* Get the address offset */
  478.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  479.    
  480.     /* Send read page command sequence */
  481.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;  
  482.    
  483.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  484.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);
  485.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);
  486.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  487.  
  488.     /* for 512 and 1 GB devices, 4th cycle is required */    
  489.     if(hnand->Info.BlockNbr >= 1024)
  490.     {
  491.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  492.     }
  493.  
  494.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  495.      
  496.     /* Get Data into Buffer */    
  497.     for(; index < size; index++)
  498.     {
  499.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  500.     }
  501.    
  502.     /* Increment read pages number */
  503.     numpagesread++;
  504.    
  505.     /* Decrement pages to read */
  506.     NumPageToRead--;
  507.    
  508.     /* Increment the NAND address */
  509.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  510.   }
  511.  
  512.   /* Update the NAND controller state */
  513.   hnand->State = HAL_NAND_STATE_READY;
  514.  
  515.   /* Process unlocked */
  516.   __HAL_UNLOCK(hnand);  
  517.    
  518.   return HAL_OK;
  519.  
  520. }
  521.  
  522. /**
  523.   * @brief  Write Page(s) to NAND memory block
  524.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  525.   *                the configuration information for NAND module.
  526.   * @param  pAddress : pointer to NAND address structure
  527.   * @param  pBuffer : pointer to source buffer to write  
  528.   * @param  NumPageToWrite  : number of pages to write to block
  529.   * @retval HAL status
  530.   */
  531. HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  532. {
  533.   __IO uint32_t index   = 0;
  534.   uint32_t tickstart = 0;
  535.   uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
  536.   NAND_AddressTypeDef nandaddress;
  537.   uint32_t addressoffset = 0;
  538.  
  539.   /* Process Locked */
  540.   __HAL_LOCK(hnand);  
  541.  
  542.   /* Check the NAND controller state */
  543.   if(hnand->State == HAL_NAND_STATE_BUSY)
  544.   {
  545.      return HAL_BUSY;
  546.   }
  547.  
  548.   /* Identify the device address */
  549.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  550.   {
  551.     deviceaddress = NAND_DEVICE1;
  552.   }
  553.   else
  554.   {
  555.     deviceaddress = NAND_DEVICE2;
  556.   }
  557.  
  558.   /* Update the NAND controller state */
  559.   hnand->State = HAL_NAND_STATE_BUSY;
  560.  
  561.   /* Save the content of pAddress as it will be modified */
  562.   nandaddress.Block     = pAddress->Block;
  563.   nandaddress.Page      = pAddress->Page;
  564.   nandaddress.Zone      = pAddress->Zone;
  565.    
  566.   /* Page(s) write loop */
  567.   while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  568.   {  
  569.     /* update the buffer size */
  570.     size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
  571.    
  572.     /* Get the address offset */
  573.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  574.    
  575.     /* Send write page command sequence */
  576.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  577.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  578.  
  579.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;  
  580.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);  
  581.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);  
  582.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  583.  
  584.     /* for 512 and 1 GB devices, 4th cycle is required */    
  585.     if(hnand->Info.BlockNbr >= 1024)
  586.     {
  587.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  588.     }
  589.  
  590.     /* Write data to memory */
  591.     for(; index < size; index++)
  592.     {
  593.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  594.     }
  595.    
  596.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  597.    
  598.     /* Get tick */
  599.     tickstart = HAL_GetTick();
  600.    
  601.     /* Read status until NAND is ready */
  602.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  603.     {
  604.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  605.       {
  606.         return HAL_TIMEOUT;
  607.       }
  608.     }    
  609.  
  610.     /* Increment written pages number */
  611.     numpageswritten++;
  612.    
  613.     /* Decrement pages to write */
  614.     NumPageToWrite--;
  615.    
  616.     /* Increment the NAND address */
  617.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  618.   }
  619.  
  620.   /* Update the NAND controller state */
  621.   hnand->State = HAL_NAND_STATE_READY;
  622.  
  623.   /* Process unlocked */
  624.   __HAL_UNLOCK(hnand);      
  625.  
  626.   return HAL_OK;
  627. }
  628.  
  629. /**
  630.   * @brief  Read Spare area(s) from NAND memory
  631.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  632.   *                the configuration information for NAND module.
  633.   * @param  pAddress : pointer to NAND address structure
  634.   * @param  pBuffer: pointer to source buffer to write  
  635.   * @param  NumSpareAreaToRead: Number of spare area to read  
  636.   * @retval HAL status
  637. */
  638. HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  639. {
  640.   __IO uint32_t index   = 0;
  641.   uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
  642.   NAND_AddressTypeDef nandaddress;
  643.   uint32_t addressoffset = 0;
  644.  
  645.   /* Process Locked */
  646.   __HAL_LOCK(hnand);  
  647.  
  648.   /* Check the NAND controller state */
  649.   if(hnand->State == HAL_NAND_STATE_BUSY)
  650.   {
  651.      return HAL_BUSY;
  652.   }
  653.  
  654.   /* Identify the device address */
  655.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  656.   {
  657.     deviceaddress = NAND_DEVICE1;
  658.   }
  659.   else
  660.   {
  661.     deviceaddress = NAND_DEVICE2;
  662.   }
  663.  
  664.   /* Update the NAND controller state */
  665.   hnand->State = HAL_NAND_STATE_BUSY;
  666.  
  667.   /* Save the content of pAddress as it will be modified */
  668.   nandaddress.Block     = pAddress->Block;
  669.   nandaddress.Page      = pAddress->Page;
  670.   nandaddress.Zone      = pAddress->Zone;
  671.  
  672.   /* Spare area(s) read loop */
  673.   while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
  674.   {    
  675.     /* update the buffer size */
  676.     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);  
  677.  
  678.     /* Get the address offset */
  679.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  680.    
  681.     /* Send read spare area command sequence */    
  682.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  683.  
  684.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  685.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);    
  686.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);    
  687.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  688.  
  689.     /* for 512 and 1 GB devices, 4th cycle is required */    
  690.     if(hnand->Info.BlockNbr >= 1024)
  691.     {
  692.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  693.     }
  694.  
  695.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;    
  696.    
  697.     /* Get Data into Buffer */
  698.     for ( ;index < size; index++)
  699.     {
  700.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  701.     }
  702.    
  703.     /* Increment read spare areas number */
  704.     num_spare_area_read++;
  705.    
  706.     /* Decrement spare areas to read */
  707.     NumSpareAreaToRead--;
  708.    
  709.     /* Increment the NAND address */
  710.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  711.   }
  712.  
  713.   /* Update the NAND controller state */
  714.   hnand->State = HAL_NAND_STATE_READY;
  715.  
  716.   /* Process unlocked */
  717.   __HAL_UNLOCK(hnand);    
  718.  
  719.   return HAL_OK;  
  720. }
  721.  
  722. /**
  723.   * @brief  Write Spare area(s) to NAND memory
  724.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  725.   *                the configuration information for NAND module.
  726.   * @param  pAddress : pointer to NAND address structure
  727.   * @param  pBuffer : pointer to source buffer to write  
  728.   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
  729.   * @retval HAL status
  730.   */
  731. HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  732. {
  733.   __IO uint32_t index = 0;
  734.   uint32_t tickstart = 0;
  735.   uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
  736.   NAND_AddressTypeDef nandaddress;
  737.   uint32_t addressoffset = 0;
  738.  
  739.   /* Process Locked */
  740.   __HAL_LOCK(hnand);
  741.  
  742.   /* Check the NAND controller state */
  743.   if(hnand->State == HAL_NAND_STATE_BUSY)
  744.   {
  745.      return HAL_BUSY;
  746.   }
  747.  
  748.   /* Identify the device address */
  749.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  750.   {
  751.     deviceaddress = NAND_DEVICE1;
  752.   }
  753.   else
  754.   {
  755.     deviceaddress = NAND_DEVICE2;
  756.   }
  757.  
  758.   /* Update the FSMC_NAND controller state */
  759.   hnand->State = HAL_NAND_STATE_BUSY;  
  760.  
  761.   /* Save the content of pAddress as it will be modified */
  762.   nandaddress.Block     = pAddress->Block;
  763.   nandaddress.Page      = pAddress->Page;
  764.   nandaddress.Zone      = pAddress->Zone;
  765.  
  766.   /* Spare area(s) write loop */
  767.   while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  768.   {  
  769.     /* update the buffer size */
  770.     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
  771.  
  772.     /* Get the address offset */
  773.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  774.    
  775.     /* Send write Spare area command sequence */
  776.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  777.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  778.  
  779.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;  
  780.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);  
  781.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);  
  782.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  783.  
  784.     /* for 512 and 1 GB devices, 4th cycle is required */    
  785.     if(hnand->Info.BlockNbr >= 1024)
  786.     {
  787.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  788.     }
  789.  
  790.     /* Write data to memory */
  791.     for(; index < size; index++)
  792.     {
  793.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  794.     }
  795.    
  796.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  797.    
  798.     /* Get tick */
  799.     tickstart = HAL_GetTick();
  800.    
  801.     /* Read status until NAND is ready */
  802.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  803.     {
  804.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  805.       {
  806.         return HAL_TIMEOUT;
  807.       }
  808.     }
  809.  
  810.     /* Increment written spare areas number */
  811.     num_spare_area_written++;
  812.    
  813.     /* Decrement spare areas to write */
  814.     NumSpareAreaTowrite--;
  815.    
  816.     /* Increment the NAND address */
  817.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  818.   }
  819.  
  820.   /* Update the NAND controller state */
  821.   hnand->State = HAL_NAND_STATE_READY;
  822.  
  823.   /* Process unlocked */
  824.   __HAL_UNLOCK(hnand);
  825.    
  826.   return HAL_OK;  
  827. }
  828.  
  829. /**
  830.   * @brief  NAND memory Block erase
  831.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  832.   *                the configuration information for NAND module.
  833.   * @param  pAddress : pointer to NAND address structure
  834.   * @retval HAL status
  835.   */
  836. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  837. {
  838.   uint32_t deviceaddress = 0;
  839.   uint32_t tickstart = 0;
  840.  
  841.   /* Process Locked */
  842.   __HAL_LOCK(hnand);
  843.  
  844.   /* Check the NAND controller state */
  845.   if(hnand->State == HAL_NAND_STATE_BUSY)
  846.   {
  847.      return HAL_BUSY;
  848.   }
  849.  
  850.   /* Identify the device address */
  851.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  852.   {
  853.     deviceaddress = NAND_DEVICE1;
  854.   }
  855.   else
  856.   {
  857.     deviceaddress = NAND_DEVICE2;
  858.   }
  859.  
  860.   /* Update the NAND controller state */
  861.   hnand->State = HAL_NAND_STATE_BUSY;  
  862.  
  863.   /* Send Erase block command sequence */
  864.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
  865.  
  866.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  867.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  868.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  869.  
  870.   /* for 512 and 1 GB devices, 4th cycle is required */    
  871.   if(hnand->Info.BlockNbr >= 1024)
  872.   {
  873.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  874.   }  
  875.    
  876.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
  877.  
  878.   /* Update the NAND controller state */
  879.   hnand->State = HAL_NAND_STATE_READY;
  880.  
  881.   /* Get tick */
  882.   tickstart = HAL_GetTick();
  883.  
  884.   /* Read status until NAND is ready */
  885.   while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  886.   {
  887.     if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  888.     {
  889.       /* Process unlocked */
  890.       __HAL_UNLOCK(hnand);    
  891.  
  892.       return HAL_TIMEOUT;
  893.     }
  894.   }    
  895.  
  896.   /* Process unlocked */
  897.   __HAL_UNLOCK(hnand);    
  898.  
  899.   return HAL_OK;  
  900. }
  901.  
  902. /**
  903.   * @brief  NAND memory read status
  904.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  905.   *                the configuration information for NAND module.
  906.   * @retval NAND status
  907.   */
  908. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  909. {
  910.   uint32_t data = 0;
  911.   uint32_t deviceaddress = 0;
  912.  
  913.   /* Identify the device address */
  914.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  915.   {
  916.     deviceaddress = NAND_DEVICE1;
  917.   }
  918.   else
  919.   {
  920.     deviceaddress = NAND_DEVICE2;
  921.   }
  922.  
  923.   /* Send Read status operation command */
  924.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
  925.  
  926.   /* Read status register data */
  927.   data = *(__IO uint8_t *)deviceaddress;
  928.  
  929.   /* Return the status */
  930.   if((data & NAND_ERROR) == NAND_ERROR)
  931.   {
  932.     return NAND_ERROR;
  933.   }
  934.   else if((data & NAND_READY) == NAND_READY)
  935.   {
  936.     return NAND_READY;
  937.   }
  938.  
  939.   return NAND_BUSY;
  940. }
  941.  
  942. /**
  943.   * @brief  Increment the NAND memory address
  944.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  945.   *                the configuration information for NAND module.
  946.   * @param pAddress: pointer to NAND address structure
  947.   * @retval The new status of the increment address operation. It can be:
  948.   *           - NAND_VALID_ADDRESS: When the new address is valid address
  949.   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
  950.   */
  951. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  952. {
  953.   uint32_t status = NAND_VALID_ADDRESS;
  954.  
  955.   /* Increment page address */
  956.   pAddress->Page++;
  957.  
  958.   /* Check NAND address is valid */
  959.   if(pAddress->Page == hnand->Info.BlockSize)
  960.   {
  961.     pAddress->Page = 0;
  962.     pAddress->Block++;
  963.    
  964.     if(pAddress->Block == hnand->Info.ZoneSize)
  965.     {
  966.       pAddress->Block = 0;
  967.       pAddress->Zone++;
  968.  
  969.       if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
  970.       {
  971.         status = NAND_INVALID_ADDRESS;
  972.       }
  973.     }
  974.   }
  975.  
  976.   return (status);
  977. }
  978. /**
  979.   * @}
  980.   */
  981.  
  982. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  983.  *  @brief   management functions
  984.  *
  985. @verbatim  
  986.   ==============================================================================
  987.                          ##### NAND Control functions #####
  988.   ==============================================================================  
  989.   [..]
  990.     This subsection provides a set of functions allowing to control dynamically
  991.     the NAND interface.
  992.  
  993. @endverbatim
  994.   * @{
  995.   */
  996.  
  997.    
  998. /**
  999.   * @brief  Enables dynamically NAND ECC feature.
  1000.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1001.   *                the configuration information for NAND module.
  1002.   * @retval HAL status
  1003.   */    
  1004. HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  1005. {
  1006.   /* Check the NAND controller state */
  1007.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1008.   {
  1009.      return HAL_BUSY;
  1010.   }
  1011.  
  1012.   /* Update the NAND state */
  1013.   hnand->State = HAL_NAND_STATE_BUSY;
  1014.    
  1015.   /* Enable ECC feature */
  1016.   FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  1017.  
  1018.   /* Update the NAND state */
  1019.   hnand->State = HAL_NAND_STATE_READY;
  1020.  
  1021.   return HAL_OK;  
  1022. }
  1023.  
  1024. /**
  1025.   * @brief  Disables dynamically FSMC_NAND ECC feature.
  1026.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1027.   *                the configuration information for NAND module.
  1028.   * @retval HAL status
  1029.   */  
  1030. HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)  
  1031. {
  1032.   /* Check the NAND controller state */
  1033.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1034.   {
  1035.      return HAL_BUSY;
  1036.   }
  1037.  
  1038.   /* Update the NAND state */
  1039.   hnand->State = HAL_NAND_STATE_BUSY;
  1040.    
  1041.   /* Disable ECC feature */
  1042.   FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  1043.  
  1044.   /* Update the NAND state */
  1045.   hnand->State = HAL_NAND_STATE_READY;
  1046.  
  1047.   return HAL_OK;  
  1048. }
  1049.  
  1050. /**
  1051.   * @brief  Disables dynamically NAND ECC feature.
  1052.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1053.   *                the configuration information for NAND module.
  1054.   * @param  ECCval: pointer to ECC value
  1055.   * @param  Timeout: maximum timeout to wait    
  1056.   * @retval HAL status
  1057.   */
  1058. HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  1059. {
  1060.   HAL_StatusTypeDef status = HAL_OK;
  1061.  
  1062.   /* Check the NAND controller state */
  1063.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1064.   {
  1065.      return HAL_BUSY;
  1066.   }
  1067.  
  1068.   /* Update the NAND state */
  1069.   hnand->State = HAL_NAND_STATE_BUSY;  
  1070.    
  1071.   /* Get NAND ECC value */
  1072.   status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  1073.  
  1074.   /* Update the NAND state */
  1075.   hnand->State = HAL_NAND_STATE_READY;
  1076.  
  1077.   return status;  
  1078. }
  1079.                      
  1080. /**
  1081.   * @}
  1082.   */
  1083.  
  1084.    
  1085. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  1086.  *  @brief   Peripheral State functions
  1087.  *
  1088. @verbatim  
  1089.   ==============================================================================
  1090.                          ##### NAND State functions #####
  1091.   ==============================================================================  
  1092.   [..]
  1093.     This subsection permits to get in run-time the status of the NAND controller
  1094.     and the data flow.
  1095.  
  1096. @endverbatim
  1097.   * @{
  1098.   */
  1099.  
  1100. /**
  1101.   * @brief  return the NAND state
  1102.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1103.   *                the configuration information for NAND module.
  1104.   * @retval HAL state
  1105.   */
  1106. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  1107. {
  1108.   return hnand->State;
  1109. }
  1110.  
  1111. /**
  1112.   * @}
  1113.   */  
  1114.  
  1115. /**
  1116.   * @}
  1117.   */
  1118.  
  1119. /** @addtogroup NAND_Private_Functions
  1120.   * @{
  1121.   */
  1122.  
  1123. /**
  1124.   * @brief  Increment the NAND memory address.
  1125.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1126.   *                the configuration information for NAND module.
  1127.   * @param  Address: address to be incremented.
  1128.   * @retval The new status of the increment address operation. It can be:
  1129.   *              - NAND_VALID_ADDRESS: When the new address is valid address
  1130.   *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
  1131.   */
  1132. static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address)
  1133. {
  1134.   uint32_t status = NAND_VALID_ADDRESS;
  1135.  
  1136.   Address->Page++;
  1137.  
  1138.   if(Address->Page == hnand->Info.BlockSize)
  1139.   {
  1140.     Address->Page = 0;
  1141.     Address->Block++;
  1142.    
  1143.     if(Address->Block == hnand->Info.ZoneSize)
  1144.     {
  1145.       Address->Block = 0;
  1146.       Address->Zone++;
  1147.  
  1148.       if(Address->Zone == hnand->Info.BlockNbr)
  1149.       {
  1150.         status = NAND_INVALID_ADDRESS;
  1151.       }
  1152.     }
  1153.   }
  1154.  
  1155.   return (status);
  1156. }
  1157.  
  1158. /**
  1159.   * @}
  1160.   */
  1161.  
  1162. /**
  1163.   * @}
  1164.   */
  1165.  
  1166. #endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
  1167. #endif /* HAL_NAND_MODULE_ENABLED  */
  1168.  
  1169. /**
  1170.   * @}
  1171.   */
  1172.  
  1173. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1174.