STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_nand.c 00004 * @author MCD Application Team 00005 * @brief NAND HAL module driver. 00006 * This file provides a generic firmware to drive NAND memories mounted 00007 * as external device. 00008 * 00009 @verbatim 00010 ============================================================================== 00011 ##### How to use this driver ##### 00012 ============================================================================== 00013 [..] 00014 This driver is a generic layered driver which contains a set of APIs used to 00015 control NAND flash memories. It uses the FMC/FSMC layer functions to interface 00016 with NAND devices. This driver is used as follows: 00017 00018 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init() 00019 with control and timing parameters for both common and attribute spaces. 00020 00021 (+) Read NAND flash memory maker and device IDs using the function 00022 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef 00023 structure declared by the function caller. 00024 00025 (+) Access NAND flash memory by read/write operations using the functions 00026 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(), 00027 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(), 00028 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(), 00029 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b() 00030 to read/write page(s)/spare area(s). These functions use specific device 00031 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef 00032 structure. The read/write address information is contained by the Nand_Address_Typedef 00033 structure passed as parameter. 00034 00035 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset(). 00036 00037 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block(). 00038 The erase block address information is contained in the Nand_Address_Typedef 00039 structure passed as parameter. 00040 00041 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status(). 00042 00043 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/ 00044 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction 00045 feature or the function HAL_NAND_GetECC() to get the ECC correction code. 00046 00047 (+) You can monitor the NAND device HAL state by calling the function 00048 HAL_NAND_GetState() 00049 00050 [..] 00051 (@) This driver is a set of generic APIs which handle standard NAND flash operations. 00052 If a NAND flash device contains different operations and/or implementations, 00053 it should be implemented separately. 00054 00055 *** Callback registration *** 00056 ============================================= 00057 [..] 00058 The compilation define USE_HAL_NAND_REGISTER_CALLBACKS when set to 1 00059 allows the user to configure dynamically the driver callbacks. 00060 00061 Use Functions HAL_NAND_RegisterCallback() to register a user callback, 00062 it allows to register following callbacks: 00063 (+) MspInitCallback : NAND MspInit. 00064 (+) MspDeInitCallback : NAND MspDeInit. 00065 This function takes as parameters the HAL peripheral handle, the Callback ID 00066 and a pointer to the user callback function. 00067 00068 Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default 00069 weak (surcharged) function. It allows to reset following callbacks: 00070 (+) MspInitCallback : NAND MspInit. 00071 (+) MspDeInitCallback : NAND MspDeInit. 00072 This function) takes as parameters the HAL peripheral handle and the Callback ID. 00073 00074 By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET 00075 all callbacks are reset to the corresponding legacy weak (surcharged) functions. 00076 Exception done for MspInit and MspDeInit callbacks that are respectively 00077 reset to the legacy weak (surcharged) functions in the HAL_NAND_Init 00078 and HAL_NAND_DeInit only when these callbacks are null (not registered beforehand). 00079 If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit 00080 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) 00081 00082 Callbacks can be registered/unregistered in READY state only. 00083 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00084 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00085 during the Init/DeInit. 00086 In that case first register the MspInit/MspDeInit user callbacks 00087 using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit 00088 or HAL_NAND_Init function. 00089 00090 When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or 00091 not defined, the callback registering feature is not available 00092 and weak (surcharged) callbacks are used. 00093 00094 @endverbatim 00095 ****************************************************************************** 00096 * @attention 00097 * 00098 * <h2><center>© Copyright (c) 2017 STMicroelectronics. 00099 * All rights reserved.</center></h2> 00100 * 00101 * This software component is licensed by ST under BSD 3-Clause license, 00102 * the "License"; You may not use this file except in compliance with the 00103 * License. You may obtain a copy of the License at: 00104 * opensource.org/licenses/BSD-3-Clause 00105 * 00106 ****************************************************************************** 00107 */ 00108 00109 /* Includes ------------------------------------------------------------------*/ 00110 #include "stm32f4xx_hal.h" 00111 00112 #if defined(FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00113 00114 /** @addtogroup STM32F4xx_HAL_Driver 00115 * @{ 00116 */ 00117 00118 #ifdef HAL_NAND_MODULE_ENABLED 00119 00120 /** @defgroup NAND NAND 00121 * @brief NAND HAL module driver 00122 * @{ 00123 */ 00124 00125 /* Private typedef -----------------------------------------------------------*/ 00126 /* Private Constants ------------------------------------------------------------*/ 00127 /* Private macro -------------------------------------------------------------*/ 00128 /* Private variables ---------------------------------------------------------*/ 00129 /* Private function prototypes -----------------------------------------------*/ 00130 /* Exported functions ---------------------------------------------------------*/ 00131 00132 /** @defgroup NAND_Exported_Functions NAND Exported Functions 00133 * @{ 00134 */ 00135 00136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions 00137 * @brief Initialization and Configuration functions 00138 * 00139 @verbatim 00140 ============================================================================== 00141 ##### NAND Initialization and de-initialization functions ##### 00142 ============================================================================== 00143 [..] 00144 This section provides functions allowing to initialize/de-initialize 00145 the NAND memory 00146 00147 @endverbatim 00148 * @{ 00149 */ 00150 00151 /** 00152 * @brief Perform NAND memory Initialization sequence 00153 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00154 * the configuration information for NAND module. 00155 * @param ComSpace_Timing pointer to Common space timing structure 00156 * @param AttSpace_Timing pointer to Attribute space timing structure 00157 * @retval HAL status 00158 */ 00159 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, 00160 FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing) 00161 { 00162 /* Check the NAND handle state */ 00163 if (hnand == NULL) 00164 { 00165 return HAL_ERROR; 00166 } 00167 00168 if (hnand->State == HAL_NAND_STATE_RESET) 00169 { 00170 /* Allocate lock resource and initialize it */ 00171 hnand->Lock = HAL_UNLOCKED; 00172 00173 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00174 if (hnand->MspInitCallback == NULL) 00175 { 00176 hnand->MspInitCallback = HAL_NAND_MspInit; 00177 } 00178 hnand->ItCallback = HAL_NAND_ITCallback; 00179 00180 /* Init the low level hardware */ 00181 hnand->MspInitCallback(hnand); 00182 #else 00183 /* Initialize the low level hardware (MSP) */ 00184 HAL_NAND_MspInit(hnand); 00185 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00186 } 00187 00188 /* Initialize NAND control Interface */ 00189 (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init)); 00190 00191 /* Initialize NAND common space timing Interface */ 00192 (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank); 00193 00194 /* Initialize NAND attribute space timing Interface */ 00195 (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank); 00196 00197 /* Enable the NAND device */ 00198 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00199 __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank); 00200 #else 00201 __FMC_NAND_ENABLE(hnand->Instance); 00202 #endif 00203 00204 /* Update the NAND controller state */ 00205 hnand->State = HAL_NAND_STATE_READY; 00206 00207 return HAL_OK; 00208 } 00209 00210 /** 00211 * @brief Perform NAND memory De-Initialization sequence 00212 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00213 * the configuration information for NAND module. 00214 * @retval HAL status 00215 */ 00216 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand) 00217 { 00218 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00219 if (hnand->MspDeInitCallback == NULL) 00220 { 00221 hnand->MspDeInitCallback = HAL_NAND_MspDeInit; 00222 } 00223 00224 /* DeInit the low level hardware */ 00225 hnand->MspDeInitCallback(hnand); 00226 #else 00227 /* Initialize the low level hardware (MSP) */ 00228 HAL_NAND_MspDeInit(hnand); 00229 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00230 00231 /* Configure the NAND registers with their reset values */ 00232 (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank); 00233 00234 /* Reset the NAND controller state */ 00235 hnand->State = HAL_NAND_STATE_RESET; 00236 00237 /* Release Lock */ 00238 __HAL_UNLOCK(hnand); 00239 00240 return HAL_OK; 00241 } 00242 00243 /** 00244 * @brief NAND MSP Init 00245 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00246 * the configuration information for NAND module. 00247 * @retval None 00248 */ 00249 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand) 00250 { 00251 /* Prevent unused argument(s) compilation warning */ 00252 UNUSED(hnand); 00253 00254 /* NOTE : This function Should not be modified, when the callback is needed, 00255 the HAL_NAND_MspInit could be implemented in the user file 00256 */ 00257 } 00258 00259 /** 00260 * @brief NAND MSP DeInit 00261 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00262 * the configuration information for NAND module. 00263 * @retval None 00264 */ 00265 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand) 00266 { 00267 /* Prevent unused argument(s) compilation warning */ 00268 UNUSED(hnand); 00269 00270 /* NOTE : This function Should not be modified, when the callback is needed, 00271 the HAL_NAND_MspDeInit could be implemented in the user file 00272 */ 00273 } 00274 00275 00276 /** 00277 * @brief This function handles NAND device interrupt request. 00278 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00279 * the configuration information for NAND module. 00280 * @retval HAL status 00281 */ 00282 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand) 00283 { 00284 /* Check NAND interrupt Rising edge flag */ 00285 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE)) 00286 { 00287 /* NAND interrupt callback*/ 00288 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00289 hnand->ItCallback(hnand); 00290 #else 00291 HAL_NAND_ITCallback(hnand); 00292 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00293 00294 /* Clear NAND interrupt Rising edge pending bit */ 00295 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00296 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE); 00297 #else 00298 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE); 00299 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */ 00300 } 00301 00302 /* Check NAND interrupt Level flag */ 00303 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL)) 00304 { 00305 /* NAND interrupt callback*/ 00306 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00307 hnand->ItCallback(hnand); 00308 #else 00309 HAL_NAND_ITCallback(hnand); 00310 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00311 00312 /* Clear NAND interrupt Level pending bit */ 00313 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00314 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL); 00315 #else 00316 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL); 00317 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */ 00318 } 00319 00320 /* Check NAND interrupt Falling edge flag */ 00321 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE)) 00322 { 00323 /* NAND interrupt callback*/ 00324 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00325 hnand->ItCallback(hnand); 00326 #else 00327 HAL_NAND_ITCallback(hnand); 00328 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00329 00330 /* Clear NAND interrupt Falling edge pending bit */ 00331 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00332 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE); 00333 #else 00334 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE); 00335 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */ 00336 } 00337 00338 /* Check NAND interrupt FIFO empty flag */ 00339 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT)) 00340 { 00341 /* NAND interrupt callback*/ 00342 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 00343 hnand->ItCallback(hnand); 00344 #else 00345 HAL_NAND_ITCallback(hnand); 00346 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ 00347 00348 /* Clear NAND interrupt FIFO empty pending bit */ 00349 #if defined(FMC_Bank2_3) || defined(FSMC_Bank2_3) 00350 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT); 00351 #else 00352 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT); 00353 #endif /* FMC_Bank2_3 || FSMC_Bank2_3 */ 00354 } 00355 00356 } 00357 00358 /** 00359 * @brief NAND interrupt feature callback 00360 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00361 * the configuration information for NAND module. 00362 * @retval None 00363 */ 00364 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand) 00365 { 00366 /* Prevent unused argument(s) compilation warning */ 00367 UNUSED(hnand); 00368 00369 /* NOTE : This function Should not be modified, when the callback is needed, 00370 the HAL_NAND_ITCallback could be implemented in the user file 00371 */ 00372 } 00373 00374 /** 00375 * @} 00376 */ 00377 00378 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions 00379 * @brief Input Output and memory control functions 00380 * 00381 @verbatim 00382 ============================================================================== 00383 ##### NAND Input and Output functions ##### 00384 ============================================================================== 00385 [..] 00386 This section provides functions allowing to use and control the NAND 00387 memory 00388 00389 @endverbatim 00390 * @{ 00391 */ 00392 00393 /** 00394 * @brief Read the NAND memory electronic signature 00395 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00396 * the configuration information for NAND module. 00397 * @param pNAND_ID NAND ID structure 00398 * @retval HAL status 00399 */ 00400 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID) 00401 { 00402 __IO uint32_t data = 0; 00403 __IO uint32_t data1 = 0; 00404 uint32_t deviceaddress; 00405 00406 /* Check the NAND controller state */ 00407 if (hnand->State == HAL_NAND_STATE_BUSY) 00408 { 00409 return HAL_BUSY; 00410 } 00411 else if (hnand->State == HAL_NAND_STATE_READY) 00412 { 00413 /* Process Locked */ 00414 __HAL_LOCK(hnand); 00415 00416 /* Update the NAND controller state */ 00417 hnand->State = HAL_NAND_STATE_BUSY; 00418 00419 /* Identify the device address */ 00420 #if defined(FMC_Bank2_3) 00421 if (hnand->Init.NandBank == FMC_NAND_BANK2) 00422 { 00423 deviceaddress = NAND_DEVICE1; 00424 } 00425 else 00426 { 00427 deviceaddress = NAND_DEVICE2; 00428 } 00429 #else 00430 deviceaddress = NAND_DEVICE; 00431 #endif 00432 00433 /* Send Read ID command sequence */ 00434 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID; 00435 __DSB(); 00436 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; 00437 __DSB(); 00438 00439 /* Read the electronic signature from NAND flash */ 00440 #ifdef FSMC_PCR2_PWID 00441 if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) 00442 #else /* FMC_PCR2_PWID is defined */ 00443 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8) 00444 #endif 00445 { 00446 data = *(__IO uint32_t *)deviceaddress; 00447 00448 /* Return the data read */ 00449 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); 00450 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data); 00451 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data); 00452 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data); 00453 } 00454 else 00455 { 00456 data = *(__IO uint32_t *)deviceaddress; 00457 data1 = *((__IO uint32_t *)deviceaddress + 4); 00458 00459 /* Return the data read */ 00460 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); 00461 pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data); 00462 pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1); 00463 pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1); 00464 } 00465 00466 /* Update the NAND controller state */ 00467 hnand->State = HAL_NAND_STATE_READY; 00468 00469 /* Process unlocked */ 00470 __HAL_UNLOCK(hnand); 00471 } 00472 else 00473 { 00474 return HAL_ERROR; 00475 } 00476 00477 return HAL_OK; 00478 } 00479 00480 /** 00481 * @brief NAND memory reset 00482 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00483 * the configuration information for NAND module. 00484 * @retval HAL status 00485 */ 00486 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand) 00487 { 00488 uint32_t deviceaddress; 00489 00490 /* Check the NAND controller state */ 00491 if (hnand->State == HAL_NAND_STATE_BUSY) 00492 { 00493 return HAL_BUSY; 00494 } 00495 else if (hnand->State == HAL_NAND_STATE_READY) 00496 { 00497 /* Process Locked */ 00498 __HAL_LOCK(hnand); 00499 00500 /* Update the NAND controller state */ 00501 hnand->State = HAL_NAND_STATE_BUSY; 00502 00503 /* Identify the device address */ 00504 #if defined(FMC_Bank2_3) 00505 if (hnand->Init.NandBank == FMC_NAND_BANK2) 00506 { 00507 deviceaddress = NAND_DEVICE1; 00508 } 00509 else 00510 { 00511 deviceaddress = NAND_DEVICE2; 00512 } 00513 #else 00514 deviceaddress = NAND_DEVICE; 00515 #endif 00516 00517 /* Send NAND reset command */ 00518 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF; 00519 00520 /* Update the NAND controller state */ 00521 hnand->State = HAL_NAND_STATE_READY; 00522 00523 /* Process unlocked */ 00524 __HAL_UNLOCK(hnand); 00525 } 00526 else 00527 { 00528 return HAL_ERROR; 00529 } 00530 00531 return HAL_OK; 00532 00533 } 00534 00535 /** 00536 * @brief Configure the device: Enter the physical parameters of the device 00537 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00538 * the configuration information for NAND module. 00539 * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure 00540 * @retval HAL status 00541 */ 00542 HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig) 00543 { 00544 hnand->Config.PageSize = pDeviceConfig->PageSize; 00545 hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize; 00546 hnand->Config.BlockSize = pDeviceConfig->BlockSize; 00547 hnand->Config.BlockNbr = pDeviceConfig->BlockNbr; 00548 hnand->Config.PlaneSize = pDeviceConfig->PlaneSize; 00549 hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr; 00550 hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable; 00551 00552 return HAL_OK; 00553 } 00554 00555 /** 00556 * @brief Read Page(s) from NAND memory block (8-bits addressing) 00557 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00558 * the configuration information for NAND module. 00559 * @param pAddress pointer to NAND address structure 00560 * @param pBuffer pointer to destination read buffer 00561 * @param NumPageToRead number of pages to read from block 00562 * @retval HAL status 00563 */ 00564 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, 00565 uint32_t NumPageToRead) 00566 { 00567 uint32_t index; 00568 uint32_t tickstart; 00569 uint32_t deviceaddress; 00570 uint32_t numpagesread = 0U; 00571 uint32_t nandaddress; 00572 uint32_t nbpages = NumPageToRead; 00573 uint8_t *buff = pBuffer; 00574 00575 /* Check the NAND controller state */ 00576 if (hnand->State == HAL_NAND_STATE_BUSY) 00577 { 00578 return HAL_BUSY; 00579 } 00580 else if (hnand->State == HAL_NAND_STATE_READY) 00581 { 00582 /* Process Locked */ 00583 __HAL_LOCK(hnand); 00584 00585 /* Update the NAND controller state */ 00586 hnand->State = HAL_NAND_STATE_BUSY; 00587 00588 /* Identify the device address */ 00589 #if defined(FMC_Bank2_3) 00590 if (hnand->Init.NandBank == FMC_NAND_BANK2) 00591 { 00592 deviceaddress = NAND_DEVICE1; 00593 } 00594 else 00595 { 00596 deviceaddress = NAND_DEVICE2; 00597 } 00598 #else 00599 deviceaddress = NAND_DEVICE; 00600 #endif 00601 00602 /* NAND raw address calculation */ 00603 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 00604 00605 /* Page(s) read loop */ 00606 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00607 { 00608 /* Send read page command sequence */ 00609 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 00610 __DSB(); 00611 00612 /* Cards with page size <= 512 bytes */ 00613 if ((hnand->Config.PageSize) <= 512U) 00614 { 00615 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00616 { 00617 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00618 __DSB(); 00619 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00620 __DSB(); 00621 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00622 __DSB(); 00623 } 00624 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00625 { 00626 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00627 __DSB(); 00628 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00629 __DSB(); 00630 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00631 __DSB(); 00632 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 00633 __DSB(); 00634 } 00635 } 00636 else /* (hnand->Config.PageSize) > 512 */ 00637 { 00638 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00639 { 00640 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00641 __DSB(); 00642 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00643 __DSB(); 00644 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00645 __DSB(); 00646 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00647 __DSB(); 00648 } 00649 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00650 { 00651 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00652 __DSB(); 00653 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00654 __DSB(); 00655 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00656 __DSB(); 00657 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00658 __DSB(); 00659 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 00660 __DSB(); 00661 } 00662 } 00663 00664 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 00665 __DSB(); 00666 00667 00668 if (hnand->Config.ExtraCommandEnable == ENABLE) 00669 { 00670 /* Get tick */ 00671 tickstart = HAL_GetTick(); 00672 00673 /* Read status until NAND is ready */ 00674 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 00675 { 00676 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 00677 { 00678 /* Update the NAND controller state */ 00679 hnand->State = HAL_NAND_STATE_ERROR; 00680 00681 /* Process unlocked */ 00682 __HAL_UNLOCK(hnand); 00683 00684 return HAL_TIMEOUT; 00685 } 00686 } 00687 00688 /* Go back to read mode */ 00689 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); 00690 __DSB(); 00691 } 00692 00693 /* Get Data into Buffer */ 00694 for (index = 0U; index < hnand->Config.PageSize; index++) 00695 { 00696 *buff = *(uint8_t *)deviceaddress; 00697 buff++; 00698 } 00699 00700 /* Increment read pages number */ 00701 numpagesread++; 00702 00703 /* Decrement pages to read */ 00704 nbpages--; 00705 00706 /* Increment the NAND address */ 00707 nandaddress = (uint32_t)(nandaddress + 1U); 00708 } 00709 00710 /* Update the NAND controller state */ 00711 hnand->State = HAL_NAND_STATE_READY; 00712 00713 /* Process unlocked */ 00714 __HAL_UNLOCK(hnand); 00715 } 00716 else 00717 { 00718 return HAL_ERROR; 00719 } 00720 00721 return HAL_OK; 00722 } 00723 00724 /** 00725 * @brief Read Page(s) from NAND memory block (16-bits addressing) 00726 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00727 * the configuration information for NAND module. 00728 * @param pAddress pointer to NAND address structure 00729 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned 00730 * @param NumPageToRead number of pages to read from block 00731 * @retval HAL status 00732 */ 00733 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, 00734 uint32_t NumPageToRead) 00735 { 00736 uint32_t index; 00737 uint32_t tickstart; 00738 uint32_t deviceaddress; 00739 uint32_t numpagesread = 0U; 00740 uint32_t nandaddress; 00741 uint32_t nbpages = NumPageToRead; 00742 uint16_t *buff = pBuffer; 00743 00744 /* Check the NAND controller state */ 00745 if (hnand->State == HAL_NAND_STATE_BUSY) 00746 { 00747 return HAL_BUSY; 00748 } 00749 else if (hnand->State == HAL_NAND_STATE_READY) 00750 { 00751 /* Process Locked */ 00752 __HAL_LOCK(hnand); 00753 00754 /* Update the NAND controller state */ 00755 hnand->State = HAL_NAND_STATE_BUSY; 00756 00757 /* Identify the device address */ 00758 #if defined(FMC_Bank2_3) 00759 if (hnand->Init.NandBank == FMC_NAND_BANK2) 00760 { 00761 deviceaddress = NAND_DEVICE1; 00762 } 00763 else 00764 { 00765 deviceaddress = NAND_DEVICE2; 00766 } 00767 #else 00768 deviceaddress = NAND_DEVICE; 00769 #endif 00770 00771 /* NAND raw address calculation */ 00772 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 00773 00774 /* Page(s) read loop */ 00775 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00776 { 00777 /* Send read page command sequence */ 00778 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 00779 __DSB(); 00780 00781 /* Cards with page size <= 512 bytes */ 00782 if ((hnand->Config.PageSize) <= 512U) 00783 { 00784 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00785 { 00786 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00787 __DSB(); 00788 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00789 __DSB(); 00790 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00791 __DSB(); 00792 } 00793 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00794 { 00795 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00796 __DSB(); 00797 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00798 __DSB(); 00799 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00800 __DSB(); 00801 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 00802 __DSB(); 00803 } 00804 } 00805 else /* (hnand->Config.PageSize) > 512 */ 00806 { 00807 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00808 { 00809 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00810 __DSB(); 00811 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00812 __DSB(); 00813 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00814 __DSB(); 00815 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00816 __DSB(); 00817 } 00818 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00819 { 00820 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00821 __DSB(); 00822 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00823 __DSB(); 00824 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00825 __DSB(); 00826 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00827 __DSB(); 00828 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 00829 __DSB(); 00830 } 00831 } 00832 00833 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 00834 __DSB(); 00835 00836 if (hnand->Config.ExtraCommandEnable == ENABLE) 00837 { 00838 /* Get tick */ 00839 tickstart = HAL_GetTick(); 00840 00841 /* Read status until NAND is ready */ 00842 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 00843 { 00844 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 00845 { 00846 /* Update the NAND controller state */ 00847 hnand->State = HAL_NAND_STATE_ERROR; 00848 00849 /* Process unlocked */ 00850 __HAL_UNLOCK(hnand); 00851 00852 return HAL_TIMEOUT; 00853 } 00854 } 00855 00856 /* Go back to read mode */ 00857 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); 00858 __DSB(); 00859 } 00860 00861 /* Calculate PageSize */ 00862 #if defined(FSMC_PCR2_PWID) 00863 if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) 00864 #else 00865 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8) 00866 #endif /* FSMC_PCR2_PWID */ 00867 { 00868 hnand->Config.PageSize = hnand->Config.PageSize / 2U; 00869 } 00870 else 00871 { 00872 /* Do nothing */ 00873 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/ 00874 } 00875 00876 /* Get Data into Buffer */ 00877 for (index = 0U; index < hnand->Config.PageSize; index++) 00878 { 00879 *buff = *(uint16_t *)deviceaddress; 00880 buff++; 00881 } 00882 00883 /* Increment read pages number */ 00884 numpagesread++; 00885 00886 /* Decrement pages to read */ 00887 nbpages--; 00888 00889 /* Increment the NAND address */ 00890 nandaddress = (uint32_t)(nandaddress + 1U); 00891 } 00892 00893 /* Update the NAND controller state */ 00894 hnand->State = HAL_NAND_STATE_READY; 00895 00896 /* Process unlocked */ 00897 __HAL_UNLOCK(hnand); 00898 } 00899 else 00900 { 00901 return HAL_ERROR; 00902 } 00903 00904 return HAL_OK; 00905 } 00906 00907 /** 00908 * @brief Write Page(s) to NAND memory block (8-bits addressing) 00909 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00910 * the configuration information for NAND module. 00911 * @param pAddress pointer to NAND address structure 00912 * @param pBuffer pointer to source buffer to write 00913 * @param NumPageToWrite number of pages to write to block 00914 * @retval HAL status 00915 */ 00916 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, 00917 uint32_t NumPageToWrite) 00918 { 00919 uint32_t index; 00920 uint32_t tickstart; 00921 uint32_t deviceaddress; 00922 uint32_t numpageswritten = 0U; 00923 uint32_t nandaddress; 00924 uint32_t nbpages = NumPageToWrite; 00925 uint8_t *buff = pBuffer; 00926 00927 /* Check the NAND controller state */ 00928 if (hnand->State == HAL_NAND_STATE_BUSY) 00929 { 00930 return HAL_BUSY; 00931 } 00932 else if (hnand->State == HAL_NAND_STATE_READY) 00933 { 00934 /* Process Locked */ 00935 __HAL_LOCK(hnand); 00936 00937 /* Update the NAND controller state */ 00938 hnand->State = HAL_NAND_STATE_BUSY; 00939 00940 /* Identify the device address */ 00941 #if defined(FMC_Bank2_3) 00942 if (hnand->Init.NandBank == FMC_NAND_BANK2) 00943 { 00944 deviceaddress = NAND_DEVICE1; 00945 } 00946 else 00947 { 00948 deviceaddress = NAND_DEVICE2; 00949 } 00950 #else 00951 deviceaddress = NAND_DEVICE; 00952 #endif 00953 00954 /* NAND raw address calculation */ 00955 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 00956 00957 /* Page(s) write loop */ 00958 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00959 { 00960 /* Send write page command sequence */ 00961 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 00962 __DSB(); 00963 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 00964 __DSB(); 00965 00966 /* Cards with page size <= 512 bytes */ 00967 if ((hnand->Config.PageSize) <= 512U) 00968 { 00969 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00970 { 00971 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00972 __DSB(); 00973 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00974 __DSB(); 00975 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00976 __DSB(); 00977 } 00978 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00979 { 00980 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00981 __DSB(); 00982 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00983 __DSB(); 00984 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 00985 __DSB(); 00986 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 00987 __DSB(); 00988 } 00989 } 00990 else /* (hnand->Config.PageSize) > 512 */ 00991 { 00992 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 00993 { 00994 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00995 __DSB(); 00996 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 00997 __DSB(); 00998 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 00999 __DSB(); 01000 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01001 __DSB(); 01002 } 01003 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01004 { 01005 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01006 __DSB(); 01007 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01008 __DSB(); 01009 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01010 __DSB(); 01011 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01012 __DSB(); 01013 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01014 __DSB(); 01015 } 01016 } 01017 01018 /* Write data to memory */ 01019 for (index = 0U; index < hnand->Config.PageSize; index++) 01020 { 01021 *(__IO uint8_t *)deviceaddress = *buff; 01022 buff++; 01023 __DSB(); 01024 } 01025 01026 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01027 __DSB(); 01028 01029 /* Get tick */ 01030 tickstart = HAL_GetTick(); 01031 01032 /* Read status until NAND is ready */ 01033 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01034 { 01035 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01036 { 01037 /* Update the NAND controller state */ 01038 hnand->State = HAL_NAND_STATE_ERROR; 01039 01040 /* Process unlocked */ 01041 __HAL_UNLOCK(hnand); 01042 01043 return HAL_TIMEOUT; 01044 } 01045 } 01046 01047 /* Increment written pages number */ 01048 numpageswritten++; 01049 01050 /* Decrement pages to write */ 01051 nbpages--; 01052 01053 /* Increment the NAND address */ 01054 nandaddress = (uint32_t)(nandaddress + 1U); 01055 } 01056 01057 /* Update the NAND controller state */ 01058 hnand->State = HAL_NAND_STATE_READY; 01059 01060 /* Process unlocked */ 01061 __HAL_UNLOCK(hnand); 01062 } 01063 else 01064 { 01065 return HAL_ERROR; 01066 } 01067 01068 return HAL_OK; 01069 } 01070 01071 /** 01072 * @brief Write Page(s) to NAND memory block (16-bits addressing) 01073 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01074 * the configuration information for NAND module. 01075 * @param pAddress pointer to NAND address structure 01076 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned 01077 * @param NumPageToWrite number of pages to write to block 01078 * @retval HAL status 01079 */ 01080 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, 01081 uint32_t NumPageToWrite) 01082 { 01083 uint32_t index; 01084 uint32_t tickstart; 01085 uint32_t deviceaddress; 01086 uint32_t numpageswritten = 0U; 01087 uint32_t nandaddress; 01088 uint32_t nbpages = NumPageToWrite; 01089 uint16_t *buff = pBuffer; 01090 01091 /* Check the NAND controller state */ 01092 if (hnand->State == HAL_NAND_STATE_BUSY) 01093 { 01094 return HAL_BUSY; 01095 } 01096 else if (hnand->State == HAL_NAND_STATE_READY) 01097 { 01098 /* Process Locked */ 01099 __HAL_LOCK(hnand); 01100 01101 /* Update the NAND controller state */ 01102 hnand->State = HAL_NAND_STATE_BUSY; 01103 01104 /* Identify the device address */ 01105 #if defined(FMC_Bank2_3) 01106 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01107 { 01108 deviceaddress = NAND_DEVICE1; 01109 } 01110 else 01111 { 01112 deviceaddress = NAND_DEVICE2; 01113 } 01114 #else 01115 deviceaddress = NAND_DEVICE; 01116 #endif 01117 01118 /* NAND raw address calculation */ 01119 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 01120 01121 /* Page(s) write loop */ 01122 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01123 { 01124 /* Send write page command sequence */ 01125 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 01126 __DSB(); 01127 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 01128 __DSB(); 01129 01130 /* Cards with page size <= 512 bytes */ 01131 if ((hnand->Config.PageSize) <= 512U) 01132 { 01133 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01134 { 01135 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01136 __DSB(); 01137 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01138 __DSB(); 01139 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01140 __DSB(); 01141 } 01142 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01143 { 01144 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01145 __DSB(); 01146 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01147 __DSB(); 01148 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01149 __DSB(); 01150 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01151 __DSB(); 01152 } 01153 } 01154 else /* (hnand->Config.PageSize) > 512 */ 01155 { 01156 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01157 { 01158 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01159 __DSB(); 01160 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01161 __DSB(); 01162 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01163 __DSB(); 01164 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01165 __DSB(); 01166 } 01167 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01168 { 01169 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01170 __DSB(); 01171 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01172 __DSB(); 01173 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01174 __DSB(); 01175 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01176 __DSB(); 01177 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01178 __DSB(); 01179 } 01180 } 01181 01182 /* Calculate PageSize */ 01183 #if defined(FSMC_PCR2_PWID) 01184 if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) 01185 #else 01186 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8) 01187 #endif /* FSMC_PCR2_PWID */ 01188 { 01189 hnand->Config.PageSize = hnand->Config.PageSize / 2U; 01190 } 01191 else 01192 { 01193 /* Do nothing */ 01194 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/ 01195 } 01196 01197 /* Write data to memory */ 01198 for (index = 0U; index < hnand->Config.PageSize; index++) 01199 { 01200 *(__IO uint16_t *)deviceaddress = *buff; 01201 buff++; 01202 __DSB(); 01203 } 01204 01205 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01206 __DSB(); 01207 01208 /* Get tick */ 01209 tickstart = HAL_GetTick(); 01210 01211 /* Read status until NAND is ready */ 01212 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01213 { 01214 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01215 { 01216 /* Update the NAND controller state */ 01217 hnand->State = HAL_NAND_STATE_ERROR; 01218 01219 /* Process unlocked */ 01220 __HAL_UNLOCK(hnand); 01221 01222 return HAL_TIMEOUT; 01223 } 01224 } 01225 01226 /* Increment written pages number */ 01227 numpageswritten++; 01228 01229 /* Decrement pages to write */ 01230 nbpages--; 01231 01232 /* Increment the NAND address */ 01233 nandaddress = (uint32_t)(nandaddress + 1U); 01234 } 01235 01236 /* Update the NAND controller state */ 01237 hnand->State = HAL_NAND_STATE_READY; 01238 01239 /* Process unlocked */ 01240 __HAL_UNLOCK(hnand); 01241 } 01242 else 01243 { 01244 return HAL_ERROR; 01245 } 01246 01247 return HAL_OK; 01248 } 01249 01250 /** 01251 * @brief Read Spare area(s) from NAND memory (8-bits addressing) 01252 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01253 * the configuration information for NAND module. 01254 * @param pAddress pointer to NAND address structure 01255 * @param pBuffer pointer to source buffer to write 01256 * @param NumSpareAreaToRead Number of spare area to read 01257 * @retval HAL status 01258 */ 01259 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, 01260 uint32_t NumSpareAreaToRead) 01261 { 01262 uint32_t index; 01263 uint32_t tickstart; 01264 uint32_t deviceaddress; 01265 uint32_t numsparearearead = 0U; 01266 uint32_t nandaddress; 01267 uint32_t columnaddress; 01268 uint32_t nbspare = NumSpareAreaToRead; 01269 uint8_t *buff = pBuffer; 01270 01271 /* Check the NAND controller state */ 01272 if (hnand->State == HAL_NAND_STATE_BUSY) 01273 { 01274 return HAL_BUSY; 01275 } 01276 else if (hnand->State == HAL_NAND_STATE_READY) 01277 { 01278 /* Process Locked */ 01279 __HAL_LOCK(hnand); 01280 01281 /* Update the NAND controller state */ 01282 hnand->State = HAL_NAND_STATE_BUSY; 01283 01284 /* Identify the device address */ 01285 #if defined(FMC_Bank2_3) 01286 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01287 { 01288 deviceaddress = NAND_DEVICE1; 01289 } 01290 else 01291 { 01292 deviceaddress = NAND_DEVICE2; 01293 } 01294 #else 01295 deviceaddress = NAND_DEVICE; 01296 #endif 01297 01298 /* NAND raw address calculation */ 01299 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 01300 01301 /* Column in page address */ 01302 columnaddress = COLUMN_ADDRESS(hnand); 01303 01304 /* Spare area(s) read loop */ 01305 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01306 { 01307 /* Cards with page size <= 512 bytes */ 01308 if ((hnand->Config.PageSize) <= 512U) 01309 { 01310 /* Send read spare area command sequence */ 01311 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; 01312 __DSB(); 01313 01314 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01315 { 01316 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01317 __DSB(); 01318 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01319 __DSB(); 01320 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01321 __DSB(); 01322 } 01323 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01324 { 01325 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01326 __DSB(); 01327 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01328 __DSB(); 01329 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01330 __DSB(); 01331 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01332 __DSB(); 01333 } 01334 } 01335 else /* (hnand->Config.PageSize) > 512 */ 01336 { 01337 /* Send read spare area command sequence */ 01338 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 01339 __DSB(); 01340 01341 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01342 { 01343 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01344 __DSB(); 01345 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01346 __DSB(); 01347 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01348 __DSB(); 01349 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01350 __DSB(); 01351 } 01352 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01353 { 01354 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01355 __DSB(); 01356 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01357 __DSB(); 01358 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01359 __DSB(); 01360 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01361 __DSB(); 01362 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01363 __DSB(); 01364 } 01365 } 01366 01367 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 01368 __DSB(); 01369 01370 if (hnand->Config.ExtraCommandEnable == ENABLE) 01371 { 01372 /* Get tick */ 01373 tickstart = HAL_GetTick(); 01374 01375 /* Read status until NAND is ready */ 01376 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01377 { 01378 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01379 { 01380 /* Update the NAND controller state */ 01381 hnand->State = HAL_NAND_STATE_ERROR; 01382 01383 /* Process unlocked */ 01384 __HAL_UNLOCK(hnand); 01385 01386 return HAL_TIMEOUT; 01387 } 01388 } 01389 01390 /* Go back to read mode */ 01391 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); 01392 __DSB(); 01393 } 01394 01395 /* Get Data into Buffer */ 01396 for (index = 0U; index < hnand->Config.SpareAreaSize; index++) 01397 { 01398 *buff = *(uint8_t *)deviceaddress; 01399 buff++; 01400 } 01401 01402 /* Increment read spare areas number */ 01403 numsparearearead++; 01404 01405 /* Decrement spare areas to read */ 01406 nbspare--; 01407 01408 /* Increment the NAND address */ 01409 nandaddress = (uint32_t)(nandaddress + 1U); 01410 } 01411 01412 /* Update the NAND controller state */ 01413 hnand->State = HAL_NAND_STATE_READY; 01414 01415 /* Process unlocked */ 01416 __HAL_UNLOCK(hnand); 01417 } 01418 else 01419 { 01420 return HAL_ERROR; 01421 } 01422 01423 return HAL_OK; 01424 } 01425 01426 /** 01427 * @brief Read Spare area(s) from NAND memory (16-bits addressing) 01428 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01429 * the configuration information for NAND module. 01430 * @param pAddress pointer to NAND address structure 01431 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. 01432 * @param NumSpareAreaToRead Number of spare area to read 01433 * @retval HAL status 01434 */ 01435 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, 01436 uint16_t *pBuffer, uint32_t NumSpareAreaToRead) 01437 { 01438 uint32_t index; 01439 uint32_t tickstart; 01440 uint32_t deviceaddress; 01441 uint32_t numsparearearead = 0U; 01442 uint32_t nandaddress; 01443 uint32_t columnaddress; 01444 uint32_t nbspare = NumSpareAreaToRead; 01445 uint16_t *buff = pBuffer; 01446 01447 /* Check the NAND controller state */ 01448 if (hnand->State == HAL_NAND_STATE_BUSY) 01449 { 01450 return HAL_BUSY; 01451 } 01452 else if (hnand->State == HAL_NAND_STATE_READY) 01453 { 01454 /* Process Locked */ 01455 __HAL_LOCK(hnand); 01456 01457 /* Update the NAND controller state */ 01458 hnand->State = HAL_NAND_STATE_BUSY; 01459 01460 /* Identify the device address */ 01461 #if defined(FMC_Bank2_3) 01462 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01463 { 01464 deviceaddress = NAND_DEVICE1; 01465 } 01466 else 01467 { 01468 deviceaddress = NAND_DEVICE2; 01469 } 01470 #else 01471 deviceaddress = NAND_DEVICE; 01472 #endif 01473 01474 /* NAND raw address calculation */ 01475 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 01476 01477 /* Column in page address */ 01478 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand)); 01479 01480 /* Spare area(s) read loop */ 01481 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01482 { 01483 /* Cards with page size <= 512 bytes */ 01484 if ((hnand->Config.PageSize) <= 512U) 01485 { 01486 /* Send read spare area command sequence */ 01487 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; 01488 __DSB(); 01489 01490 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01491 { 01492 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01493 __DSB(); 01494 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01495 __DSB(); 01496 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01497 __DSB(); 01498 } 01499 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01500 { 01501 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01502 __DSB(); 01503 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01504 __DSB(); 01505 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01506 __DSB(); 01507 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01508 __DSB(); 01509 } 01510 } 01511 else /* (hnand->Config.PageSize) > 512 */ 01512 { 01513 /* Send read spare area command sequence */ 01514 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 01515 __DSB(); 01516 01517 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01518 { 01519 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01520 __DSB(); 01521 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01522 __DSB(); 01523 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01524 __DSB(); 01525 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01526 __DSB(); 01527 } 01528 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01529 { 01530 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01531 __DSB(); 01532 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01533 __DSB(); 01534 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01535 __DSB(); 01536 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01537 __DSB(); 01538 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01539 __DSB(); 01540 } 01541 } 01542 01543 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 01544 __DSB(); 01545 01546 if (hnand->Config.ExtraCommandEnable == ENABLE) 01547 { 01548 /* Get tick */ 01549 tickstart = HAL_GetTick(); 01550 01551 /* Read status until NAND is ready */ 01552 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01553 { 01554 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01555 { 01556 /* Update the NAND controller state */ 01557 hnand->State = HAL_NAND_STATE_ERROR; 01558 01559 /* Process unlocked */ 01560 __HAL_UNLOCK(hnand); 01561 01562 return HAL_TIMEOUT; 01563 } 01564 } 01565 01566 /* Go back to read mode */ 01567 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); 01568 __DSB(); 01569 } 01570 01571 /* Get Data into Buffer */ 01572 for (index = 0U; index < hnand->Config.SpareAreaSize; index++) 01573 { 01574 *buff = *(uint16_t *)deviceaddress; 01575 buff++; 01576 } 01577 01578 /* Increment read spare areas number */ 01579 numsparearearead++; 01580 01581 /* Decrement spare areas to read */ 01582 nbspare--; 01583 01584 /* Increment the NAND address */ 01585 nandaddress = (uint32_t)(nandaddress + 1U); 01586 } 01587 01588 /* Update the NAND controller state */ 01589 hnand->State = HAL_NAND_STATE_READY; 01590 01591 /* Process unlocked */ 01592 __HAL_UNLOCK(hnand); 01593 } 01594 else 01595 { 01596 return HAL_ERROR; 01597 } 01598 01599 return HAL_OK; 01600 } 01601 01602 /** 01603 * @brief Write Spare area(s) to NAND memory (8-bits addressing) 01604 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01605 * the configuration information for NAND module. 01606 * @param pAddress pointer to NAND address structure 01607 * @param pBuffer pointer to source buffer to write 01608 * @param NumSpareAreaTowrite number of spare areas to write to block 01609 * @retval HAL status 01610 */ 01611 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, 01612 uint8_t *pBuffer, uint32_t NumSpareAreaTowrite) 01613 { 01614 uint32_t index; 01615 uint32_t tickstart; 01616 uint32_t deviceaddress; 01617 uint32_t numspareareawritten = 0U; 01618 uint32_t nandaddress; 01619 uint32_t columnaddress; 01620 uint32_t nbspare = NumSpareAreaTowrite; 01621 uint8_t *buff = pBuffer; 01622 01623 /* Check the NAND controller state */ 01624 if (hnand->State == HAL_NAND_STATE_BUSY) 01625 { 01626 return HAL_BUSY; 01627 } 01628 else if (hnand->State == HAL_NAND_STATE_READY) 01629 { 01630 /* Process Locked */ 01631 __HAL_LOCK(hnand); 01632 01633 /* Update the NAND controller state */ 01634 hnand->State = HAL_NAND_STATE_BUSY; 01635 01636 /* Identify the device address */ 01637 #if defined(FMC_Bank2_3) 01638 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01639 { 01640 deviceaddress = NAND_DEVICE1; 01641 } 01642 else 01643 { 01644 deviceaddress = NAND_DEVICE2; 01645 } 01646 #else 01647 deviceaddress = NAND_DEVICE; 01648 #endif 01649 01650 /* Page address calculation */ 01651 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 01652 01653 /* Column in page address */ 01654 columnaddress = COLUMN_ADDRESS(hnand); 01655 01656 /* Spare area(s) write loop */ 01657 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01658 { 01659 /* Cards with page size <= 512 bytes */ 01660 if ((hnand->Config.PageSize) <= 512U) 01661 { 01662 /* Send write Spare area command sequence */ 01663 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; 01664 __DSB(); 01665 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 01666 __DSB(); 01667 01668 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01669 { 01670 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01671 __DSB(); 01672 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01673 __DSB(); 01674 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01675 __DSB(); 01676 } 01677 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01678 { 01679 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01680 __DSB(); 01681 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01682 __DSB(); 01683 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01684 __DSB(); 01685 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01686 __DSB(); 01687 } 01688 } 01689 else /* (hnand->Config.PageSize) > 512 */ 01690 { 01691 /* Send write Spare area command sequence */ 01692 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 01693 __DSB(); 01694 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 01695 __DSB(); 01696 01697 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01698 { 01699 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01700 __DSB(); 01701 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01702 __DSB(); 01703 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01704 __DSB(); 01705 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01706 __DSB(); 01707 } 01708 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01709 { 01710 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01711 __DSB(); 01712 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01713 __DSB(); 01714 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01715 __DSB(); 01716 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01717 __DSB(); 01718 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01719 __DSB(); 01720 } 01721 } 01722 01723 /* Write data to memory */ 01724 for (index = 0U; index < hnand->Config.SpareAreaSize; index++) 01725 { 01726 *(__IO uint8_t *)deviceaddress = *buff; 01727 buff++; 01728 __DSB(); 01729 } 01730 01731 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01732 __DSB(); 01733 01734 /* Get tick */ 01735 tickstart = HAL_GetTick(); 01736 01737 /* Read status until NAND is ready */ 01738 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01739 { 01740 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01741 { 01742 /* Update the NAND controller state */ 01743 hnand->State = HAL_NAND_STATE_ERROR; 01744 01745 /* Process unlocked */ 01746 __HAL_UNLOCK(hnand); 01747 01748 return HAL_TIMEOUT; 01749 } 01750 } 01751 01752 /* Increment written spare areas number */ 01753 numspareareawritten++; 01754 01755 /* Decrement spare areas to write */ 01756 nbspare--; 01757 01758 /* Increment the NAND address */ 01759 nandaddress = (uint32_t)(nandaddress + 1U); 01760 } 01761 01762 /* Update the NAND controller state */ 01763 hnand->State = HAL_NAND_STATE_READY; 01764 01765 /* Process unlocked */ 01766 __HAL_UNLOCK(hnand); 01767 } 01768 else 01769 { 01770 return HAL_ERROR; 01771 } 01772 01773 return HAL_OK; 01774 } 01775 01776 /** 01777 * @brief Write Spare area(s) to NAND memory (16-bits addressing) 01778 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01779 * the configuration information for NAND module. 01780 * @param pAddress pointer to NAND address structure 01781 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. 01782 * @param NumSpareAreaTowrite number of spare areas to write to block 01783 * @retval HAL status 01784 */ 01785 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, 01786 uint16_t *pBuffer, uint32_t NumSpareAreaTowrite) 01787 { 01788 uint32_t index; 01789 uint32_t tickstart; 01790 uint32_t deviceaddress; 01791 uint32_t numspareareawritten = 0U; 01792 uint32_t nandaddress; 01793 uint32_t columnaddress; 01794 uint32_t nbspare = NumSpareAreaTowrite; 01795 uint16_t *buff = pBuffer; 01796 01797 /* Check the NAND controller state */ 01798 if (hnand->State == HAL_NAND_STATE_BUSY) 01799 { 01800 return HAL_BUSY; 01801 } 01802 else if (hnand->State == HAL_NAND_STATE_READY) 01803 { 01804 /* Process Locked */ 01805 __HAL_LOCK(hnand); 01806 01807 /* Update the NAND controller state */ 01808 hnand->State = HAL_NAND_STATE_BUSY; 01809 01810 /* Identify the device address */ 01811 #if defined(FMC_Bank2_3) 01812 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01813 { 01814 deviceaddress = NAND_DEVICE1; 01815 } 01816 else 01817 { 01818 deviceaddress = NAND_DEVICE2; 01819 } 01820 #else 01821 deviceaddress = NAND_DEVICE; 01822 #endif 01823 01824 /* NAND raw address calculation */ 01825 nandaddress = ARRAY_ADDRESS(pAddress, hnand); 01826 01827 /* Column in page address */ 01828 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand)); 01829 01830 /* Spare area(s) write loop */ 01831 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01832 { 01833 /* Cards with page size <= 512 bytes */ 01834 if ((hnand->Config.PageSize) <= 512U) 01835 { 01836 /* Send write Spare area command sequence */ 01837 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; 01838 __DSB(); 01839 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 01840 __DSB(); 01841 01842 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01843 { 01844 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01845 __DSB(); 01846 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01847 __DSB(); 01848 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01849 __DSB(); 01850 } 01851 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01852 { 01853 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; 01854 __DSB(); 01855 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01856 __DSB(); 01857 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01858 __DSB(); 01859 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01860 __DSB(); 01861 } 01862 } 01863 else /* (hnand->Config.PageSize) > 512 */ 01864 { 01865 /* Send write Spare area command sequence */ 01866 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; 01867 __DSB(); 01868 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; 01869 __DSB(); 01870 01871 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) 01872 { 01873 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01874 __DSB(); 01875 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01876 __DSB(); 01877 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01878 __DSB(); 01879 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01880 __DSB(); 01881 } 01882 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01883 { 01884 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); 01885 __DSB(); 01886 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); 01887 __DSB(); 01888 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); 01889 __DSB(); 01890 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); 01891 __DSB(); 01892 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); 01893 __DSB(); 01894 } 01895 } 01896 01897 /* Write data to memory */ 01898 for (index = 0U; index < hnand->Config.SpareAreaSize; index++) 01899 { 01900 *(__IO uint16_t *)deviceaddress = *buff; 01901 buff++; 01902 __DSB(); 01903 } 01904 01905 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01906 __DSB(); 01907 01908 /* Get tick */ 01909 tickstart = HAL_GetTick(); 01910 01911 /* Read status until NAND is ready */ 01912 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01913 { 01914 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01915 { 01916 /* Update the NAND controller state */ 01917 hnand->State = HAL_NAND_STATE_ERROR; 01918 01919 /* Process unlocked */ 01920 __HAL_UNLOCK(hnand); 01921 01922 return HAL_TIMEOUT; 01923 } 01924 } 01925 01926 /* Increment written spare areas number */ 01927 numspareareawritten++; 01928 01929 /* Decrement spare areas to write */ 01930 nbspare--; 01931 01932 /* Increment the NAND address */ 01933 nandaddress = (uint32_t)(nandaddress + 1U); 01934 } 01935 01936 /* Update the NAND controller state */ 01937 hnand->State = HAL_NAND_STATE_READY; 01938 01939 /* Process unlocked */ 01940 __HAL_UNLOCK(hnand); 01941 } 01942 else 01943 { 01944 return HAL_ERROR; 01945 } 01946 01947 return HAL_OK; 01948 } 01949 01950 /** 01951 * @brief NAND memory Block erase 01952 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01953 * the configuration information for NAND module. 01954 * @param pAddress pointer to NAND address structure 01955 * @retval HAL status 01956 */ 01957 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) 01958 { 01959 uint32_t deviceaddress; 01960 01961 /* Check the NAND controller state */ 01962 if (hnand->State == HAL_NAND_STATE_BUSY) 01963 { 01964 return HAL_BUSY; 01965 } 01966 else if (hnand->State == HAL_NAND_STATE_READY) 01967 { 01968 /* Process Locked */ 01969 __HAL_LOCK(hnand); 01970 01971 /* Update the NAND controller state */ 01972 hnand->State = HAL_NAND_STATE_BUSY; 01973 01974 /* Identify the device address */ 01975 #if defined(FMC_Bank2_3) 01976 if (hnand->Init.NandBank == FMC_NAND_BANK2) 01977 { 01978 deviceaddress = NAND_DEVICE1; 01979 } 01980 else 01981 { 01982 deviceaddress = NAND_DEVICE2; 01983 } 01984 #else 01985 deviceaddress = NAND_DEVICE; 01986 #endif 01987 01988 /* Send Erase block command sequence */ 01989 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0; 01990 __DSB(); 01991 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01992 __DSB(); 01993 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01994 __DSB(); 01995 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01996 __DSB(); 01997 01998 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1; 01999 __DSB(); 02000 02001 /* Update the NAND controller state */ 02002 hnand->State = HAL_NAND_STATE_READY; 02003 02004 /* Process unlocked */ 02005 __HAL_UNLOCK(hnand); 02006 } 02007 else 02008 { 02009 return HAL_ERROR; 02010 } 02011 02012 return HAL_OK; 02013 } 02014 02015 /** 02016 * @brief Increment the NAND memory address 02017 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02018 * the configuration information for NAND module. 02019 * @param pAddress pointer to NAND address structure 02020 * @retval The new status of the increment address operation. It can be: 02021 * - NAND_VALID_ADDRESS: When the new address is valid address 02022 * - NAND_INVALID_ADDRESS: When the new address is invalid address 02023 */ 02024 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) 02025 { 02026 uint32_t status = NAND_VALID_ADDRESS; 02027 02028 /* Increment page address */ 02029 pAddress->Page++; 02030 02031 /* Check NAND address is valid */ 02032 if (pAddress->Page == hnand->Config.BlockSize) 02033 { 02034 pAddress->Page = 0; 02035 pAddress->Block++; 02036 02037 if (pAddress->Block == hnand->Config.PlaneSize) 02038 { 02039 pAddress->Block = 0; 02040 pAddress->Plane++; 02041 02042 if (pAddress->Plane == (hnand->Config.PlaneNbr)) 02043 { 02044 status = NAND_INVALID_ADDRESS; 02045 } 02046 } 02047 } 02048 02049 return (status); 02050 } 02051 02052 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) 02053 /** 02054 * @brief Register a User NAND Callback 02055 * To be used instead of the weak (surcharged) predefined callback 02056 * @param hnand : NAND handle 02057 * @param CallbackId : ID of the callback to be registered 02058 * This parameter can be one of the following values: 02059 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID 02060 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID 02061 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID 02062 * @param pCallback : pointer to the Callback function 02063 * @retval status 02064 */ 02065 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, 02066 pNAND_CallbackTypeDef pCallback) 02067 { 02068 HAL_StatusTypeDef status = HAL_OK; 02069 02070 if (pCallback == NULL) 02071 { 02072 return HAL_ERROR; 02073 } 02074 02075 /* Process locked */ 02076 __HAL_LOCK(hnand); 02077 02078 if (hnand->State == HAL_NAND_STATE_READY) 02079 { 02080 switch (CallbackId) 02081 { 02082 case HAL_NAND_MSP_INIT_CB_ID : 02083 hnand->MspInitCallback = pCallback; 02084 break; 02085 case HAL_NAND_MSP_DEINIT_CB_ID : 02086 hnand->MspDeInitCallback = pCallback; 02087 break; 02088 case HAL_NAND_IT_CB_ID : 02089 hnand->ItCallback = pCallback; 02090 break; 02091 default : 02092 /* update return status */ 02093 status = HAL_ERROR; 02094 break; 02095 } 02096 } 02097 else if (hnand->State == HAL_NAND_STATE_RESET) 02098 { 02099 switch (CallbackId) 02100 { 02101 case HAL_NAND_MSP_INIT_CB_ID : 02102 hnand->MspInitCallback = pCallback; 02103 break; 02104 case HAL_NAND_MSP_DEINIT_CB_ID : 02105 hnand->MspDeInitCallback = pCallback; 02106 break; 02107 default : 02108 /* update return status */ 02109 status = HAL_ERROR; 02110 break; 02111 } 02112 } 02113 else 02114 { 02115 /* update return status */ 02116 status = HAL_ERROR; 02117 } 02118 02119 /* Release Lock */ 02120 __HAL_UNLOCK(hnand); 02121 return status; 02122 } 02123 02124 /** 02125 * @brief Unregister a User NAND Callback 02126 * NAND Callback is redirected to the weak (surcharged) predefined callback 02127 * @param hnand : NAND handle 02128 * @param CallbackId : ID of the callback to be unregistered 02129 * This parameter can be one of the following values: 02130 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID 02131 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID 02132 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID 02133 * @retval status 02134 */ 02135 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId) 02136 { 02137 HAL_StatusTypeDef status = HAL_OK; 02138 02139 /* Process locked */ 02140 __HAL_LOCK(hnand); 02141 02142 if (hnand->State == HAL_NAND_STATE_READY) 02143 { 02144 switch (CallbackId) 02145 { 02146 case HAL_NAND_MSP_INIT_CB_ID : 02147 hnand->MspInitCallback = HAL_NAND_MspInit; 02148 break; 02149 case HAL_NAND_MSP_DEINIT_CB_ID : 02150 hnand->MspDeInitCallback = HAL_NAND_MspDeInit; 02151 break; 02152 case HAL_NAND_IT_CB_ID : 02153 hnand->ItCallback = HAL_NAND_ITCallback; 02154 break; 02155 default : 02156 /* update return status */ 02157 status = HAL_ERROR; 02158 break; 02159 } 02160 } 02161 else if (hnand->State == HAL_NAND_STATE_RESET) 02162 { 02163 switch (CallbackId) 02164 { 02165 case HAL_NAND_MSP_INIT_CB_ID : 02166 hnand->MspInitCallback = HAL_NAND_MspInit; 02167 break; 02168 case HAL_NAND_MSP_DEINIT_CB_ID : 02169 hnand->MspDeInitCallback = HAL_NAND_MspDeInit; 02170 break; 02171 default : 02172 /* update return status */ 02173 status = HAL_ERROR; 02174 break; 02175 } 02176 } 02177 else 02178 { 02179 /* update return status */ 02180 status = HAL_ERROR; 02181 } 02182 02183 /* Release Lock */ 02184 __HAL_UNLOCK(hnand); 02185 return status; 02186 } 02187 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */ 02188 02189 /** 02190 * @} 02191 */ 02192 02193 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions 02194 * @brief management functions 02195 * 02196 @verbatim 02197 ============================================================================== 02198 ##### NAND Control functions ##### 02199 ============================================================================== 02200 [..] 02201 This subsection provides a set of functions allowing to control dynamically 02202 the NAND interface. 02203 02204 @endverbatim 02205 * @{ 02206 */ 02207 02208 02209 /** 02210 * @brief Enables dynamically NAND ECC feature. 02211 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02212 * the configuration information for NAND module. 02213 * @retval HAL status 02214 */ 02215 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand) 02216 { 02217 /* Check the NAND controller state */ 02218 if (hnand->State == HAL_NAND_STATE_BUSY) 02219 { 02220 return HAL_BUSY; 02221 } 02222 else if (hnand->State == HAL_NAND_STATE_READY) 02223 { 02224 /* Update the NAND state */ 02225 hnand->State = HAL_NAND_STATE_BUSY; 02226 02227 /* Enable ECC feature */ 02228 (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank); 02229 02230 /* Update the NAND state */ 02231 hnand->State = HAL_NAND_STATE_READY; 02232 } 02233 else 02234 { 02235 return HAL_ERROR; 02236 } 02237 02238 return HAL_OK; 02239 } 02240 02241 /** 02242 * @brief Disables dynamically FMC_NAND ECC feature. 02243 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02244 * the configuration information for NAND module. 02245 * @retval HAL status 02246 */ 02247 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand) 02248 { 02249 /* Check the NAND controller state */ 02250 if (hnand->State == HAL_NAND_STATE_BUSY) 02251 { 02252 return HAL_BUSY; 02253 } 02254 else if (hnand->State == HAL_NAND_STATE_READY) 02255 { 02256 /* Update the NAND state */ 02257 hnand->State = HAL_NAND_STATE_BUSY; 02258 02259 /* Disable ECC feature */ 02260 (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank); 02261 02262 /* Update the NAND state */ 02263 hnand->State = HAL_NAND_STATE_READY; 02264 } 02265 else 02266 { 02267 return HAL_ERROR; 02268 } 02269 02270 return HAL_OK; 02271 } 02272 02273 /** 02274 * @brief Disables dynamically NAND ECC feature. 02275 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02276 * the configuration information for NAND module. 02277 * @param ECCval pointer to ECC value 02278 * @param Timeout maximum timeout to wait 02279 * @retval HAL status 02280 */ 02281 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout) 02282 { 02283 HAL_StatusTypeDef status; 02284 02285 /* Check the NAND controller state */ 02286 if (hnand->State == HAL_NAND_STATE_BUSY) 02287 { 02288 return HAL_BUSY; 02289 } 02290 else if (hnand->State == HAL_NAND_STATE_READY) 02291 { 02292 /* Update the NAND state */ 02293 hnand->State = HAL_NAND_STATE_BUSY; 02294 02295 /* Get NAND ECC value */ 02296 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout); 02297 02298 /* Update the NAND state */ 02299 hnand->State = HAL_NAND_STATE_READY; 02300 } 02301 else 02302 { 02303 return HAL_ERROR; 02304 } 02305 02306 return status; 02307 } 02308 02309 /** 02310 * @} 02311 */ 02312 02313 02314 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions 02315 * @brief Peripheral State functions 02316 * 02317 @verbatim 02318 ============================================================================== 02319 ##### NAND State functions ##### 02320 ============================================================================== 02321 [..] 02322 This subsection permits to get in run-time the status of the NAND controller 02323 and the data flow. 02324 02325 @endverbatim 02326 * @{ 02327 */ 02328 02329 /** 02330 * @brief return the NAND state 02331 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02332 * the configuration information for NAND module. 02333 * @retval HAL state 02334 */ 02335 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand) 02336 { 02337 return hnand->State; 02338 } 02339 02340 /** 02341 * @brief NAND memory read status 02342 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 02343 * the configuration information for NAND module. 02344 * @retval NAND status 02345 */ 02346 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand) 02347 { 02348 uint32_t data; 02349 uint32_t deviceaddress; 02350 UNUSED(hnand); 02351 02352 /* Identify the device address */ 02353 #if defined(FMC_Bank2_3) 02354 if (hnand->Init.NandBank == FMC_NAND_BANK2) 02355 { 02356 deviceaddress = NAND_DEVICE1; 02357 } 02358 else 02359 { 02360 deviceaddress = NAND_DEVICE2; 02361 } 02362 #else 02363 deviceaddress = NAND_DEVICE; 02364 #endif 02365 02366 /* Send Read status operation command */ 02367 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS; 02368 02369 /* Read status register data */ 02370 data = *(__IO uint8_t *)deviceaddress; 02371 02372 /* Return the status */ 02373 if ((data & NAND_ERROR) == NAND_ERROR) 02374 { 02375 return NAND_ERROR; 02376 } 02377 else if ((data & NAND_READY) == NAND_READY) 02378 { 02379 return NAND_READY; 02380 } 02381 else 02382 { 02383 return NAND_BUSY; 02384 } 02385 } 02386 02387 /** 02388 * @} 02389 */ 02390 02391 /** 02392 * @} 02393 */ 02394 02395 /** 02396 * @} 02397 */ 02398 02399 #endif /* HAL_NAND_MODULE_ENABLED */ 02400 02401 /** 02402 * @} 02403 */ 02404 02405 #endif /* FMC_Bank3) || defined(FMC_Bank2_3) || defined(FSMC_Bank2_3 */ 02406 02407 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/