inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

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