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