Subversion Repositories LedShow

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.   * @brief   NAND HAL module driver.
  6.   *          This file provides a generic firmware to drive NAND memories mounted
  7.   *          as external device.
  8.   *        
  9.   @verbatim
  10.   ==============================================================================
  11.                          ##### How to use this driver #####
  12.   ==============================================================================    
  13.     [..]
  14.       This driver is a generic layered driver which contains a set of APIs used to
  15.       control NAND flash memories. It uses the FSMC layer functions to interface
  16.       with NAND devices. This driver is used as follows:
  17.    
  18.       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
  19.           with control and timing parameters for both common and attribute spaces.
  20.            
  21.       (+) Read NAND flash memory maker and device IDs using the function
  22.           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
  23.           structure declared by the function caller.
  24.        
  25.       (+) Access NAND flash memory by read/write operations using the functions
  26.           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
  27.           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
  28.           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
  29.           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
  30.           to read/write page(s)/spare area(s). These functions use specific device
  31.           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
  32.           structure. The read/write address information is contained by the Nand_Address_Typedef
  33.           structure passed as parameter.
  34.        
  35.       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
  36.        
  37.       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
  38.           The erase block address information is contained in the Nand_Address_Typedef
  39.           structure passed as parameter.
  40.    
  41.       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
  42.        
  43.       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
  44.           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
  45.           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
  46.        
  47.       (+) You can monitor the NAND device HAL state by calling the function
  48.           HAL_NAND_GetState()  
  49.  
  50.     [..]
  51.       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
  52.           If a NAND flash device contains different operations and/or implementations,
  53.           it should be implemented separately.
  54.  
  55.   @endverbatim
  56.   ******************************************************************************
  57.   * @attention
  58.   *
  59.   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  60.   *
  61.   * Redistribution and use in source and binary forms, with or without modification,
  62.   * are permitted provided that the following conditions are met:
  63.   *   1. Redistributions of source code must retain the above copyright notice,
  64.   *      this list of conditions and the following disclaimer.
  65.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  66.   *      this list of conditions and the following disclaimer in the documentation
  67.   *      and/or other materials provided with the distribution.
  68.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  69.   *      may be used to endorse or promote products derived from this software
  70.   *      without specific prior written permission.
  71.   *
  72.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  73.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  74.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  76.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  77.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  78.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  79.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  80.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  81.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  82.   *
  83.   ******************************************************************************
  84.   */
  85.  
  86. /* Includes ------------------------------------------------------------------*/
  87. #include "stm32f1xx_hal.h"
  88.  
  89. /** @addtogroup STM32F1xx_HAL_Driver
  90.   * @{
  91.   */
  92.  
  93. #ifdef HAL_NAND_MODULE_ENABLED
  94.  
  95. #if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
  96.  
  97. /** @defgroup NAND NAND
  98.   * @brief NAND HAL module driver
  99.   * @{
  100.   */
  101.  
  102. /* Private typedef -----------------------------------------------------------*/
  103. /* Private define ------------------------------------------------------------*/
  104. /** @defgroup NAND_Private_Constants NAND Private Constants
  105.   * @{
  106.   */
  107.  
  108. /**
  109.   * @}
  110.   */
  111.  
  112. /* Private macro -------------------------------------------------------------*/    
  113. /** @defgroup NAND_Private_Macros NAND Private Macros
  114.   * @{
  115.   */
  116.  
  117. /**
  118.   * @}
  119.   */
  120.  
  121. /* Private variables ---------------------------------------------------------*/
  122. /* Private function prototypes -----------------------------------------------*/
  123. /* Exported functions --------------------------------------------------------*/
  124. /** @defgroup NAND_Exported_Functions NAND Exported Functions
  125.   * @{
  126.   */
  127.    
  128. /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
  129.   * @brief    Initialization and Configuration functions
  130.   *
  131.   @verbatim    
  132.   ==============================================================================
  133.             ##### NAND Initialization and de-initialization functions #####
  134.   ==============================================================================
  135.   [..]  
  136.     This section provides functions allowing to initialize/de-initialize
  137.     the NAND memory
  138.  
  139. @endverbatim
  140.   * @{
  141.   */
  142.    
  143. /**
  144.   * @brief  Perform NAND memory Initialization sequence
  145.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  146.   *                the configuration information for NAND module.
  147.   * @param  ComSpace_Timing: pointer to Common space timing structure
  148.   * @param  AttSpace_Timing: pointer to Attribute space timing structure
  149.   * @retval HAL status
  150.   */
  151. HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  152. {
  153.   /* Check the NAND handle state */
  154.   if(hnand == NULL)
  155.   {
  156.      return HAL_ERROR;
  157.   }
  158.  
  159.   if(hnand->State == HAL_NAND_STATE_RESET)
  160.   {
  161.     /* Allocate lock resource and initialize it */
  162.     hnand->Lock = HAL_UNLOCKED;
  163.     /* Initialize the low level hardware (MSP) */
  164.     HAL_NAND_MspInit(hnand);
  165.   }
  166.  
  167.   /* Initialize NAND control Interface */
  168.   FSMC_NAND_Init(hnand->Instance, &(hnand->Init));
  169.  
  170.   /* Initialize NAND common space timing Interface */  
  171.   FSMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  172.  
  173.   /* Initialize NAND attribute space timing Interface */  
  174.   FSMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  175.  
  176.   /* Enable the NAND device */
  177.   __FSMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
  178.  
  179.   /* Update the NAND controller state */
  180.   hnand->State = HAL_NAND_STATE_READY;
  181.  
  182.   return HAL_OK;
  183. }
  184.  
  185. /**
  186.   * @brief  Perform NAND memory De-Initialization sequence
  187.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  188.   *                the configuration information for NAND module.
  189.   * @retval HAL status
  190.   */
  191. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)  
  192. {
  193.   /* Initialize the low level hardware (MSP) */
  194.   HAL_NAND_MspDeInit(hnand);
  195.  
  196.   /* Configure the NAND registers with their reset values */
  197.   FSMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
  198.  
  199.   /* Reset the NAND controller state */
  200.   hnand->State = HAL_NAND_STATE_RESET;
  201.  
  202.   /* Release Lock */
  203.   __HAL_UNLOCK(hnand);
  204.  
  205.   return HAL_OK;
  206. }
  207.  
  208. /**
  209.   * @brief  NAND MSP Init
  210.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  211.   *                the configuration information for NAND module.
  212.   * @retval None
  213.   */
  214. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  215. {
  216.   /* Prevent unused argument(s) compilation warning */
  217.   UNUSED(hnand);
  218.   /* NOTE : This function Should not be modified, when the callback is needed,
  219.             the HAL_NAND_MspInit could be implemented in the user file
  220.    */
  221. }
  222.  
  223. /**
  224.   * @brief  NAND MSP DeInit
  225.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  226.   *                the configuration information for NAND module.
  227.   * @retval None
  228.   */
  229. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  230. {
  231.   /* Prevent unused argument(s) compilation warning */
  232.   UNUSED(hnand);
  233.   /* NOTE : This function Should not be modified, when the callback is needed,
  234.             the HAL_NAND_MspDeInit could be implemented in the user file
  235.    */
  236. }
  237.  
  238.  
  239. /**
  240.   * @brief  This function handles NAND device interrupt request.
  241.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  242.   *                the configuration information for NAND module.
  243.   * @retval HAL status
  244. */
  245. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  246. {
  247.   /* Check NAND interrupt Rising edge flag */
  248.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
  249.   {
  250.     /* NAND interrupt callback*/
  251.     HAL_NAND_ITCallback(hnand);
  252.  
  253.     /* Clear NAND interrupt Rising edge pending bit */
  254.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
  255.   }
  256.  
  257.   /* Check NAND interrupt Level flag */
  258.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
  259.   {
  260.     /* NAND interrupt callback*/
  261.     HAL_NAND_ITCallback(hnand);
  262.  
  263.     /* Clear NAND interrupt Level pending bit */
  264.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
  265.   }
  266.  
  267.   /* Check NAND interrupt Falling edge flag */
  268.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
  269.   {
  270.     /* NAND interrupt callback*/
  271.     HAL_NAND_ITCallback(hnand);
  272.  
  273.     /* Clear NAND interrupt Falling edge pending bit */
  274.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
  275.   }
  276.  
  277.   /* Check NAND interrupt FIFO empty flag */
  278.   if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
  279.   {
  280.     /* NAND interrupt callback*/
  281.     HAL_NAND_ITCallback(hnand);
  282.  
  283.     /* Clear NAND interrupt FIFO empty pending bit */
  284.     __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
  285.   }
  286. }
  287.  
  288. /**
  289.   * @brief  NAND interrupt feature callback
  290.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  291.   *                the configuration information for NAND module.
  292.   * @retval None
  293.   */
  294. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  295. {
  296.   /* Prevent unused argument(s) compilation warning */
  297.   UNUSED(hnand);
  298.   /* NOTE : This function Should not be modified, when the callback is needed,
  299.             the HAL_NAND_ITCallback could be implemented in the user file
  300.    */
  301. }
  302.  
  303. /**
  304.   * @}
  305.   */
  306.  
  307. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  308.   * @brief    Input Output and memory control functions
  309.   *
  310.   @verbatim    
  311.   ==============================================================================
  312.                     ##### NAND Input and Output functions #####
  313.   ==============================================================================
  314.   [..]  
  315.     This section provides functions allowing to use and control the NAND
  316.     memory
  317.  
  318. @endverbatim
  319.   * @{
  320.   */
  321.  
  322. /**
  323.   * @brief  Read the NAND memory electronic signature
  324.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  325.   *                the configuration information for NAND module.
  326.   * @param  pNAND_ID: NAND ID structure
  327.   * @retval HAL status
  328.   */
  329. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  330. {
  331.   __IO uint32_t data = 0U;
  332.   __IO uint32_t data1 = 0U;
  333.   uint32_t deviceaddress = 0U;
  334.  
  335.   /* Process Locked */
  336.   __HAL_LOCK(hnand);  
  337.  
  338.   /* Check the NAND controller state */
  339.   if(hnand->State == HAL_NAND_STATE_BUSY)
  340.   {
  341.      return HAL_BUSY;
  342.   }
  343.  
  344.   /* Identify the device address */
  345.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  346.   {
  347.     deviceaddress = NAND_DEVICE1;
  348.   }
  349.   else
  350.   {
  351.     deviceaddress = NAND_DEVICE2;
  352.   }
  353.  
  354.   /* Update the NAND controller state */
  355.   hnand->State = HAL_NAND_STATE_BUSY;
  356.  
  357.   /* Send Read ID command sequence */  
  358.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
  359.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  360.  
  361.   /* Read the electronic signature from NAND flash */
  362.   if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
  363.   {
  364.     data = *(__IO uint32_t *)deviceaddress;
  365.  
  366.     /* Return the data read */
  367.     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
  368.     pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
  369.     pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
  370.     pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
  371.   }
  372.   else
  373.   {
  374.     data = *(__IO uint32_t *)deviceaddress;
  375.     data1 = *((__IO uint32_t *)deviceaddress + 4U);
  376.    
  377.     /* Return the data read */
  378.     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
  379.     pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
  380.     pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
  381.     pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
  382.   }
  383.  
  384.   /* Update the NAND controller state */
  385.   hnand->State = HAL_NAND_STATE_READY;
  386.  
  387.   /* Process unlocked */
  388.   __HAL_UNLOCK(hnand);
  389.    
  390.   return HAL_OK;
  391. }
  392.  
  393. /**
  394.   * @brief  NAND memory reset
  395.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  396.   *                the configuration information for NAND module.
  397.   * @retval HAL status
  398.   */
  399. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  400. {
  401.   uint32_t deviceaddress = 0U;
  402.  
  403.   /* Process Locked */
  404.   __HAL_LOCK(hnand);
  405.  
  406.   /* Check the NAND controller state */
  407.   if(hnand->State == HAL_NAND_STATE_BUSY)
  408.   {
  409.      return HAL_BUSY;
  410.   }
  411.  
  412.   /* Identify the device address */
  413.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  414.   {
  415.     deviceaddress = NAND_DEVICE1;
  416.   }
  417.   else
  418.   {
  419.     deviceaddress = NAND_DEVICE2;
  420.   }  
  421.  
  422.   /* Update the NAND controller state */
  423.   hnand->State = HAL_NAND_STATE_BUSY;
  424.  
  425.   /* Send NAND reset command */  
  426.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
  427.  
  428.  
  429.   /* Update the NAND controller state */
  430.   hnand->State = HAL_NAND_STATE_READY;
  431.  
  432.   /* Process unlocked */
  433.   __HAL_UNLOCK(hnand);
  434.  
  435.   return HAL_OK;
  436.  
  437. }
  438.  
  439. /**
  440.   * @brief  Configure the device: Enter the physical parameters of the device
  441.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  442.   *                the configuration information for NAND module.
  443.   * @param  pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
  444.   * @retval HAL status
  445.   */
  446. HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
  447. {
  448.   hnand->Config.PageSize           = pDeviceConfig->PageSize;
  449.   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
  450.   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
  451.   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
  452.   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
  453.   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
  454.   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
  455.  
  456.   return HAL_OK;
  457. }
  458.  
  459. /**
  460.   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
  461.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  462.   *                the configuration information for NAND module.
  463.   * @param  pAddress : pointer to NAND address structure
  464.   * @param  pBuffer : pointer to destination read buffer
  465.   * @param  NumPageToRead : number of pages to read from block
  466.   * @retval HAL status
  467.   */
  468. HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  469. {  
  470.   __IO uint32_t index  = 0U;
  471.   uint32_t tickstart = 0U;
  472.   uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
  473.  
  474.   /* Process Locked */
  475.   __HAL_LOCK(hnand);
  476.  
  477.   /* Check the NAND controller state */
  478.   if(hnand->State == HAL_NAND_STATE_BUSY)
  479.   {
  480.      return HAL_BUSY;
  481.   }
  482.  
  483.   /* Identify the device address */
  484.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  485.   {
  486.     deviceaddress = NAND_DEVICE1;
  487.   }
  488.   else
  489.   {
  490.     deviceaddress = NAND_DEVICE2;
  491.   }
  492.  
  493.   /* Update the NAND controller state */
  494.   hnand->State = HAL_NAND_STATE_BUSY;
  495.  
  496.   /* NAND raw address calculation */
  497.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  498.  
  499.   /* Page(s) read loop */  
  500.   while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  501.   {
  502.     /* update the buffer size */
  503.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  504.    
  505.     /* Send read page command sequence */
  506.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  507.    
  508.     /* Cards with page size <= 512 bytes */
  509.     if((hnand->Config.PageSize) <= 512U)
  510.     {
  511.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  512.       {
  513.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  514.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  515.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  516.       }
  517.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  518.       {
  519.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  520.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  521.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  522.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  523.       }
  524.     }
  525.     else /* (hnand->Config.PageSize) > 512 */
  526.     {
  527.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  528.       {
  529.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  530.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  531.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  532.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  533.       }
  534.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  535.       {
  536.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  537.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  538.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  539.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  540.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  541.       }
  542.     }
  543.  
  544.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  545.    
  546.     /* Check if an extra command is needed for reading pages  */
  547.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  548.     {
  549.       /* Get tick */
  550.       tickstart = HAL_GetTick();
  551.      
  552.       /* Read status until NAND is ready */
  553.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  554.       {
  555.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  556.         {
  557.           return HAL_TIMEOUT;
  558.         }
  559.       }
  560.      
  561.       /* Go back to read mode */
  562.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
  563.     }
  564.    
  565.     /* Get Data into Buffer */    
  566.     for(; index < size; index++)
  567.     {
  568.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  569.     }
  570.    
  571.     /* Increment read pages number */
  572.     numPagesRead++;
  573.    
  574.     /* Decrement pages to read */
  575.     NumPageToRead--;
  576.    
  577.     /* Increment the NAND address */
  578.     nandaddress = (uint32_t)(nandaddress + 1U);
  579.   }
  580.  
  581.   /* Update the NAND controller state */
  582.   hnand->State = HAL_NAND_STATE_READY;
  583.  
  584.   /* Process unlocked */
  585.   __HAL_UNLOCK(hnand);
  586.  
  587.   return HAL_OK;
  588. }
  589.  
  590. /**
  591.   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
  592.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  593.   *                the configuration information for NAND module.
  594.   * @param  pAddress : pointer to NAND address structure
  595.   * @param  pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
  596.   * @param  NumPageToRead : number of pages to read from block
  597.   * @retval HAL status
  598.   */
  599. HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
  600. {  
  601.   __IO uint32_t index  = 0U;
  602.   uint32_t tickstart = 0U;
  603.   uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
  604.  
  605.   /* Process Locked */
  606.   __HAL_LOCK(hnand);
  607.  
  608.   /* Check the NAND controller state */
  609.   if(hnand->State == HAL_NAND_STATE_BUSY)
  610.   {
  611.      return HAL_BUSY;
  612.   }
  613.  
  614.   /* Identify the device address */
  615.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  616.   {
  617.     deviceaddress = NAND_DEVICE1;
  618.   }
  619.   else
  620.   {
  621.     deviceaddress = NAND_DEVICE2;
  622.   }
  623.  
  624.   /* Update the NAND controller state */
  625.   hnand->State = HAL_NAND_STATE_BUSY;
  626.  
  627.   /* NAND raw address calculation */
  628.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  629.  
  630.   /* Page(s) read loop */  
  631.   while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  632.   {
  633.     /* update the buffer size */
  634.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  635.    
  636.     /* Send read page command sequence */
  637.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;  
  638.    
  639.     /* Cards with page size <= 512 bytes */
  640.     if((hnand->Config.PageSize) <= 512U)
  641.     {
  642.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  643.       {
  644.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  645.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  646.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  647.       }
  648.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  649.       {
  650.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  651.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  652.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  653.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  654.       }
  655.     }
  656.     else /* (hnand->Config.PageSize) > 512 */
  657.     {
  658.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  659.       {
  660.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  661.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  662.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  663.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  664.       }
  665.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  666.       {
  667.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  668.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  669.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  670.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  671.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  672.       }
  673.     }
  674.  
  675.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  676.    
  677.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  678.     {
  679.       /* Get tick */
  680.       tickstart = HAL_GetTick();
  681.      
  682.       /* Read status until NAND is ready */
  683.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  684.       {
  685.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  686.         {
  687.           return HAL_TIMEOUT;
  688.         }
  689.       }
  690.      
  691.       /* Go back to read mode */
  692.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
  693.     }
  694.    
  695.     /* Get Data into Buffer */    
  696.     for(; index < size; index++)
  697.     {
  698.       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
  699.     }
  700.    
  701.     /* Increment read pages number */
  702.     numPagesRead++;
  703.    
  704.     /* Decrement pages to read */
  705.     NumPageToRead--;
  706.    
  707.     /* Increment the NAND address */
  708.     nandaddress = (uint32_t)(nandaddress + 1U);
  709.   }
  710.  
  711.   /* Update the NAND controller state */
  712.   hnand->State = HAL_NAND_STATE_READY;
  713.  
  714.   /* Process unlocked */
  715.   __HAL_UNLOCK(hnand);  
  716.    
  717.   return HAL_OK;
  718. }
  719.  
  720. /**
  721.   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
  722.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  723.   *                the configuration information for NAND module.
  724.   * @param  pAddress : pointer to NAND address structure
  725.   * @param  pBuffer : pointer to source buffer to write  
  726.   * @param  NumPageToWrite  : number of pages to write to block
  727.   * @retval HAL status
  728.   */
  729. HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  730. {
  731.   __IO uint32_t index = 0U;
  732.   uint32_t tickstart = 0U;
  733.   uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
  734.  
  735.   /* Process Locked */
  736.   __HAL_LOCK(hnand);  
  737.  
  738.   /* Check the NAND controller state */
  739.   if(hnand->State == HAL_NAND_STATE_BUSY)
  740.   {
  741.      return HAL_BUSY;
  742.   }
  743.  
  744.   /* Identify the device address */
  745.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  746.   {
  747.     deviceaddress = NAND_DEVICE1;
  748.   }
  749.   else
  750.   {
  751.     deviceaddress = NAND_DEVICE2;
  752.   }
  753.  
  754.   /* Update the NAND controller state */
  755.   hnand->State = HAL_NAND_STATE_BUSY;
  756.  
  757.   /* NAND raw address calculation */
  758.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  759.    
  760.   /* Page(s) write loop */
  761.   while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  762.   {
  763.     /* update the buffer size */
  764.     size = hnand->Config.PageSize + ((hnand->Config.PageSize) * numPagesWritten);
  765.    
  766.     /* Send write page command sequence */
  767.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  768.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  769.  
  770.     /* Cards with page size <= 512 bytes */
  771.     if((hnand->Config.PageSize) <= 512U)
  772.     {
  773.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  774.       {
  775.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  776.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  777.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  778.       }
  779.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  780.       {
  781.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  782.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  783.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  784.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  785.       }
  786.     }
  787.     else /* (hnand->Config.PageSize) > 512 */
  788.     {
  789.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  790.       {
  791.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  792.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  793.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  794.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  795.       }
  796.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  797.       {
  798.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  799.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  800.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  801.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  802.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  803.       }
  804.     }
  805.  
  806.  
  807.     /* Write data to memory */
  808.     for(; index < size; index++)
  809.     {
  810.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  811.     }
  812.    
  813.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  814.    
  815.     /* Read status until NAND is ready */
  816.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  817.     {
  818.       /* Get tick */
  819.       tickstart = HAL_GetTick();
  820.      
  821.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  822.       {
  823.         return HAL_TIMEOUT;
  824.       }
  825.     }
  826.  
  827.     /* Increment written pages number */
  828.     numPagesWritten++;
  829.    
  830.     /* Decrement pages to write */
  831.     NumPageToWrite--;
  832.    
  833.     /* Increment the NAND address */
  834.     nandaddress = (uint32_t)(nandaddress + 1U);
  835.   }
  836.  
  837.   /* Update the NAND controller state */
  838.   hnand->State = HAL_NAND_STATE_READY;
  839.  
  840.   /* Process unlocked */
  841.   __HAL_UNLOCK(hnand);
  842.  
  843.   return HAL_OK;
  844. }
  845.  
  846. /**
  847.   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
  848.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  849.   *                the configuration information for NAND module.
  850.   * @param  pAddress : pointer to NAND address structure
  851.   * @param  pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
  852.   * @param  NumPageToWrite  : number of pages to write to block
  853.   * @retval HAL status
  854.   */
  855. HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
  856. {
  857.   __IO uint32_t index = 0U;
  858.   uint32_t tickstart = 0U;
  859.   uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
  860.  
  861.   /* Process Locked */
  862.   __HAL_LOCK(hnand);  
  863.  
  864.   /* Check the NAND controller state */
  865.   if(hnand->State == HAL_NAND_STATE_BUSY)
  866.   {
  867.      return HAL_BUSY;
  868.   }
  869.  
  870.   /* Identify the device address */
  871.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  872.   {
  873.     deviceaddress = NAND_DEVICE1;
  874.   }
  875.   else
  876.   {
  877.     deviceaddress = NAND_DEVICE2;
  878.   }
  879.  
  880.   /* Update the NAND controller state */
  881.   hnand->State = HAL_NAND_STATE_BUSY;
  882.  
  883.   /* NAND raw address calculation */
  884.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  885.  
  886.   /* Page(s) write loop */
  887.   while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  888.   {
  889.     /* update the buffer size */
  890.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
  891.  
  892.     /* Send write page command sequence */
  893.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  894.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  895.  
  896.     /* Cards with page size <= 512 bytes */
  897.     if((hnand->Config.PageSize) <= 512U)
  898.     {
  899.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  900.       {
  901.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  902.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  903.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  904.       }
  905.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  906.       {
  907.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  908.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  909.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  910.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  911.       }
  912.     }
  913.     else /* (hnand->Config.PageSize) > 512 */
  914.     {
  915.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  916.       {
  917.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  918.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  919.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  920.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  921.       }
  922.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  923.       {
  924.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  925.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  926.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  927.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  928.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  929.       }
  930.     }
  931.  
  932.     /* Write data to memory */
  933.     for(; index < size; index++)
  934.     {
  935.       *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
  936.     }
  937.    
  938.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  939.    
  940.     /* Read status until NAND is ready */
  941.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  942.     {
  943.       /* Get tick */
  944.       tickstart = HAL_GetTick();
  945.    
  946.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  947.       {
  948.         return HAL_TIMEOUT;
  949.       }
  950.     }  
  951.  
  952.     /* Increment written pages number */
  953.     numPagesWritten++;
  954.    
  955.     /* Decrement pages to write */
  956.     NumPageToWrite--;
  957.    
  958.     /* Increment the NAND address */
  959.     nandaddress = (uint32_t)(nandaddress + 1U);
  960.   }
  961.  
  962.   /* Update the NAND controller state */
  963.   hnand->State = HAL_NAND_STATE_READY;
  964.  
  965.   /* Process unlocked */
  966.   __HAL_UNLOCK(hnand);
  967.  
  968.   return HAL_OK;
  969. }
  970.  
  971. /**
  972.   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
  973.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  974.   *                the configuration information for NAND module.
  975.   * @param  pAddress : pointer to NAND address structure
  976.   * @param  pBuffer: pointer to source buffer to write  
  977.   * @param  NumSpareAreaToRead: Number of spare area to read  
  978.   * @retval HAL status
  979. */
  980. HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  981. {
  982.   __IO uint32_t index = 0U;
  983.   uint32_t tickstart = 0U;
  984.   uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
  985.  
  986.   /* Process Locked */
  987.   __HAL_LOCK(hnand);  
  988.  
  989.   /* Check the NAND controller state */
  990.   if(hnand->State == HAL_NAND_STATE_BUSY)
  991.   {
  992.      return HAL_BUSY;
  993.   }
  994.  
  995.   /* Identify the device address */
  996.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  997.   {
  998.     deviceaddress = NAND_DEVICE1;
  999.   }
  1000.   else
  1001.   {
  1002.     deviceaddress = NAND_DEVICE2;
  1003.   }
  1004.  
  1005.   /* Update the NAND controller state */
  1006.   hnand->State = HAL_NAND_STATE_BUSY;
  1007.  
  1008.   /* NAND raw address calculation */
  1009.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  1010.  
  1011.   /* Column in page address */
  1012.   columnaddress = COLUMN_ADDRESS(hnand);
  1013.  
  1014.   /* Spare area(s) read loop */
  1015.   while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1016.   {    
  1017.     /* update the buffer size */
  1018.     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
  1019.  
  1020.     /* Cards with page size <= 512 bytes */
  1021.     if((hnand->Config.PageSize) <= 512U)
  1022.     {
  1023.       /* Send read spare area command sequence */    
  1024.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1025.      
  1026.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1027.       {
  1028.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1029.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1030.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1031.       }
  1032.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1033.       {
  1034.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1035.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1036.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1037.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1038.       }
  1039.     }
  1040.     else /* (hnand->Config.PageSize) > 512 */
  1041.     {
  1042.       /* Send read spare area command sequence */
  1043.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1044.      
  1045.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1046.       {
  1047.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1048.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1049.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1050.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1051.       }
  1052.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1053.       {
  1054.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1055.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1056.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1057.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1058.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1059.       }
  1060.     }
  1061.  
  1062.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  1063.    
  1064.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  1065.     {
  1066.       /* Get tick */
  1067.       tickstart = HAL_GetTick();
  1068.      
  1069.       /* Read status until NAND is ready */
  1070.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1071.       {
  1072.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1073.         {
  1074.           return HAL_TIMEOUT;
  1075.         }
  1076.       }
  1077.      
  1078.       /* Go back to read mode */
  1079.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
  1080.     }
  1081.    
  1082.     /* Get Data into Buffer */
  1083.     for(; index < size; index++)
  1084.     {
  1085.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  1086.     }
  1087.    
  1088.     /* Increment read spare areas number */
  1089.     numSpareAreaRead++;
  1090.    
  1091.     /* Decrement spare areas to read */
  1092.     NumSpareAreaToRead--;
  1093.    
  1094.     /* Increment the NAND address */
  1095.     nandaddress = (uint32_t)(nandaddress + 1U);
  1096.   }
  1097.  
  1098.   /* Update the NAND controller state */
  1099.   hnand->State = HAL_NAND_STATE_READY;
  1100.  
  1101.   /* Process unlocked */
  1102.   __HAL_UNLOCK(hnand);
  1103.  
  1104.   return HAL_OK;
  1105. }
  1106.  
  1107. /**
  1108.   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
  1109.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1110.   *                the configuration information for NAND module.
  1111.   * @param  pAddress : pointer to NAND address structure
  1112.   * @param  pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
  1113.   * @param  NumSpareAreaToRead: Number of spare area to read  
  1114.   * @retval HAL status
  1115. */
  1116. HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
  1117. {
  1118.   __IO uint32_t index = 0U;
  1119.   uint32_t tickstart = 0U;
  1120.   uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
  1121.  
  1122.   /* Process Locked */
  1123.   __HAL_LOCK(hnand);
  1124.  
  1125.   /* Check the NAND controller state */
  1126.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1127.   {
  1128.      return HAL_BUSY;
  1129.   }
  1130.  
  1131.   /* Identify the device address */
  1132.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  1133.   {
  1134.     deviceaddress = NAND_DEVICE1;
  1135.   }
  1136.   else
  1137.   {
  1138.     deviceaddress = NAND_DEVICE2;
  1139.   }
  1140.  
  1141.   /* Update the NAND controller state */
  1142.   hnand->State = HAL_NAND_STATE_BUSY;
  1143.  
  1144.   /* NAND raw address calculation */
  1145.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  1146.  
  1147.   /* Column in page address */
  1148.   columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
  1149.  
  1150.   /* Spare area(s) read loop */
  1151.   while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1152.   {
  1153.     /* update the buffer size */
  1154.     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
  1155.  
  1156.     /* Cards with page size <= 512 bytes */
  1157.     if((hnand->Config.PageSize) <= 512U)
  1158.     {
  1159.       /* Send read spare area command sequence */    
  1160.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1161.      
  1162.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1163.       {
  1164.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1165.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1166.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1167.       }
  1168.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1169.       {
  1170.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1171.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1172.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1173.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1174.       }
  1175.     }
  1176.     else /* (hnand->Config.PageSize) > 512 */
  1177.     {
  1178.       /* Send read spare area command sequence */    
  1179.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1180.      
  1181.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1182.       {
  1183.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1184.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1185.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1186.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1187.       }
  1188.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1189.       {
  1190.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1191.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1192.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1193.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1194.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1195.       }
  1196.     }
  1197.  
  1198.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  1199.  
  1200.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  1201.     {
  1202.       /* Get tick */
  1203.       tickstart = HAL_GetTick();
  1204.      
  1205.       /* Read status until NAND is ready */
  1206.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1207.       {
  1208.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1209.         {
  1210.           return HAL_TIMEOUT;
  1211.         }
  1212.       }
  1213.      
  1214.       /* Go back to read mode */
  1215.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
  1216.     }
  1217.    
  1218.     /* Get Data into Buffer */
  1219.     for(; index < size; index++)
  1220.     {
  1221.       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
  1222.     }
  1223.    
  1224.     /* Increment read spare areas number */
  1225.     numSpareAreaRead++;
  1226.    
  1227.     /* Decrement spare areas to read */
  1228.     NumSpareAreaToRead--;
  1229.    
  1230.     /* Increment the NAND address */
  1231.     nandaddress = (uint32_t)(nandaddress + 1U);
  1232.   }
  1233.  
  1234.   /* Update the NAND controller state */
  1235.   hnand->State = HAL_NAND_STATE_READY;
  1236.  
  1237.   /* Process unlocked */
  1238.   __HAL_UNLOCK(hnand);    
  1239.  
  1240.   return HAL_OK;  
  1241. }
  1242.  
  1243. /**
  1244.   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
  1245.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1246.   *                the configuration information for NAND module.
  1247.   * @param  pAddress : pointer to NAND address structure
  1248.   * @param  pBuffer : pointer to source buffer to write  
  1249.   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
  1250.   * @retval HAL status
  1251.   */
  1252. HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  1253. {
  1254.   __IO uint32_t index = 0U;
  1255.   uint32_t tickstart = 0U;
  1256.   uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
  1257.  
  1258.   /* Process Locked */
  1259.   __HAL_LOCK(hnand);
  1260.  
  1261.   /* Check the NAND controller state */
  1262.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1263.   {
  1264.      return HAL_BUSY;
  1265.   }
  1266.  
  1267.   /* Identify the device address */
  1268.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  1269.   {
  1270.     deviceaddress = NAND_DEVICE1;
  1271.   }
  1272.   else
  1273.   {
  1274.     deviceaddress = NAND_DEVICE2;
  1275.   }
  1276.  
  1277.   /* Update the FSMC_NAND controller state */
  1278.   hnand->State = HAL_NAND_STATE_BUSY;  
  1279.  
  1280.   /* Page address calculation */
  1281.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  1282.  
  1283.   /* Column in page address */
  1284.   columnaddress = COLUMN_ADDRESS(hnand);
  1285.  
  1286.   /* Spare area(s) write loop */
  1287.   while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1288.   {
  1289.     /* update the buffer size */
  1290.     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
  1291.  
  1292.     /* Cards with page size <= 512 bytes */
  1293.     if((hnand->Config.PageSize) <= 512U)
  1294.     {
  1295.       /* Send write Spare area command sequence */
  1296.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1297.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1298.      
  1299.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1300.       {
  1301.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1302.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1303.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1304.       }
  1305.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1306.       {
  1307.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1308.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1309.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1310.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1311.       }
  1312.     }
  1313.     else /* (hnand->Config.PageSize) > 512 */
  1314.     {
  1315.       /* Send write Spare area command sequence */
  1316.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1317.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1318.    
  1319.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1320.       {
  1321.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1322.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1323.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1324.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1325.       }
  1326.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1327.       {
  1328.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1329.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1330.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1331.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1332.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1333.       }
  1334.     }
  1335.  
  1336.     /* Write data to memory */
  1337.     for(; index < size; index++)
  1338.     {
  1339.       *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  1340.     }
  1341.    
  1342.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  1343.    
  1344.     /* Get tick */
  1345.     tickstart = HAL_GetTick();
  1346.    
  1347.     /* Read status until NAND is ready */
  1348.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1349.     {
  1350.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1351.       {
  1352.         return HAL_TIMEOUT;
  1353.       }
  1354.     }
  1355.  
  1356.     /* Increment written spare areas number */
  1357.     numSpareAreaWritten++;
  1358.    
  1359.     /* Decrement spare areas to write */
  1360.     NumSpareAreaTowrite--;
  1361.    
  1362.     /* Increment the NAND address */
  1363.     nandaddress = (uint32_t)(nandaddress + 1U);
  1364.   }
  1365.  
  1366.   /* Update the NAND controller state */
  1367.   hnand->State = HAL_NAND_STATE_READY;
  1368.  
  1369.   /* Process unlocked */
  1370.   __HAL_UNLOCK(hnand);
  1371.    
  1372.   return HAL_OK;
  1373. }
  1374.  
  1375. /**
  1376.   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
  1377.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1378.   *                the configuration information for NAND module.
  1379.   * @param  pAddress : pointer to NAND address structure
  1380.   * @param  pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.  
  1381.   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
  1382.   * @retval HAL status
  1383.   */
  1384. HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
  1385. {
  1386.   __IO uint32_t index = 0U;
  1387.   uint32_t tickstart = 0U;
  1388.   uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
  1389.  
  1390.   /* Process Locked */
  1391.   __HAL_LOCK(hnand);
  1392.  
  1393.   /* Check the NAND controller state */
  1394.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1395.   {
  1396.      return HAL_BUSY;
  1397.   }
  1398.  
  1399.   /* Identify the device address */
  1400.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  1401.   {
  1402.     deviceaddress = NAND_DEVICE1;
  1403.   }
  1404.   else
  1405.   {
  1406.     deviceaddress = NAND_DEVICE2;
  1407.   }
  1408.  
  1409.   /* Update the FSMC_NAND controller state */
  1410.   hnand->State = HAL_NAND_STATE_BUSY;  
  1411.  
  1412.   /* NAND raw address calculation */
  1413.   nandaddress = ARRAY_ADDRESS(pAddress, hnand);
  1414.  
  1415.   /* Column in page address */
  1416.   columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
  1417.  
  1418.   /* Spare area(s) write loop */
  1419.   while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1420.   {
  1421.     /* update the buffer size */
  1422.     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
  1423.  
  1424.     /* Cards with page size <= 512 bytes */
  1425.     if((hnand->Config.PageSize) <= 512U)
  1426.     {
  1427.       /* Send write Spare area command sequence */
  1428.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1429.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1430.    
  1431.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1432.       {
  1433.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1434.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1435.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1436.       }
  1437.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1438.       {
  1439.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  1440.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1441.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1442.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1443.       }
  1444.     }
  1445.     else /* (hnand->Config.PageSize) > 512 */
  1446.     {
  1447.       /* Send write Spare area command sequence */
  1448.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1449.       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1450.    
  1451.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
  1452.       {
  1453.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1454.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1455.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1456.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1457.       }
  1458.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1459.       {
  1460.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
  1461.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
  1462.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
  1463.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
  1464.         *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
  1465.       }
  1466.     }
  1467.  
  1468.     /* Write data to memory */
  1469.     for(; index < size; index++)
  1470.     {
  1471.       *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
  1472.     }
  1473.    
  1474.     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  1475.    
  1476.     /* Read status until NAND is ready */
  1477.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1478.     {
  1479.       /* Get tick */
  1480.       tickstart = HAL_GetTick();
  1481.    
  1482.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1483.       {
  1484.         return HAL_TIMEOUT;
  1485.       }
  1486.     }
  1487.  
  1488.     /* Increment written spare areas number */
  1489.     numSpareAreaWritten++;
  1490.    
  1491.     /* Decrement spare areas to write */
  1492.     NumSpareAreaTowrite--;
  1493.    
  1494.     /* Increment the NAND address */
  1495.     nandaddress = (uint32_t)(nandaddress + 1U);
  1496.   }
  1497.  
  1498.   /* Update the NAND controller state */
  1499.   hnand->State = HAL_NAND_STATE_READY;
  1500.  
  1501.   /* Process unlocked */
  1502.   __HAL_UNLOCK(hnand);
  1503.  
  1504.   return HAL_OK;  
  1505. }
  1506.  
  1507. /**
  1508.   * @brief  NAND memory Block erase
  1509.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1510.   *                the configuration information for NAND module.
  1511.   * @param  pAddress : pointer to NAND address structure
  1512.   * @retval HAL status
  1513.   */
  1514. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  1515. {
  1516.   uint32_t deviceaddress = 0U;
  1517.   uint32_t tickstart = 0U;
  1518.  
  1519.   /* Process Locked */
  1520.   __HAL_LOCK(hnand);
  1521.  
  1522.   /* Check the NAND controller state */
  1523.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1524.   {
  1525.      return HAL_BUSY;
  1526.   }
  1527.  
  1528.   /* Identify the device address */
  1529.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  1530.   {
  1531.     deviceaddress = NAND_DEVICE1;
  1532.   }
  1533.   else
  1534.   {
  1535.     deviceaddress = NAND_DEVICE2;
  1536.   }
  1537.  
  1538.   /* Update the NAND controller state */
  1539.   hnand->State = HAL_NAND_STATE_BUSY;  
  1540.  
  1541.   /* Send Erase block command sequence */
  1542.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
  1543.  
  1544.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1545.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1546.   *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1547.    
  1548.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
  1549.  
  1550.   /* Update the NAND controller state */
  1551.   hnand->State = HAL_NAND_STATE_READY;
  1552.  
  1553.   /* Get tick */
  1554.   tickstart = HAL_GetTick();
  1555.  
  1556.   /* Read status until NAND is ready */
  1557.   while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1558.   {
  1559.     if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1560.     {
  1561.       /* Process unlocked */
  1562.       __HAL_UNLOCK(hnand);    
  1563.  
  1564.       return HAL_TIMEOUT;
  1565.     }
  1566.   }    
  1567.  
  1568.   /* Process unlocked */
  1569.   __HAL_UNLOCK(hnand);    
  1570.  
  1571.   return HAL_OK;  
  1572. }
  1573.  
  1574. /**
  1575.   * @brief  NAND memory read status
  1576.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1577.   *                the configuration information for NAND module.
  1578.   * @retval NAND status
  1579.   */
  1580. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  1581. {
  1582.   uint32_t data = 0U;
  1583.   uint32_t deviceaddress = 0U;
  1584.  
  1585.   /* Identify the device address */
  1586.   if(hnand->Init.NandBank == FSMC_NAND_BANK2)
  1587.   {
  1588.     deviceaddress = NAND_DEVICE1;
  1589.   }
  1590.   else
  1591.   {
  1592.     deviceaddress = NAND_DEVICE2;
  1593.   }
  1594.  
  1595.   /* Send Read status operation command */
  1596.   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
  1597.  
  1598.   /* Read status register data */
  1599.   data = *(__IO uint8_t *)deviceaddress;
  1600.  
  1601.   /* Return the status */
  1602.   if((data & NAND_ERROR) == NAND_ERROR)
  1603.   {
  1604.     return NAND_ERROR;
  1605.   }
  1606.   else if((data & NAND_READY) == NAND_READY)
  1607.   {
  1608.     return NAND_READY;
  1609.   }
  1610.  
  1611.   return NAND_BUSY;
  1612. }
  1613.  
  1614. /**
  1615.   * @brief  Increment the NAND memory address
  1616.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1617.   *                the configuration information for NAND module.
  1618.   * @param pAddress: pointer to NAND address structure
  1619.   * @retval The new status of the increment address operation. It can be:
  1620.   *           - NAND_VALID_ADDRESS: When the new address is valid address
  1621.   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
  1622.   */
  1623. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  1624. {
  1625.   uint32_t status = NAND_VALID_ADDRESS;
  1626.  
  1627.   /* Increment page address */
  1628.   pAddress->Page++;
  1629.  
  1630.   /* Check NAND address is valid */
  1631.   if(pAddress->Page == hnand->Config.BlockSize)
  1632.   {
  1633.     pAddress->Page = 0U;
  1634.     pAddress->Block++;
  1635.    
  1636.     if(pAddress->Block == hnand->Config.PlaneSize)
  1637.     {
  1638.       pAddress->Block = 0U;
  1639.       pAddress->Plane++;
  1640.  
  1641.       if(pAddress->Plane == (hnand->Config.PlaneNbr))
  1642.       {
  1643.         status = NAND_INVALID_ADDRESS;
  1644.       }
  1645.     }
  1646.   }
  1647.  
  1648.   return (status);
  1649. }
  1650. /**
  1651.   * @}
  1652.   */
  1653.  
  1654. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  1655.  *  @brief   management functions
  1656.  *
  1657. @verbatim  
  1658.   ==============================================================================
  1659.                          ##### NAND Control functions #####
  1660.   ==============================================================================  
  1661.   [..]
  1662.     This subsection provides a set of functions allowing to control dynamically
  1663.     the NAND interface.
  1664.  
  1665. @endverbatim
  1666.   * @{
  1667.   */
  1668.  
  1669.    
  1670. /**
  1671.   * @brief  Enables dynamically NAND ECC feature.
  1672.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1673.   *                the configuration information for NAND module.
  1674.   * @retval HAL status
  1675.   */    
  1676. HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  1677. {
  1678.   /* Check the NAND controller state */
  1679.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1680.   {
  1681.      return HAL_BUSY;
  1682.   }
  1683.  
  1684.   /* Update the NAND state */
  1685.   hnand->State = HAL_NAND_STATE_BUSY;
  1686.    
  1687.   /* Enable ECC feature */
  1688.   FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  1689.  
  1690.   /* Update the NAND state */
  1691.   hnand->State = HAL_NAND_STATE_READY;
  1692.  
  1693.   return HAL_OK;
  1694. }
  1695.  
  1696. /**
  1697.   * @brief  Disables dynamically FSMC_NAND ECC feature.
  1698.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1699.   *                the configuration information for NAND module.
  1700.   * @retval HAL status
  1701.   */  
  1702. HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
  1703. {
  1704.   /* Check the NAND controller state */
  1705.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1706.   {
  1707.      return HAL_BUSY;
  1708.   }
  1709.  
  1710.   /* Update the NAND state */
  1711.   hnand->State = HAL_NAND_STATE_BUSY;
  1712.    
  1713.   /* Disable ECC feature */
  1714.   FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  1715.  
  1716.   /* Update the NAND state */
  1717.   hnand->State = HAL_NAND_STATE_READY;
  1718.  
  1719.   return HAL_OK;  
  1720. }
  1721.  
  1722. /**
  1723.   * @brief  Disables dynamically NAND ECC feature.
  1724.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1725.   *                the configuration information for NAND module.
  1726.   * @param  ECCval: pointer to ECC value
  1727.   * @param  Timeout: maximum timeout to wait    
  1728.   * @retval HAL status
  1729.   */
  1730. HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  1731. {
  1732.   HAL_StatusTypeDef status = HAL_OK;
  1733.  
  1734.   /* Check the NAND controller state */
  1735.   if(hnand->State == HAL_NAND_STATE_BUSY)
  1736.   {
  1737.      return HAL_BUSY;
  1738.   }
  1739.  
  1740.   /* Update the NAND state */
  1741.   hnand->State = HAL_NAND_STATE_BUSY;  
  1742.    
  1743.   /* Get NAND ECC value */
  1744.   status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  1745.  
  1746.   /* Update the NAND state */
  1747.   hnand->State = HAL_NAND_STATE_READY;
  1748.  
  1749.   return status;  
  1750. }
  1751.  
  1752. /**
  1753.   * @}
  1754.   */
  1755.  
  1756.    
  1757. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  1758.  *  @brief   Peripheral State functions
  1759.  *
  1760. @verbatim  
  1761.   ==============================================================================
  1762.                          ##### NAND State functions #####
  1763.   ==============================================================================  
  1764.   [..]
  1765.     This subsection permits to get in run-time the status of the NAND controller
  1766.     and the data flow.
  1767.  
  1768. @endverbatim
  1769.   * @{
  1770.   */
  1771.  
  1772. /**
  1773.   * @brief  return the NAND state
  1774.   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
  1775.   *                the configuration information for NAND module.
  1776.   * @retval HAL state
  1777.   */
  1778. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  1779. {
  1780.   return hnand->State;
  1781. }
  1782.  
  1783. /**
  1784.   * @}
  1785.   */  
  1786.  
  1787. /**
  1788.   * @}
  1789.   */
  1790.  
  1791. /**
  1792.   * @}
  1793.   */
  1794.  
  1795. #endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
  1796. #endif /* HAL_NAND_MODULE_ENABLED  */
  1797.  
  1798. /**
  1799.   * @}
  1800.   */
  1801.  
  1802. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1803.