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