STM32L486xx 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 @verbatim 00010 ============================================================================== 00011 ##### How to use this driver ##### 00012 ============================================================================== 00013 [..] 00014 This driver is a generic layered driver which contains a set of APIs used to 00015 control NAND flash memories. It uses the FMC layer functions to interface 00016 with NAND devices. This driver is used as follows: 00017 00018 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init() 00019 with control and timing parameters for both common and attribute spaces. 00020 00021 (+) Read NAND flash memory maker and device IDs using the function 00022 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef 00023 structure declared by the function caller. 00024 00025 (+) Access NAND flash memory by read/write operations using the functions 00026 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(), 00027 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(), 00028 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(), 00029 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b() 00030 to read/write page(s)/spare area(s). These functions use specific device 00031 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef 00032 structure. The read/write address information is contained by the Nand_Address_Typedef 00033 structure passed as parameter. 00034 00035 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset(). 00036 00037 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block(). 00038 The erase block address information is contained in the Nand_Address_Typedef 00039 structure passed as parameter. 00040 00041 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status(). 00042 00043 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/ 00044 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction 00045 feature or the function HAL_NAND_GetECC() to get the ECC correction code. 00046 00047 (+) You can monitor the NAND device HAL state by calling the function 00048 HAL_NAND_GetState() 00049 00050 [..] 00051 (@) This driver is a set of generic APIs which handle standard NAND flash operations. 00052 If a NAND flash device contains different operations and/or implementations, 00053 it should be implemented separately. 00054 00055 @endverbatim 00056 ****************************************************************************** 00057 * @attention 00058 * 00059 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00060 * 00061 * Redistribution and use in source and binary forms, with or without modification, 00062 * are permitted provided that the following conditions are met: 00063 * 1. Redistributions of source code must retain the above copyright notice, 00064 * this list of conditions and the following disclaimer. 00065 * 2. Redistributions in binary form must reproduce the above copyright notice, 00066 * this list of conditions and the following disclaimer in the documentation 00067 * and/or other materials provided with the distribution. 00068 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00069 * may be used to endorse or promote products derived from this software 00070 * without specific prior written permission. 00071 * 00072 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00073 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00074 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00075 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00076 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00077 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00078 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00079 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00080 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00081 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00082 * 00083 ****************************************************************************** 00084 */ 00085 00086 /* Includes ------------------------------------------------------------------*/ 00087 #include "stm32l4xx_hal.h" 00088 00089 #if defined(FMC_BANK3) 00090 00091 /** @addtogroup STM32L4xx_HAL_Driver 00092 * @{ 00093 */ 00094 00095 #ifdef HAL_NAND_MODULE_ENABLED 00096 00097 /** @defgroup NAND NAND 00098 * @brief NAND HAL module driver 00099 * @{ 00100 */ 00101 00102 /* Private typedef -----------------------------------------------------------*/ 00103 /* Private Constants ------------------------------------------------------------*/ 00104 /* Private macro -------------------------------------------------------------*/ 00105 /* Private variables ---------------------------------------------------------*/ 00106 /* Private function prototypes -----------------------------------------------*/ 00107 /* Exported functions ---------------------------------------------------------*/ 00108 00109 /** @defgroup NAND_Exported_Functions NAND Exported Functions 00110 * @{ 00111 */ 00112 00113 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions 00114 * @brief Initialization and Configuration functions 00115 * 00116 @verbatim 00117 ============================================================================== 00118 ##### NAND Initialization and de-initialization functions ##### 00119 ============================================================================== 00120 [..] 00121 This section provides functions allowing to initialize/de-initialize 00122 the NAND memory 00123 00124 @endverbatim 00125 * @{ 00126 */ 00127 00128 /** 00129 * @brief Perform NAND memory Initialization sequence 00130 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00131 * the configuration information for NAND module. 00132 * @param ComSpace_Timing pointer to Common space timing structure 00133 * @param AttSpace_Timing pointer to Attribute space timing structure 00134 * @retval HAL status 00135 */ 00136 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing) 00137 { 00138 /* Check the NAND handle state */ 00139 if(hnand == NULL) 00140 { 00141 return HAL_ERROR; 00142 } 00143 00144 if(hnand->State == HAL_NAND_STATE_RESET) 00145 { 00146 /* Allocate lock resource and initialize it */ 00147 hnand->Lock = HAL_UNLOCKED; 00148 /* Initialize the low level hardware (MSP) */ 00149 HAL_NAND_MspInit(hnand); 00150 } 00151 00152 /* Initialize NAND control Interface */ 00153 FMC_NAND_Init(hnand->Instance, &(hnand->Init)); 00154 00155 /* Initialize NAND common space timing Interface */ 00156 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank); 00157 00158 /* Initialize NAND attribute space timing Interface */ 00159 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank); 00160 00161 /* Enable the NAND device */ 00162 __FMC_NAND_ENABLE(hnand->Instance); 00163 00164 /* Update the NAND controller state */ 00165 hnand->State = HAL_NAND_STATE_READY; 00166 00167 return HAL_OK; 00168 } 00169 00170 /** 00171 * @brief Perform NAND memory De-Initialization sequence 00172 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00173 * the configuration information for NAND module. 00174 * @retval HAL status 00175 */ 00176 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand) 00177 { 00178 /* Initialize the low level hardware (MSP) */ 00179 HAL_NAND_MspDeInit(hnand); 00180 00181 /* Configure the NAND registers with their reset values */ 00182 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank); 00183 00184 /* Reset the NAND controller state */ 00185 hnand->State = HAL_NAND_STATE_RESET; 00186 00187 /* Release Lock */ 00188 __HAL_UNLOCK(hnand); 00189 00190 return HAL_OK; 00191 } 00192 00193 /** 00194 * @brief Initialize the NAND MSP 00195 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00196 * the configuration information for NAND module. 00197 * @retval None 00198 */ 00199 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand) 00200 { 00201 /* Prevent unused argument(s) compilation warning */ 00202 UNUSED(hnand); 00203 00204 /* NOTE : This function should not be modified, when the callback is needed, 00205 the HAL_NAND_MspInit could be implemented in the user file 00206 */ 00207 } 00208 00209 /** 00210 * @brief DeInitialize the NAND MSP 00211 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00212 * the configuration information for NAND module. 00213 * @retval None 00214 */ 00215 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand) 00216 { 00217 /* Prevent unused argument(s) compilation warning */ 00218 UNUSED(hnand); 00219 00220 /* NOTE : This function should not be modified, when the callback is needed, 00221 the HAL_NAND_MspDeInit could be implemented in the user file 00222 */ 00223 } 00224 00225 00226 /** 00227 * @brief This function handles NAND device interrupt request. 00228 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00229 * the configuration information for NAND module. 00230 * @retval HAL status 00231 */ 00232 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand) 00233 { 00234 /* Check NAND interrupt Rising edge flag */ 00235 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE)) 00236 { 00237 /* NAND interrupt callback*/ 00238 HAL_NAND_ITCallback(hnand); 00239 00240 /* Clear NAND interrupt Rising edge pending bit */ 00241 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE); 00242 } 00243 00244 /* Check NAND interrupt Level flag */ 00245 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL)) 00246 { 00247 /* NAND interrupt callback*/ 00248 HAL_NAND_ITCallback(hnand); 00249 00250 /* Clear NAND interrupt Level pending bit */ 00251 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL); 00252 } 00253 00254 /* Check NAND interrupt Falling edge flag */ 00255 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE)) 00256 { 00257 /* NAND interrupt callback*/ 00258 HAL_NAND_ITCallback(hnand); 00259 00260 /* Clear NAND interrupt Falling edge pending bit */ 00261 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE); 00262 } 00263 00264 /* Check NAND interrupt FIFO empty flag */ 00265 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT)) 00266 { 00267 /* NAND interrupt callback*/ 00268 HAL_NAND_ITCallback(hnand); 00269 00270 /* Clear NAND interrupt FIFO empty pending bit */ 00271 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT); 00272 } 00273 00274 } 00275 00276 /** 00277 * @brief NAND interrupt feature callback 00278 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00279 * the configuration information for NAND module. 00280 * @retval None 00281 */ 00282 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand) 00283 { 00284 /* Prevent unused argument(s) compilation warning */ 00285 UNUSED(hnand); 00286 00287 /* NOTE : This function should not be modified, when the callback is needed, 00288 the HAL_NAND_ITCallback could be implemented in the user file 00289 */ 00290 } 00291 00292 /** 00293 * @} 00294 */ 00295 00296 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions 00297 * @brief Input Output and memory control functions 00298 * 00299 @verbatim 00300 ============================================================================== 00301 ##### NAND Input and Output functions ##### 00302 ============================================================================== 00303 [..] 00304 This section provides functions allowing to use and control the NAND 00305 memory 00306 00307 @endverbatim 00308 * @{ 00309 */ 00310 00311 /** 00312 * @brief Read the NAND memory electronic signature 00313 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00314 * the configuration information for NAND module. 00315 * @param pNAND_ID NAND ID structure 00316 * @retval HAL status 00317 */ 00318 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID) 00319 { 00320 __IO uint32_t data = 0; 00321 __IO uint32_t data1 = 0; 00322 uint32_t deviceAddress = 0; 00323 00324 /* Process Locked */ 00325 __HAL_LOCK(hnand); 00326 00327 /* Check the NAND controller state */ 00328 if(hnand->State == HAL_NAND_STATE_BUSY) 00329 { 00330 return HAL_BUSY; 00331 } 00332 00333 /* Identify the device address */ 00334 deviceAddress = NAND_DEVICE; 00335 00336 /* Update the NAND controller state */ 00337 hnand->State = HAL_NAND_STATE_BUSY; 00338 00339 /* Send Read ID command sequence */ 00340 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID; 00341 __DSB(); 00342 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00343 __DSB(); 00344 00345 /* Read the electronic signature from NAND flash */ 00346 if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8) 00347 { 00348 data = *(__IO uint32_t *)deviceAddress; 00349 00350 /* Return the data read */ 00351 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); 00352 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data); 00353 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data); 00354 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data); 00355 } 00356 else 00357 { 00358 data = *(__IO uint32_t *)deviceAddress; 00359 data1 = *((__IO uint32_t *)deviceAddress + 4); 00360 00361 /* Return the data read */ 00362 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); 00363 pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data); 00364 pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1); 00365 pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1); 00366 } 00367 00368 /* Update the NAND controller state */ 00369 hnand->State = HAL_NAND_STATE_READY; 00370 00371 /* Process unlocked */ 00372 __HAL_UNLOCK(hnand); 00373 00374 return HAL_OK; 00375 } 00376 00377 /** 00378 * @brief NAND memory reset 00379 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00380 * the configuration information for NAND module. 00381 * @retval HAL status 00382 */ 00383 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand) 00384 { 00385 uint32_t deviceAddress = 0; 00386 00387 /* Process Locked */ 00388 __HAL_LOCK(hnand); 00389 00390 /* Check the NAND controller state */ 00391 if(hnand->State == HAL_NAND_STATE_BUSY) 00392 { 00393 return HAL_BUSY; 00394 } 00395 00396 /* Identify the device address */ 00397 deviceAddress = NAND_DEVICE; 00398 00399 /* Update the NAND controller state */ 00400 hnand->State = HAL_NAND_STATE_BUSY; 00401 00402 /* Send NAND reset command */ 00403 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF; 00404 00405 /* Update the NAND controller state */ 00406 hnand->State = HAL_NAND_STATE_READY; 00407 00408 /* Process unlocked */ 00409 __HAL_UNLOCK(hnand); 00410 00411 return HAL_OK; 00412 00413 } 00414 00415 /** 00416 * @brief Configure the device: Enter the physical parameters of the device 00417 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00418 * the configuration information for NAND module. 00419 * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure 00420 * @retval HAL status 00421 */ 00422 HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig) 00423 { 00424 hnand->Config.PageSize = pDeviceConfig->PageSize; 00425 hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize; 00426 hnand->Config.BlockSize = pDeviceConfig->BlockSize; 00427 hnand->Config.BlockNbr = pDeviceConfig->BlockNbr; 00428 hnand->Config.PlaneSize = pDeviceConfig->PlaneSize; 00429 hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr; 00430 hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable; 00431 00432 return HAL_OK; 00433 } 00434 00435 00436 /** 00437 * @brief Read Page(s) from NAND memory block (8-bits addressing) 00438 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00439 * the configuration information for NAND module. 00440 * @param pAddress pointer to NAND address structure 00441 * @param pBuffer pointer to destination read buffer 00442 * @param NumPageToRead number of pages to read from block 00443 * @retval HAL status 00444 */ 00445 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead) 00446 { 00447 __IO uint32_t index = 0; 00448 uint32_t tickstart = 0U; 00449 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0; 00450 00451 /* Process Locked */ 00452 __HAL_LOCK(hnand); 00453 00454 /* Check the NAND controller state */ 00455 if(hnand->State == HAL_NAND_STATE_BUSY) 00456 { 00457 return HAL_BUSY; 00458 } 00459 00460 /* Identify the device address */ 00461 deviceAddress = NAND_DEVICE; 00462 00463 /* Update the NAND controller state */ 00464 hnand->State = HAL_NAND_STATE_BUSY; 00465 00466 /* NAND raw address calculation */ 00467 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 00468 00469 /* Page(s) read loop */ 00470 while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00471 { 00472 /* update the buffer size */ 00473 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead); 00474 00475 /* Send read page command sequence */ 00476 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 00477 __DSB(); 00478 00479 /* Cards with page size <= 512 bytes */ 00480 if ((hnand->Config.PageSize) <= 512) 00481 { 00482 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00483 { 00484 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00485 __DSB(); 00486 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00487 __DSB(); 00488 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00489 __DSB(); 00490 } 00491 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00492 { 00493 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00494 __DSB(); 00495 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00496 __DSB(); 00497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00498 __DSB(); 00499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00500 __DSB(); 00501 } 00502 } 00503 else /* (hnand->Config.PageSize) > 512 */ 00504 { 00505 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00506 { 00507 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00508 __DSB(); 00509 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00510 __DSB(); 00511 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00512 __DSB(); 00513 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00514 __DSB(); 00515 } 00516 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00517 { 00518 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00519 __DSB(); 00520 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00521 __DSB(); 00522 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00523 __DSB(); 00524 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00525 __DSB(); 00526 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00527 __DSB(); 00528 } 00529 } 00530 00531 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 00532 __DSB(); 00533 00534 00535 if (hnand->Config.ExtraCommandEnable == ENABLE) 00536 { 00537 /* Get tick */ 00538 tickstart = HAL_GetTick(); 00539 00540 /* Read status until NAND is ready */ 00541 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 00542 { 00543 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 00544 { 00545 return HAL_TIMEOUT; 00546 } 00547 } 00548 00549 /* Go back to read mode */ 00550 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U); 00551 __DSB(); 00552 } 00553 00554 /* Get Data into Buffer */ 00555 for(; index < size; index++) 00556 { 00557 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress; 00558 } 00559 00560 /* Increment read pages number */ 00561 numPagesRead++; 00562 00563 /* Decrement pages to read */ 00564 NumPageToRead--; 00565 00566 /* Increment the NAND address */ 00567 nandAddress = (uint32_t)(nandAddress + 1); 00568 } 00569 00570 /* Update the NAND controller state */ 00571 hnand->State = HAL_NAND_STATE_READY; 00572 00573 /* Process unlocked */ 00574 __HAL_UNLOCK(hnand); 00575 00576 return HAL_OK; 00577 } 00578 00579 /** 00580 * @brief Read Page(s) from NAND memory block (16-bits addressing) 00581 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00582 * the configuration information for NAND module. 00583 * @param pAddress pointer to NAND address structure 00584 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned 00585 * @param NumPageToRead number of pages to read from block 00586 * @retval HAL status 00587 */ 00588 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead) 00589 { 00590 __IO uint32_t index = 0; 00591 uint32_t tickstart = 0; 00592 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0; 00593 00594 /* Process Locked */ 00595 __HAL_LOCK(hnand); 00596 00597 /* Check the NAND controller state */ 00598 if (hnand->State == HAL_NAND_STATE_BUSY) 00599 { 00600 return HAL_BUSY; 00601 } 00602 00603 /* Identify the device address */ 00604 deviceAddress = NAND_DEVICE; 00605 00606 /* Update the NAND controller state */ 00607 hnand->State = HAL_NAND_STATE_BUSY; 00608 00609 /* NAND raw address calculation */ 00610 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 00611 00612 /* Page(s) read loop */ 00613 while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00614 { 00615 /* update the buffer size */ 00616 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead); 00617 00618 /* Send read page command sequence */ 00619 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 00620 __DSB(); 00621 00622 /* Cards with page size <= 512 bytes */ 00623 if ((hnand->Config.PageSize) <= 512) 00624 { 00625 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00626 { 00627 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00628 __DSB(); 00629 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00630 __DSB(); 00631 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00632 __DSB(); 00633 } 00634 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00635 { 00636 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00637 __DSB(); 00638 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00639 __DSB(); 00640 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00641 __DSB(); 00642 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00643 __DSB(); 00644 } 00645 } 00646 else /* (hnand->Config.PageSize) > 512 */ 00647 { 00648 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00649 { 00650 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00651 __DSB(); 00652 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00653 __DSB(); 00654 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00655 __DSB(); 00656 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00657 __DSB(); 00658 } 00659 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00660 { 00661 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00662 __DSB(); 00663 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00664 __DSB(); 00665 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00666 __DSB(); 00667 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00668 __DSB(); 00669 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00670 __DSB(); 00671 } 00672 } 00673 00674 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 00675 __DSB(); 00676 00677 if (hnand->Config.ExtraCommandEnable == ENABLE) 00678 { 00679 /* Get tick */ 00680 tickstart = HAL_GetTick(); 00681 00682 /* Read status until NAND is ready */ 00683 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 00684 { 00685 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 00686 { 00687 return HAL_TIMEOUT; 00688 } 00689 } 00690 00691 /* Go back to read mode */ 00692 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U); 00693 __DSB(); 00694 } 00695 00696 /* Get Data into Buffer */ 00697 for (; index < size; index++) 00698 { 00699 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress; 00700 } 00701 00702 /* Increment read pages number */ 00703 numPagesRead++; 00704 00705 /* Decrement pages to read */ 00706 NumPageToRead--; 00707 00708 /* Increment the NAND address */ 00709 nandAddress = (uint32_t)(nandAddress + 1); 00710 } 00711 00712 /* Update the NAND controller state */ 00713 hnand->State = HAL_NAND_STATE_READY; 00714 00715 /* Process unlocked */ 00716 __HAL_UNLOCK(hnand); 00717 00718 return HAL_OK; 00719 } 00720 00721 /** 00722 * @brief Write Page(s) to NAND memory block (8-bits addressing) 00723 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00724 * the configuration information for NAND module. 00725 * @param pAddress pointer to NAND address structure 00726 * @param pBuffer pointer to source buffer to write 00727 * @param NumPageToWrite number of pages to write to block 00728 * @retval HAL status 00729 */ 00730 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite) 00731 { 00732 __IO uint32_t index = 0; 00733 uint32_t tickstart = 0; 00734 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0; 00735 00736 /* Process Locked */ 00737 __HAL_LOCK(hnand); 00738 00739 /* Check the NAND controller state */ 00740 if(hnand->State == HAL_NAND_STATE_BUSY) 00741 { 00742 return HAL_BUSY; 00743 } 00744 00745 /* Identify the device address */ 00746 deviceAddress = NAND_DEVICE; 00747 00748 /* Update the NAND controller state */ 00749 hnand->State = HAL_NAND_STATE_BUSY; 00750 00751 /* NAND raw address calculation */ 00752 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 00753 00754 /* Page(s) write loop */ 00755 while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00756 { 00757 /* update the buffer size */ 00758 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten); 00759 00760 /* Send write page command sequence */ 00761 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 00762 __DSB(); 00763 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 00764 __DSB(); 00765 00766 /* Cards with page size <= 512 bytes */ 00767 if ((hnand->Config.PageSize) <= 512) 00768 { 00769 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00770 { 00771 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00772 __DSB(); 00773 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00774 __DSB(); 00775 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00776 __DSB(); 00777 } 00778 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00779 { 00780 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00781 __DSB(); 00782 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00783 __DSB(); 00784 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00785 __DSB(); 00786 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00787 __DSB(); 00788 } 00789 } 00790 else /* (hnand->Config.PageSize) > 512 */ 00791 { 00792 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00793 { 00794 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00795 __DSB(); 00796 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00797 __DSB(); 00798 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00799 __DSB(); 00800 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00801 __DSB(); 00802 } 00803 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00804 { 00805 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00806 __DSB(); 00807 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00808 __DSB(); 00809 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00810 __DSB(); 00811 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00812 __DSB(); 00813 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00814 __DSB(); 00815 } 00816 } 00817 00818 /* Write data to memory */ 00819 for (; index < size; index++) 00820 { 00821 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++; 00822 __DSB(); 00823 } 00824 00825 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 00826 __DSB(); 00827 00828 /* Get tick */ 00829 tickstart = HAL_GetTick(); 00830 00831 /* Read status until NAND is ready */ 00832 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 00833 { 00834 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 00835 { 00836 return HAL_TIMEOUT; 00837 } 00838 } 00839 00840 /* Increment written pages number */ 00841 numPagesWritten++; 00842 00843 /* Decrement pages to write */ 00844 NumPageToWrite--; 00845 00846 /* Increment the NAND address */ 00847 nandAddress = (uint32_t)(nandAddress + 1); 00848 } 00849 00850 /* Update the NAND controller state */ 00851 hnand->State = HAL_NAND_STATE_READY; 00852 00853 /* Process unlocked */ 00854 __HAL_UNLOCK(hnand); 00855 00856 return HAL_OK; 00857 } 00858 00859 /** 00860 * @brief Write Page(s) to NAND memory block (16-bits addressing) 00861 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 00862 * the configuration information for NAND module. 00863 * @param pAddress pointer to NAND address structure 00864 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned 00865 * @param NumPageToWrite number of pages to write to block 00866 * @retval HAL status 00867 */ 00868 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite) 00869 { 00870 __IO uint32_t index = 0; 00871 uint32_t tickstart = 0; 00872 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0; 00873 00874 /* Process Locked */ 00875 __HAL_LOCK(hnand); 00876 00877 /* Check the NAND controller state */ 00878 if (hnand->State == HAL_NAND_STATE_BUSY) 00879 { 00880 return HAL_BUSY; 00881 } 00882 00883 /* Identify the device address */ 00884 deviceAddress = NAND_DEVICE; 00885 00886 /* Update the NAND controller state */ 00887 hnand->State = HAL_NAND_STATE_BUSY; 00888 00889 /* NAND raw address calculation */ 00890 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 00891 00892 /* Page(s) write loop */ 00893 while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 00894 { 00895 /* update the buffer size */ 00896 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten); 00897 00898 /* Send write page command sequence */ 00899 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 00900 __DSB(); 00901 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 00902 __DSB(); 00903 00904 /* Cards with page size <= 512 bytes */ 00905 if ((hnand->Config.PageSize) <= 512) 00906 { 00907 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00908 { 00909 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00910 __DSB(); 00911 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00912 __DSB(); 00913 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00914 __DSB(); 00915 } 00916 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00917 { 00918 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00919 __DSB(); 00920 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00921 __DSB(); 00922 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00923 __DSB(); 00924 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00925 __DSB(); 00926 } 00927 } 00928 else /* (hnand->Config.PageSize) > 512 */ 00929 { 00930 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 00931 { 00932 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00933 __DSB(); 00934 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00935 __DSB(); 00936 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00937 __DSB(); 00938 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00939 __DSB(); 00940 } 00941 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 00942 { 00943 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00944 __DSB(); 00945 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 00946 __DSB(); 00947 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 00948 __DSB(); 00949 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 00950 __DSB(); 00951 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 00952 __DSB(); 00953 } 00954 } 00955 00956 /* Write data to memory */ 00957 for(; index < size; index++) 00958 { 00959 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++; 00960 __DSB(); 00961 } 00962 00963 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 00964 __DSB(); 00965 00966 /* Get tick */ 00967 tickstart = HAL_GetTick(); 00968 00969 /* Read status until NAND is ready */ 00970 while(HAL_NAND_Read_Status(hnand) != NAND_READY) 00971 { 00972 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) 00973 { 00974 return HAL_TIMEOUT; 00975 } 00976 } 00977 00978 /* Increment written pages number */ 00979 numPagesWritten++; 00980 00981 /* Decrement pages to write */ 00982 NumPageToWrite--; 00983 00984 /* Increment the NAND address */ 00985 nandAddress = (uint32_t)(nandAddress + 1); 00986 } 00987 00988 /* Update the NAND controller state */ 00989 hnand->State = HAL_NAND_STATE_READY; 00990 00991 /* Process unlocked */ 00992 __HAL_UNLOCK(hnand); 00993 00994 return HAL_OK; 00995 } 00996 00997 /** 00998 * @brief Read Spare area(s) from NAND memory (8-bits addressing) 00999 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01000 * the configuration information for NAND module. 01001 * @param pAddress pointer to NAND address structure 01002 * @param pBuffer pointer to source buffer to write 01003 * @param NumSpareAreaToRead Number of spare area to read 01004 * @retval HAL status 01005 */ 01006 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead) 01007 { 01008 __IO uint32_t index = 0; 01009 uint32_t tickstart = 0U; 01010 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0; 01011 01012 /* Process Locked */ 01013 __HAL_LOCK(hnand); 01014 01015 /* Check the NAND controller state */ 01016 if (hnand->State == HAL_NAND_STATE_BUSY) 01017 { 01018 return HAL_BUSY; 01019 } 01020 01021 /* Identify the device address */ 01022 deviceAddress = NAND_DEVICE; 01023 01024 /* Update the NAND controller state */ 01025 hnand->State = HAL_NAND_STATE_BUSY; 01026 01027 /* NAND raw address calculation */ 01028 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 01029 01030 /* Column in page address */ 01031 columnAddress = COLUMN_ADDRESS(hnand); 01032 01033 /* Spare area(s) read loop */ 01034 while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01035 { 01036 /* update the buffer size */ 01037 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead); 01038 01039 /* Cards with page size <= 512 bytes */ 01040 if ((hnand->Config.PageSize) <= 512) 01041 { 01042 /* Send read spare area command sequence */ 01043 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C; 01044 __DSB(); 01045 01046 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01047 { 01048 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01049 __DSB(); 01050 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01051 __DSB(); 01052 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01053 __DSB(); 01054 } 01055 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01056 { 01057 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01058 __DSB(); 01059 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01060 __DSB(); 01061 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01062 __DSB(); 01063 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01064 __DSB(); 01065 } 01066 } 01067 else /* (hnand->Config.PageSize) > 512 */ 01068 { 01069 /* Send read spare area command sequence */ 01070 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 01071 __DSB(); 01072 01073 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01074 { 01075 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01076 __DSB(); 01077 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 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 } 01084 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01085 { 01086 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01087 __DSB(); 01088 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01089 __DSB(); 01090 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01091 __DSB(); 01092 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01093 __DSB(); 01094 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01095 __DSB(); 01096 } 01097 } 01098 01099 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 01100 __DSB(); 01101 01102 if (hnand->Config.ExtraCommandEnable == ENABLE) 01103 { 01104 /* Get tick */ 01105 tickstart = HAL_GetTick(); 01106 01107 /* Read status until NAND is ready */ 01108 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01109 { 01110 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01111 { 01112 return HAL_TIMEOUT; 01113 } 01114 } 01115 01116 /* Go back to read mode */ 01117 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U); 01118 __DSB(); 01119 } 01120 01121 /* Get Data into Buffer */ 01122 for (; index < size; index++) 01123 { 01124 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress; 01125 } 01126 01127 /* Increment read spare areas number */ 01128 numSpareAreaRead++; 01129 01130 /* Decrement spare areas to read */ 01131 NumSpareAreaToRead--; 01132 01133 /* Increment the NAND address */ 01134 nandAddress = (uint32_t)(nandAddress + 1); 01135 } 01136 01137 /* Update the NAND controller state */ 01138 hnand->State = HAL_NAND_STATE_READY; 01139 01140 /* Process unlocked */ 01141 __HAL_UNLOCK(hnand); 01142 01143 return HAL_OK; 01144 } 01145 01146 /** 01147 * @brief Read Spare area(s) from NAND memory (16-bits addressing) 01148 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01149 * the configuration information for NAND module. 01150 * @param pAddress pointer to NAND address structure 01151 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. 01152 * @param NumSpareAreaToRead Number of spare area to read 01153 * @retval HAL status 01154 */ 01155 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead) 01156 { 01157 __IO uint32_t index = 0; 01158 uint32_t tickstart = 0U; 01159 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0; 01160 01161 /* Process Locked */ 01162 __HAL_LOCK(hnand); 01163 01164 /* Check the NAND controller state */ 01165 if(hnand->State == HAL_NAND_STATE_BUSY) 01166 { 01167 return HAL_BUSY; 01168 } 01169 01170 /* Identify the device address */ 01171 deviceAddress = NAND_DEVICE; 01172 01173 /* Update the NAND controller state */ 01174 hnand->State = HAL_NAND_STATE_BUSY; 01175 01176 /* NAND raw address calculation */ 01177 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 01178 01179 /* Column in page address */ 01180 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2); 01181 01182 /* Spare area(s) read loop */ 01183 while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01184 { 01185 /* update the buffer size */ 01186 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead); 01187 01188 /* Cards with page size <= 512 bytes */ 01189 if ((hnand->Config.PageSize) <= 512) 01190 { 01191 /* Send read spare area command sequence */ 01192 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C; 01193 __DSB(); 01194 01195 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01196 { 01197 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01198 __DSB(); 01199 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01200 __DSB(); 01201 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01202 __DSB(); 01203 } 01204 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01205 { 01206 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01207 __DSB(); 01208 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01209 __DSB(); 01210 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01211 __DSB(); 01212 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01213 __DSB(); 01214 } 01215 } 01216 else /* (hnand->Config.PageSize) > 512 */ 01217 { 01218 /* Send read spare area command sequence */ 01219 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 01220 __DSB(); 01221 01222 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01223 { 01224 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01225 __DSB(); 01226 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01227 __DSB(); 01228 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01229 __DSB(); 01230 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01231 __DSB(); 01232 } 01233 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 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 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01244 __DSB(); 01245 } 01246 } 01247 01248 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; 01249 __DSB(); 01250 01251 if (hnand->Config.ExtraCommandEnable == ENABLE) 01252 { 01253 /* Get tick */ 01254 tickstart = HAL_GetTick(); 01255 01256 /* Read status until NAND is ready */ 01257 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01258 { 01259 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01260 { 01261 return HAL_TIMEOUT; 01262 } 01263 } 01264 01265 /* Go back to read mode */ 01266 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U); 01267 __DSB(); 01268 } 01269 01270 /* Get Data into Buffer */ 01271 for ( ;index < size; index++) 01272 { 01273 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress; 01274 } 01275 01276 /* Increment read spare areas number */ 01277 numSpareAreaRead++; 01278 01279 /* Decrement spare areas to read */ 01280 NumSpareAreaToRead--; 01281 01282 /* Increment the NAND address */ 01283 nandAddress = (uint32_t)(nandAddress + 1); 01284 } 01285 01286 /* Update the NAND controller state */ 01287 hnand->State = HAL_NAND_STATE_READY; 01288 01289 /* Process unlocked */ 01290 __HAL_UNLOCK(hnand); 01291 01292 return HAL_OK; 01293 } 01294 01295 /** 01296 * @brief Write Spare area(s) to NAND memory (8-bits addressing) 01297 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01298 * the configuration information for NAND module. 01299 * @param pAddress pointer to NAND address structure 01300 * @param pBuffer pointer to source buffer to write 01301 * @param NumSpareAreaTowrite number of spare areas to write to block 01302 * @retval HAL status 01303 */ 01304 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite) 01305 { 01306 __IO uint32_t index = 0; 01307 uint32_t tickstart = 0; 01308 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0; 01309 01310 /* Process Locked */ 01311 __HAL_LOCK(hnand); 01312 01313 /* Check the NAND controller state */ 01314 if(hnand->State == HAL_NAND_STATE_BUSY) 01315 { 01316 return HAL_BUSY; 01317 } 01318 01319 /* Identify the device address */ 01320 deviceAddress = NAND_DEVICE; 01321 01322 /* Update the FMC_NAND controller state */ 01323 hnand->State = HAL_NAND_STATE_BUSY; 01324 01325 /* Page address calculation */ 01326 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 01327 01328 /* Column in page address */ 01329 columnAddress = COLUMN_ADDRESS(hnand); 01330 01331 /* Spare area(s) write loop */ 01332 while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01333 { 01334 /* update the buffer size */ 01335 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten); 01336 01337 /* Cards with page size <= 512 bytes */ 01338 if ((hnand->Config.PageSize) <= 512) 01339 { 01340 /* Send write Spare area command sequence */ 01341 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C; 01342 __DSB(); 01343 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 01344 __DSB(); 01345 01346 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01347 { 01348 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01349 __DSB(); 01350 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01351 __DSB(); 01352 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01353 __DSB(); 01354 } 01355 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01356 { 01357 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01358 __DSB(); 01359 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01360 __DSB(); 01361 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01362 __DSB(); 01363 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01364 __DSB(); 01365 } 01366 } 01367 else /* (hnand->Config.PageSize) > 512 */ 01368 { 01369 /* Send write Spare area command sequence */ 01370 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 01371 __DSB(); 01372 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 01373 __DSB(); 01374 01375 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01376 { 01377 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01378 __DSB(); 01379 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01380 __DSB(); 01381 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01382 __DSB(); 01383 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01384 __DSB(); 01385 } 01386 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01387 { 01388 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01389 __DSB(); 01390 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01391 __DSB(); 01392 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01393 __DSB(); 01394 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01395 __DSB(); 01396 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01397 __DSB(); 01398 } 01399 } 01400 01401 /* Write data to memory */ 01402 for(; index < size; index++) 01403 { 01404 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++; 01405 __DSB(); 01406 } 01407 01408 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01409 __DSB(); 01410 01411 /* Get tick */ 01412 tickstart = HAL_GetTick(); 01413 01414 /* Read status until NAND is ready */ 01415 while(HAL_NAND_Read_Status(hnand) != NAND_READY) 01416 { 01417 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) 01418 { 01419 return HAL_TIMEOUT; 01420 } 01421 } 01422 01423 /* Increment written spare areas number */ 01424 numSpareAreaWritten++; 01425 01426 /* Decrement spare areas to write */ 01427 NumSpareAreaTowrite--; 01428 01429 /* Increment the NAND address */ 01430 nandAddress = (uint32_t)(nandAddress + 1); 01431 } 01432 01433 /* Update the NAND controller state */ 01434 hnand->State = HAL_NAND_STATE_READY; 01435 01436 /* Process unlocked */ 01437 __HAL_UNLOCK(hnand); 01438 01439 return HAL_OK; 01440 } 01441 01442 /** 01443 * @brief Write Spare area(s) to NAND memory (16-bits addressing) 01444 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01445 * the configuration information for NAND module. 01446 * @param pAddress pointer to NAND address structure 01447 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. 01448 * @param NumSpareAreaTowrite number of spare areas to write to block 01449 * @retval HAL status 01450 */ 01451 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite) 01452 { 01453 __IO uint32_t index = 0; 01454 uint32_t tickstart = 0; 01455 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0; 01456 01457 /* Process Locked */ 01458 __HAL_LOCK(hnand); 01459 01460 /* Check the NAND controller state */ 01461 if (hnand->State == HAL_NAND_STATE_BUSY) 01462 { 01463 return HAL_BUSY; 01464 } 01465 01466 /* Identify the device address */ 01467 deviceAddress = NAND_DEVICE; 01468 01469 /* Update the FMC_NAND controller state */ 01470 hnand->State = HAL_NAND_STATE_BUSY; 01471 01472 /* NAND raw address calculation */ 01473 nandAddress = ARRAY_ADDRESS(pAddress, hnand); 01474 01475 /* Column in page address */ 01476 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2); 01477 01478 /* Spare area(s) write loop */ 01479 while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) 01480 { 01481 /* update the buffer size */ 01482 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten); 01483 01484 /* Cards with page size <= 512 bytes */ 01485 if ((hnand->Config.PageSize) <= 512) 01486 { 01487 /* Send write Spare area command sequence */ 01488 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C; 01489 __DSB(); 01490 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 01491 __DSB(); 01492 01493 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01494 { 01495 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01496 __DSB(); 01497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01498 __DSB(); 01499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01500 __DSB(); 01501 } 01502 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01503 { 01504 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 01505 __DSB(); 01506 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01507 __DSB(); 01508 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01509 __DSB(); 01510 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01511 __DSB(); 01512 } 01513 } 01514 else /* (hnand->Config.PageSize) > 512 */ 01515 { 01516 /* Send write Spare area command sequence */ 01517 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A; 01518 __DSB(); 01519 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0; 01520 __DSB(); 01521 01522 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535) 01523 { 01524 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01525 __DSB(); 01526 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01527 __DSB(); 01528 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01529 __DSB(); 01530 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01531 __DSB(); 01532 } 01533 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ 01534 { 01535 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress); 01536 __DSB(); 01537 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress); 01538 __DSB(); 01539 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); 01540 __DSB(); 01541 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); 01542 __DSB(); 01543 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress); 01544 __DSB(); 01545 } 01546 } 01547 01548 /* Write data to memory */ 01549 for (; index < size; index++) 01550 { 01551 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++; 01552 __DSB(); 01553 } 01554 01555 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; 01556 __DSB(); 01557 01558 /* Get tick */ 01559 tickstart = HAL_GetTick(); 01560 01561 /* Read status until NAND is ready */ 01562 while (HAL_NAND_Read_Status(hnand) != NAND_READY) 01563 { 01564 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) 01565 { 01566 return HAL_TIMEOUT; 01567 } 01568 } 01569 01570 /* Increment written spare areas number */ 01571 numSpareAreaWritten++; 01572 01573 /* Decrement spare areas to write */ 01574 NumSpareAreaTowrite--; 01575 01576 /* Increment the NAND address */ 01577 nandAddress = (uint32_t)(nandAddress + 1); 01578 } 01579 01580 /* Update the NAND controller state */ 01581 hnand->State = HAL_NAND_STATE_READY; 01582 01583 /* Process unlocked */ 01584 __HAL_UNLOCK(hnand); 01585 01586 return HAL_OK; 01587 } 01588 01589 /** 01590 * @brief NAND memory Block erase 01591 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01592 * the configuration information for NAND module. 01593 * @param pAddress pointer to NAND address structure 01594 * @retval HAL status 01595 */ 01596 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) 01597 { 01598 uint32_t DeviceAddress = 0; 01599 01600 /* Process Locked */ 01601 __HAL_LOCK(hnand); 01602 01603 /* Check the NAND controller state */ 01604 if(hnand->State == HAL_NAND_STATE_BUSY) 01605 { 01606 return HAL_BUSY; 01607 } 01608 01609 /* Identify the device address */ 01610 DeviceAddress = NAND_DEVICE; 01611 01612 /* Update the NAND controller state */ 01613 hnand->State = HAL_NAND_STATE_BUSY; 01614 01615 /* Send Erase block command sequence */ 01616 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0; 01617 __DSB(); 01618 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01619 __DSB(); 01620 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01621 __DSB(); 01622 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); 01623 __DSB(); 01624 01625 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1; 01626 __DSB(); 01627 01628 /* Update the NAND controller state */ 01629 hnand->State = HAL_NAND_STATE_READY; 01630 01631 /* Process unlocked */ 01632 __HAL_UNLOCK(hnand); 01633 01634 return HAL_OK; 01635 } 01636 01637 /** 01638 * @brief Increment the NAND memory address 01639 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01640 * the configuration information for NAND module. 01641 * @param pAddress pointer to NAND address structure 01642 * @retval The new status of the increment address operation. It can be: 01643 * - NAND_VALID_ADDRESS: When the new address is valid address 01644 * - NAND_INVALID_ADDRESS: When the new address is invalid address 01645 */ 01646 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) 01647 { 01648 uint32_t status = NAND_VALID_ADDRESS; 01649 01650 /* Increment page address */ 01651 pAddress->Page++; 01652 01653 /* Check NAND address is valid */ 01654 if (pAddress->Page == hnand->Config.BlockSize) 01655 { 01656 pAddress->Page = 0; 01657 pAddress->Block++; 01658 01659 if (pAddress->Block == hnand->Config.PlaneSize) 01660 { 01661 pAddress->Block = 0; 01662 pAddress->Plane++; 01663 01664 if (pAddress->Plane == (hnand->Config.PlaneNbr)) 01665 { 01666 status = NAND_INVALID_ADDRESS; 01667 } 01668 } 01669 } 01670 01671 return (status); 01672 } 01673 /** 01674 * @} 01675 */ 01676 01677 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions 01678 * @brief management functions 01679 * 01680 @verbatim 01681 ============================================================================== 01682 ##### NAND Control functions ##### 01683 ============================================================================== 01684 [..] 01685 This subsection provides a set of functions allowing to control dynamically 01686 the NAND interface. 01687 01688 @endverbatim 01689 * @{ 01690 */ 01691 01692 01693 /** 01694 * @brief Enable dynamically NAND ECC feature. 01695 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01696 * the configuration information for NAND module. 01697 * @retval HAL status 01698 */ 01699 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand) 01700 { 01701 /* Check the NAND controller state */ 01702 if(hnand->State == HAL_NAND_STATE_BUSY) 01703 { 01704 return HAL_BUSY; 01705 } 01706 01707 /* Update the NAND state */ 01708 hnand->State = HAL_NAND_STATE_BUSY; 01709 01710 /* Enable ECC feature */ 01711 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank); 01712 01713 /* Update the NAND state */ 01714 hnand->State = HAL_NAND_STATE_READY; 01715 01716 return HAL_OK; 01717 } 01718 01719 /** 01720 * @brief Disable dynamically NAND ECC feature 01721 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01722 * the configuration information for NAND module. 01723 * @retval HAL status 01724 */ 01725 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand) 01726 { 01727 /* Check the NAND controller state */ 01728 if(hnand->State == HAL_NAND_STATE_BUSY) 01729 { 01730 return HAL_BUSY; 01731 } 01732 01733 /* Update the NAND state */ 01734 hnand->State = HAL_NAND_STATE_BUSY; 01735 01736 /* Disable ECC feature */ 01737 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank); 01738 01739 /* Update the NAND state */ 01740 hnand->State = HAL_NAND_STATE_READY; 01741 01742 return HAL_OK; 01743 } 01744 01745 /** 01746 * @brief Get NAND ECC value 01747 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01748 * the configuration information for NAND module. 01749 * @param ECCval pointer to ECC value 01750 * @param Timeout maximum timeout to wait 01751 * @retval HAL status 01752 */ 01753 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout) 01754 { 01755 HAL_StatusTypeDef status = HAL_OK; 01756 01757 /* Check the NAND controller state */ 01758 if(hnand->State == HAL_NAND_STATE_BUSY) 01759 { 01760 return HAL_BUSY; 01761 } 01762 01763 /* Update the NAND state */ 01764 hnand->State = HAL_NAND_STATE_BUSY; 01765 01766 /* Get NAND ECC value */ 01767 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout); 01768 01769 /* Update the NAND state */ 01770 hnand->State = HAL_NAND_STATE_READY; 01771 01772 return status; 01773 } 01774 01775 /** 01776 * @} 01777 */ 01778 01779 01780 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions 01781 * @brief Peripheral State functions 01782 * 01783 @verbatim 01784 ============================================================================== 01785 ##### NAND State functions ##### 01786 ============================================================================== 01787 [..] 01788 This subsection permits to get in run-time the status of the NAND controller 01789 and the data flow. 01790 01791 @endverbatim 01792 * @{ 01793 */ 01794 01795 /** 01796 * @brief Return the NAND state 01797 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01798 * the configuration information for NAND module. 01799 * @retval HAL state 01800 */ 01801 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand) 01802 { 01803 /* Return NAND handle state */ 01804 return hnand->State; 01805 } 01806 01807 /** 01808 * @brief NAND memory read status 01809 * @param hnand pointer to a NAND_HandleTypeDef structure that contains 01810 * the configuration information for NAND module. 01811 * @retval NAND status 01812 */ 01813 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand) 01814 { 01815 uint32_t data = 0; 01816 uint32_t DeviceAddress = 0; 01817 01818 /* Identify the device address */ 01819 DeviceAddress = NAND_DEVICE; 01820 01821 /* Send Read status operation command */ 01822 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS; 01823 01824 /* Read status register data */ 01825 data = *(__IO uint8_t *)DeviceAddress; 01826 01827 /* Return the status */ 01828 if ((data & NAND_ERROR) == NAND_ERROR) 01829 { 01830 return NAND_ERROR; 01831 } 01832 else if ((data & NAND_READY) == NAND_READY) 01833 { 01834 return NAND_READY; 01835 } 01836 01837 return NAND_BUSY; 01838 } 01839 01840 /** 01841 * @} 01842 */ 01843 01844 /** 01845 * @} 01846 */ 01847 01848 /** 01849 * @} 01850 */ 01851 01852 #endif /* HAL_NAND_MODULE_ENABLED */ 01853 01854 /** 01855 * @} 01856 */ 01857 01858 #endif /* FMC_BANK3 */ 01859 01860 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/