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