Subversion Repositories DashDisplay

Rev

Rev 2 | 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.4
  6.   * @date    29-April-2016
  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) 2016 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.   /* Prevent unused argument(s) compilation warning */
  226.   UNUSED(hnand);
  227.   /* NOTE : This function Should not be modified, when the callback is needed,
  228.             the HAL_NAND_MspInit could be implemented in the user file
  229.    */
  230. }
  231.  
  232. /**
  233.   * @brief  NAND MSP DeInit
  234.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  235.   *                the configuration information for NAND module.
  236.   * @retval None
  237.   */
  238. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  239. {
  240.   /* Prevent unused argument(s) compilation warning */
  241.   UNUSED(hnand);
  242.   /* NOTE : This function Should not be modified, when the callback is needed,
  243.             the HAL_NAND_MspDeInit could be implemented in the user file
  244.    */
  245. }
  246.  
  247.  
  248. /**
  249.   * @brief  This function handles NAND device interrupt request.
  250.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  251.   *                the configuration information for NAND module.
  252.   * @retval HAL status
  253. */
  254. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  255. {
  256.   /* Check NAND interrupt Rising edge flag */
  257.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
  258.   {
  259.     /* NAND interrupt callback*/
  260.     HAL_NAND_ITCallback(hnand);
  261.  
  262.     /* Clear NAND interrupt Rising edge pending bit */
  263.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
  264.   }
  265.  
  266.   /* Check NAND interrupt Level flag */
  267.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
  268.   {
  269.     /* NAND interrupt callback*/
  270.     HAL_NAND_ITCallback(hnand);
  271.  
  272.     /* Clear NAND interrupt Level pending bit */
  273.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
  274.   }
  275.  
  276.   /* Check NAND interrupt Falling edge flag */
  277.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
  278.   {
  279.     /* NAND interrupt callback*/
  280.     HAL_NAND_ITCallback(hnand);
  281.  
  282.     /* Clear NAND interrupt Falling edge pending bit */
  283.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
  284.   }
  285.  
  286.   /* Check NAND interrupt FIFO empty flag */
  287.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
  288.   {
  289.     /* NAND interrupt callback*/
  290.     HAL_NAND_ITCallback(hnand);
  291.  
  292.     /* Clear NAND interrupt FIFO empty pending bit */
  293.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
  294.   }  
  295.  
  296. }
  297.  
  298. /**
  299.   * @brief  NAND interrupt feature callback
  300.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  301.   *                the configuration information for NAND module.
  302.   * @retval None
  303.   */
  304. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  305. {
  306.   /* Prevent unused argument(s) compilation warning */
  307.   UNUSED(hnand);
  308.   /* NOTE : This function Should not be modified, when the callback is needed,
  309.             the HAL_NAND_ITCallback could be implemented in the user file
  310.    */
  311. }
  312.  
  313. /**
  314.   * @}
  315.   */
  316.  
  317. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  318.   * @brief    Input Output and memory control functions
  319.   *
  320.   @verbatim    
  321.   ==============================================================================
  322.                     ##### NAND Input and Output functions #####
  323.   ==============================================================================
  324.   [..]  
  325.     This section provides functions allowing to use and control the NAND
  326.     memory
  327.  
  328. @endverbatim
  329.   * @{
  330.   */
  331.  
  332. /**
  333.   * @brief  Read the NAND memory electronic signature
  334.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  335.   *                the configuration information for NAND module.
  336.   * @param  pNAND_ID: NAND ID structure
  337.   * @retval HAL status
  338.   */
  339. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  340. {
  341.   __IO uint32_t data = 0;
  342.   uint32_t deviceaddress = 0;
  343.  
  344.   /* Process Locked */
  345.   __HAL_LOCK(hnand);  
  346.  
  347.   /* Check the NAND controller state */
  348.   if(hnand->State == HAL_NAND_STATE_BUSY)
  349.   {
  350.      return HAL_BUSY;
  351.   }
  352.  
  353.   /* Identify the device address */
  354.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  355.   {
  356.     deviceaddress = NAND_DEVICE1;
  357.   }
  358.   else
  359.   {
  360.     deviceaddress = NAND_DEVICE2;
  361.   }
  362.  
  363.   /* Update the NAND controller state */
  364.   hnand->State = HAL_NAND_STATE_BUSY;
  365.  
  366.   /* Send Read ID command sequence */  
  367.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
  368.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  369.  
  370.   /* Read the electronic signature from NAND flash */  
  371.   data = *(__IO uint32_t *)deviceaddress;
  372.  
  373.   /* Return the data read */
  374.   pNAND_ID->Maker_Id   = ADDR_1st_CYCLE(data);
  375.   pNAND_ID->Device_Id  = ADDR_2nd_CYCLE(data);
  376.   pNAND_ID->Third_Id   = ADDR_3rd_CYCLE(data);
  377.   pNAND_ID->Fourth_Id  = ADDR_4th_CYCLE(data);
  378.  
  379.   /* Update the NAND controller state */
  380.   hnand->State = HAL_NAND_STATE_READY;
  381.  
  382.   /* Process unlocked */
  383.   __HAL_UNLOCK(hnand);  
  384.    
  385.   return HAL_OK;
  386. }
  387.  
  388. /**
  389.   * @brief  NAND memory reset
  390.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  391.   *                the configuration information for NAND module.
  392.   * @retval HAL status
  393.   */
  394. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  395. {
  396.   uint32_t deviceaddress = 0;
  397.  
  398.   /* Process Locked */
  399.   __HAL_LOCK(hnand);
  400.    
  401.   /* Check the NAND controller state */
  402.   if(hnand->State == HAL_NAND_STATE_BUSY)
  403.   {
  404.      return HAL_BUSY;
  405.   }
  406.  
  407.   /* Identify the device address */  
  408.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  409.   {
  410.     deviceaddress = NAND_DEVICE1;
  411.   }
  412.   else
  413.   {
  414.     deviceaddress = NAND_DEVICE2;
  415.   }  
  416.  
  417.   /* Update the NAND controller state */  
  418.   hnand->State = HAL_NAND_STATE_BUSY;
  419.  
  420.   /* Send NAND reset command */  
  421.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
  422.    
  423.  
  424.   /* Update the NAND controller state */  
  425.   hnand->State = HAL_NAND_STATE_READY;
  426.  
  427.   /* Process unlocked */
  428.   __HAL_UNLOCK(hnand);    
  429.  
  430.   return HAL_OK;
  431.  
  432. }
  433.  
  434. /**
  435.   * @brief  Read Page(s) from NAND memory block
  436.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  437.   *                the configuration information for NAND module.
  438.   * @param  pAddress : pointer to NAND address structure
  439.   * @param  pBuffer : pointer to destination read buffer
  440.   * @param  NumPageToRead : number of pages to read from block
  441.   * @retval HAL status
  442.   */
  443. HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  444. {  
  445.   __IO uint32_t index  = 0;
  446.   uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
  447.   NAND_AddressTypeDef nandaddress;
  448.   uint32_t addressoffset = 0;
  449.  
  450.   /* Process Locked */
  451.   __HAL_LOCK(hnand);
  452.  
  453.   /* Check the NAND controller state */
  454.   if(hnand->State == HAL_NAND_STATE_BUSY)
  455.   {
  456.      return HAL_BUSY;
  457.   }
  458.  
  459.   /* Identify the device address */
  460.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  461.   {
  462.     deviceaddress = NAND_DEVICE1;
  463.   }
  464.   else
  465.   {
  466.     deviceaddress = NAND_DEVICE2;
  467.   }
  468.  
  469.   /* Update the NAND controller state */
  470.   hnand->State = HAL_NAND_STATE_BUSY;
  471.  
  472.   /* Save the content of pAddress as it will be modified */
  473.   nandaddress.Block     = pAddress->Block;
  474.   nandaddress.Page      = pAddress->Page;
  475.   nandaddress.Zone      = pAddress->Zone;
  476.  
  477.   /* Page(s) read loop */  
  478.   while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))  
  479.   {    
  480.     /* update the buffer size */
  481.     size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
  482.    
  483.     /* Get the address offset */
  484.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  485.    
  486.     /* Send read page command sequence */
  487.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;  
  488.    
  489.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  490.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);
  491.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);
  492.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  493.  
  494.     /* for 512 and 1 GB devices, 4th cycle is required */    
  495.     if(hnand->Info.BlockNbr >= 1024)
  496.     {
  497.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  498.     }
  499.  
  500.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  501.      
  502.     /* Get Data into Buffer */    
  503.     for(; index < size; index++)
  504.     {
  505.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  506.     }
  507.    
  508.     /* Increment read pages number */
  509.     numpagesread++;
  510.    
  511.     /* Decrement pages to read */
  512.     NumPageToRead--;
  513.    
  514.     /* Increment the NAND address */
  515.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  516.   }
  517.  
  518.   /* Update the NAND controller state */
  519.   hnand->State = HAL_NAND_STATE_READY;
  520.  
  521.   /* Process unlocked */
  522.   __HAL_UNLOCK(hnand);  
  523.    
  524.   return HAL_OK;
  525.  
  526. }
  527.  
  528. /**
  529.   * @brief  Write Page(s) to NAND memory block
  530.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  531.   *                the configuration information for NAND module.
  532.   * @param  pAddress : pointer to NAND address structure
  533.   * @param  pBuffer : pointer to source buffer to write  
  534.   * @param  NumPageToWrite  : number of pages to write to block
  535.   * @retval HAL status
  536.   */
  537. HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  538. {
  539.   __IO uint32_t index   = 0;
  540.   uint32_t tickstart = 0;
  541.   uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
  542.   NAND_AddressTypeDef nandaddress;
  543.   uint32_t addressoffset = 0;
  544.  
  545.   /* Process Locked */
  546.   __HAL_LOCK(hnand);  
  547.  
  548.   /* Check the NAND controller state */
  549.   if(hnand->State == HAL_NAND_STATE_BUSY)
  550.   {
  551.      return HAL_BUSY;
  552.   }
  553.  
  554.   /* Identify the device address */
  555.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  556.   {
  557.     deviceaddress = NAND_DEVICE1;
  558.   }
  559.   else
  560.   {
  561.     deviceaddress = NAND_DEVICE2;
  562.   }
  563.  
  564.   /* Update the NAND controller state */
  565.   hnand->State = HAL_NAND_STATE_BUSY;
  566.  
  567.   /* Save the content of pAddress as it will be modified */
  568.   nandaddress.Block     = pAddress->Block;
  569.   nandaddress.Page      = pAddress->Page;
  570.   nandaddress.Zone      = pAddress->Zone;
  571.    
  572.   /* Page(s) write loop */
  573.   while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  574.   {  
  575.     /* update the buffer size */
  576.     size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
  577.    
  578.     /* Get the address offset */
  579.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  580.    
  581.     /* Send write page command sequence */
  582.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  583.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  584.  
  585.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;  
  586.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);  
  587.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);  
  588.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  589.  
  590.     /* for 512 and 1 GB devices, 4th cycle is required */    
  591.     if(hnand->Info.BlockNbr >= 1024)
  592.     {
  593.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  594.     }
  595.  
  596.     /* Write data to memory */
  597.     for(; index < size; index++)
  598.     {
  599.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  600.     }
  601.    
  602.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  603.    
  604.     /* Get tick */
  605.     tickstart = HAL_GetTick();
  606.    
  607.     /* Read status until NAND is ready */
  608.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  609.     {
  610.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  611.       {
  612.         return HAL_TIMEOUT;
  613.       }
  614.     }    
  615.  
  616.     /* Increment written pages number */
  617.     numpageswritten++;
  618.    
  619.     /* Decrement pages to write */
  620.     NumPageToWrite--;
  621.    
  622.     /* Increment the NAND address */
  623.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  624.   }
  625.  
  626.   /* Update the NAND controller state */
  627.   hnand->State = HAL_NAND_STATE_READY;
  628.  
  629.   /* Process unlocked */
  630.   __HAL_UNLOCK(hnand);      
  631.  
  632.   return HAL_OK;
  633. }
  634.  
  635. /**
  636.   * @brief  Read Spare area(s) from NAND memory
  637.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  638.   *                the configuration information for NAND module.
  639.   * @param  pAddress : pointer to NAND address structure
  640.   * @param  pBuffer: pointer to source buffer to write  
  641.   * @param  NumSpareAreaToRead: Number of spare area to read  
  642.   * @retval HAL status
  643. */
  644. HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  645. {
  646.   __IO uint32_t index   = 0;
  647.   uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
  648.   NAND_AddressTypeDef nandaddress;
  649.   uint32_t addressoffset = 0;
  650.  
  651.   /* Process Locked */
  652.   __HAL_LOCK(hnand);  
  653.  
  654.   /* Check the NAND controller state */
  655.   if(hnand->State == HAL_NAND_STATE_BUSY)
  656.   {
  657.      return HAL_BUSY;
  658.   }
  659.  
  660.   /* Identify the device address */
  661.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  662.   {
  663.     deviceaddress = NAND_DEVICE1;
  664.   }
  665.   else
  666.   {
  667.     deviceaddress = NAND_DEVICE2;
  668.   }
  669.  
  670.   /* Update the NAND controller state */
  671.   hnand->State = HAL_NAND_STATE_BUSY;
  672.  
  673.   /* Save the content of pAddress as it will be modified */
  674.   nandaddress.Block     = pAddress->Block;
  675.   nandaddress.Page      = pAddress->Page;
  676.   nandaddress.Zone      = pAddress->Zone;
  677.  
  678.   /* Spare area(s) read loop */
  679.   while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
  680.   {    
  681.     /* update the buffer size */
  682.     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);  
  683.  
  684.     /* Get the address offset */
  685.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  686.    
  687.     /* Send read spare area command sequence */    
  688.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  689.  
  690.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  691.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);    
  692.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);    
  693.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  694.  
  695.     /* for 512 and 1 GB devices, 4th cycle is required */    
  696.     if(hnand->Info.BlockNbr >= 1024)
  697.     {
  698.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  699.     }
  700.  
  701.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;    
  702.    
  703.     /* Get Data into Buffer */
  704.     for ( ;index < size; index++)
  705.     {
  706.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  707.     }
  708.    
  709.     /* Increment read spare areas number */
  710.     num_spare_area_read++;
  711.    
  712.     /* Decrement spare areas to read */
  713.     NumSpareAreaToRead--;
  714.    
  715.     /* Increment the NAND address */
  716.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  717.   }
  718.  
  719.   /* Update the NAND controller state */
  720.   hnand->State = HAL_NAND_STATE_READY;
  721.  
  722.   /* Process unlocked */
  723.   __HAL_UNLOCK(hnand);    
  724.  
  725.   return HAL_OK;  
  726. }
  727.  
  728. /**
  729.   * @brief  Write Spare area(s) to NAND memory
  730.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  731.   *                the configuration information for NAND module.
  732.   * @param  pAddress : pointer to NAND address structure
  733.   * @param  pBuffer : pointer to source buffer to write  
  734.   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
  735.   * @retval HAL status
  736.   */
  737. HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  738. {
  739.   __IO uint32_t index = 0;
  740.   uint32_t tickstart = 0;
  741.   uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
  742.   NAND_AddressTypeDef nandaddress;
  743.   uint32_t addressoffset = 0;
  744.  
  745.   /* Process Locked */
  746.   __HAL_LOCK(hnand);
  747.  
  748.   /* Check the NAND controller state */
  749.   if(hnand->State == HAL_NAND_STATE_BUSY)
  750.   {
  751.      return HAL_BUSY;
  752.   }
  753.  
  754.   /* Identify the device address */
  755.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  756.   {
  757.     deviceaddress = NAND_DEVICE1;
  758.   }
  759.   else
  760.   {
  761.     deviceaddress = NAND_DEVICE2;
  762.   }
  763.  
  764.   /* Update the FSMC_NAND controller state */
  765.   hnand->State = HAL_NAND_STATE_BUSY;  
  766.  
  767.   /* Save the content of pAddress as it will be modified */
  768.   nandaddress.Block     = pAddress->Block;
  769.   nandaddress.Page      = pAddress->Page;
  770.   nandaddress.Zone      = pAddress->Zone;
  771.  
  772.   /* Spare area(s) write loop */
  773.   while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  774.   {  
  775.     /* update the buffer size */
  776.     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
  777.  
  778.     /* Get the address offset */
  779.     addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  780.    
  781.     /* Send write Spare area command sequence */
  782.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  783.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  784.  
  785.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;  
  786.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(addressoffset);  
  787.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(addressoffset);  
  788.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(addressoffset);
  789.  
  790.     /* for 512 and 1 GB devices, 4th cycle is required */    
  791.     if(hnand->Info.BlockNbr >= 1024)
  792.     {
  793.       *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(addressoffset);
  794.     }
  795.  
  796.     /* Write data to memory */
  797.     for(; index < size; index++)
  798.     {
  799.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  800.     }
  801.    
  802.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  803.    
  804.     /* Get tick */
  805.     tickstart = HAL_GetTick();
  806.    
  807.     /* Read status until NAND is ready */
  808.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  809.     {
  810.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  811.       {
  812.         return HAL_TIMEOUT;
  813.       }
  814.     }
  815.  
  816.     /* Increment written spare areas number */
  817.     num_spare_area_written++;
  818.    
  819.     /* Decrement spare areas to write */
  820.     NumSpareAreaTowrite--;
  821.    
  822.     /* Increment the NAND address */
  823.     addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
  824.   }
  825.  
  826.   /* Update the NAND controller state */
  827.   hnand->State = HAL_NAND_STATE_READY;
  828.  
  829.   /* Process unlocked */
  830.   __HAL_UNLOCK(hnand);
  831.    
  832.   return HAL_OK;  
  833. }
  834.  
  835. /**
  836.   * @brief  NAND memory Block erase
  837.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  838.   *                the configuration information for NAND module.
  839.   * @param  pAddress : pointer to NAND address structure
  840.   * @retval HAL status
  841.   */
  842. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  843. {
  844.   uint32_t deviceaddress = 0;
  845.   uint32_t tickstart = 0;
  846.  
  847.   /* Process Locked */
  848.   __HAL_LOCK(hnand);
  849.  
  850.   /* Check the NAND controller state */
  851.   if(hnand->State == HAL_NAND_STATE_BUSY)
  852.   {
  853.      return HAL_BUSY;
  854.   }
  855.  
  856.   /* Identify the device address */
  857.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  858.   {
  859.     deviceaddress = NAND_DEVICE1;
  860.   }
  861.   else
  862.   {
  863.     deviceaddress = NAND_DEVICE2;
  864.   }
  865.  
  866.   /* Update the NAND controller state */
  867.   hnand->State = HAL_NAND_STATE_BUSY;  
  868.  
  869.   /* Send Erase block command sequence */
  870.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
  871.  
  872.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1st_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  873.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2nd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  874.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3rd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  875.  
  876.   /* for 512 and 1 GB devices, 4th cycle is required */    
  877.   if(hnand->Info.BlockNbr >= 1024)
  878.   {
  879.     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4th_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  880.   }  
  881.    
  882.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
  883.  
  884.   /* Update the NAND controller state */
  885.   hnand->State = HAL_NAND_STATE_READY;
  886.  
  887.   /* Get tick */
  888.   tickstart = HAL_GetTick();
  889.  
  890.   /* Read status until NAND is ready */
  891.   while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  892.   {
  893.     if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  894.     {
  895.       /* Process unlocked */
  896.       __HAL_UNLOCK(hnand);    
  897.  
  898.       return HAL_TIMEOUT;
  899.     }
  900.   }    
  901.  
  902.   /* Process unlocked */
  903.   __HAL_UNLOCK(hnand);    
  904.  
  905.   return HAL_OK;  
  906. }
  907.  
  908. /**
  909.   * @brief  NAND memory read status
  910.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  911.   *                the configuration information for NAND module.
  912.   * @retval NAND status
  913.   */
  914. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  915. {
  916.   uint32_t data = 0;
  917.   uint32_t deviceaddress = 0;
  918.  
  919.   /* Identify the device address */
  920.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  921.   {
  922.     deviceaddress = NAND_DEVICE1;
  923.   }
  924.   else
  925.   {
  926.     deviceaddress = NAND_DEVICE2;
  927.   }
  928.  
  929.   /* Send Read status operation command */
  930.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
  931.  
  932.   /* Read status register data */
  933.   data = *(__IO uint8_t *)deviceaddress;
  934.  
  935.   /* Return the status */
  936.   if((data & NAND_ERROR) == NAND_ERROR)
  937.   {
  938.     return NAND_ERROR;
  939.   }
  940.   else if((data & NAND_READY) == NAND_READY)
  941.   {
  942.     return NAND_READY;
  943.   }
  944.  
  945.   return NAND_BUSY;
  946. }
  947.  
  948. /**
  949.   * @brief  Increment the NAND memory address
  950.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  951.   *                the configuration information for NAND module.
  952.   * @param pAddress: pointer to NAND address structure
  953.   * @retval The new status of the increment address operation. It can be:
  954.   *           - NAND_VALID_ADDRESS: When the new address is valid address
  955.   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
  956.   */
  957. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  958. {
  959.   uint32_t status = NAND_VALID_ADDRESS;
  960.  
  961.   /* Increment page address */
  962.   pAddress->Page++;
  963.  
  964.   /* Check NAND address is valid */
  965.   if(pAddress->Page == hnand->Info.BlockSize)
  966.   {
  967.     pAddress->Page = 0;
  968.     pAddress->Block++;
  969.    
  970.     if(pAddress->Block == hnand->Info.ZoneSize)
  971.     {
  972.       pAddress->Block = 0;
  973.       pAddress->Zone++;
  974.  
  975.       if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
  976.       {
  977.         status = NAND_INVALID_ADDRESS;
  978.       }
  979.     }
  980.   }
  981.  
  982.   return (status);
  983. }
  984. /**
  985.   * @}
  986.   */
  987.  
  988. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  989.  *  @brief   management functions
  990.  *
  991. @verbatim  
  992.   ==============================================================================
  993.                          ##### NAND Control functions #####
  994.   ==============================================================================  
  995.   [..]
  996.     This subsection provides a set of functions allowing to control dynamically
  997.     the NAND interface.
  998.  
  999. @endverbatim
  1000.   * @{
  1001.   */
  1002.  
  1003.    
  1004. /**
  1005.   * @brief  Enables dynamically NAND ECC feature.
  1006.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1007.   *                the configuration information for NAND module.
  1008.   * @retval HAL status
  1009.   */    
  1010. HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  1011. {
  1012.   /* Check the NAND controller state */
  1013.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1014.   {
  1015.      return HAL_BUSY;
  1016.   }
  1017.  
  1018.   /* Update the NAND state */
  1019.   hnand->State = HAL_NAND_STATE_BUSY;
  1020.    
  1021.   /* Enable ECC feature */
  1022.   FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  1023.  
  1024.   /* Update the NAND state */
  1025.   hnand->State = HAL_NAND_STATE_READY;
  1026.  
  1027.   return HAL_OK;  
  1028. }
  1029.  
  1030. /**
  1031.   * @brief  Disables dynamically FSMC_NAND ECC feature.
  1032.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1033.   *                the configuration information for NAND module.
  1034.   * @retval HAL status
  1035.   */  
  1036. HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)  
  1037. {
  1038.   /* Check the NAND controller state */
  1039.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1040.   {
  1041.      return HAL_BUSY;
  1042.   }
  1043.  
  1044.   /* Update the NAND state */
  1045.   hnand->State = HAL_NAND_STATE_BUSY;
  1046.    
  1047.   /* Disable ECC feature */
  1048.   FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  1049.  
  1050.   /* Update the NAND state */
  1051.   hnand->State = HAL_NAND_STATE_READY;
  1052.  
  1053.   return HAL_OK;  
  1054. }
  1055.  
  1056. /**
  1057.   * @brief  Disables dynamically NAND ECC feature.
  1058.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1059.   *                the configuration information for NAND module.
  1060.   * @param  ECCval: pointer to ECC value
  1061.   * @param  Timeout: maximum timeout to wait    
  1062.   * @retval HAL status
  1063.   */
  1064. HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  1065. {
  1066.   HAL_StatusTypeDef status = HAL_OK;
  1067.  
  1068.   /* Check the NAND controller state */
  1069.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1070.   {
  1071.      return HAL_BUSY;
  1072.   }
  1073.  
  1074.   /* Update the NAND state */
  1075.   hnand->State = HAL_NAND_STATE_BUSY;  
  1076.    
  1077.   /* Get NAND ECC value */
  1078.   status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  1079.  
  1080.   /* Update the NAND state */
  1081.   hnand->State = HAL_NAND_STATE_READY;
  1082.  
  1083.   return status;  
  1084. }
  1085.                      
  1086. /**
  1087.   * @}
  1088.   */
  1089.  
  1090.    
  1091. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  1092.  *  @brief   Peripheral State functions
  1093.  *
  1094. @verbatim  
  1095.   ==============================================================================
  1096.                          ##### NAND State functions #####
  1097.   ==============================================================================  
  1098.   [..]
  1099.     This subsection permits to get in run-time the status of the NAND controller
  1100.     and the data flow.
  1101.  
  1102. @endverbatim
  1103.   * @{
  1104.   */
  1105.  
  1106. /**
  1107.   * @brief  return the NAND state
  1108.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1109.   *                the configuration information for NAND module.
  1110.   * @retval HAL state
  1111.   */
  1112. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  1113. {
  1114.   return hnand->State;
  1115. }
  1116.  
  1117. /**
  1118.   * @}
  1119.   */  
  1120.  
  1121. /**
  1122.   * @}
  1123.   */
  1124.  
  1125. /** @addtogroup NAND_Private_Functions
  1126.   * @{
  1127.   */
  1128.  
  1129. /**
  1130.   * @brief  Increment the NAND memory address.
  1131.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1132.   *                the configuration information for NAND module.
  1133.   * @param  Address: address to be incremented.
  1134.   * @retval The new status of the increment address operation. It can be:
  1135.   *              - NAND_VALID_ADDRESS: When the new address is valid address
  1136.   *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
  1137.   */
  1138. static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address)
  1139. {
  1140.   uint32_t status = NAND_VALID_ADDRESS;
  1141.  
  1142.   Address->Page++;
  1143.  
  1144.   if(Address->Page == hnand->Info.BlockSize)
  1145.   {
  1146.     Address->Page = 0;
  1147.     Address->Block++;
  1148.    
  1149.     if(Address->Block == hnand->Info.ZoneSize)
  1150.     {
  1151.       Address->Block = 0;
  1152.       Address->Zone++;
  1153.  
  1154.       if(Address->Zone == hnand->Info.BlockNbr)
  1155.       {
  1156.         status = NAND_INVALID_ADDRESS;
  1157.       }
  1158.     }
  1159.   }
  1160.  
  1161.   return (status);
  1162. }
  1163.  
  1164. /**
  1165.   * @}
  1166.   */
  1167.  
  1168. /**
  1169.   * @}
  1170.   */
  1171.  
  1172. #endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
  1173. #endif /* HAL_NAND_MODULE_ENABLED  */
  1174.  
  1175. /**
  1176.   * @}
  1177.   */
  1178.  
  1179. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1180.