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