2 ******************************************************************************
3 * @file stm32f4xx_hal_nand.c
4 * @author MCD Application Team
7 * @brief NAND HAL module driver.
8 * This file provides a generic firmware to drive NAND memories mounted
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
16 This driver is a generic layered driver which contains a set of APIs used to
17 control NAND flash memories. It uses the FMC/FSMC layer functions to interface
18 with NAND devices. This driver is used as follows:
20 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
21 with control and timing parameters for both common and attribute spaces.
23 (+) Read NAND flash memory maker and device IDs using the function
24 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
25 structure declared by the function caller.
27 (+) Access NAND flash memory by read/write operations using the functions
28 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
29 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
30 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
31 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
32 to read/write page(s)/spare area(s). These functions use specific device
33 information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
34 structure. The read/write address information is contained by the Nand_Address_Typedef
35 structure passed as parameter.
37 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
39 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
40 The erase block address information is contained in the Nand_Address_Typedef
41 structure passed as parameter.
43 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
45 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
46 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
47 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
49 (+) You can monitor the NAND device HAL state by calling the function
53 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
54 If a NAND flash device contains different operations and/or implementations,
55 it should be implemented separately.
58 ******************************************************************************
61 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
63 * Redistribution and use in source and binary forms, with or without modification,
64 * are permitted provided that the following conditions are met:
65 * 1. Redistributions of source code must retain the above copyright notice,
66 * this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright notice,
68 * this list of conditions and the following disclaimer in the documentation
69 * and/or other materials provided with the distribution.
70 * 3. Neither the name of STMicroelectronics nor the names of its contributors
71 * may be used to endorse or promote products derived from this software
72 * without specific prior written permission.
74 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
78 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
80 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
81 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
82 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 ******************************************************************************
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32f4xx_hal.h"
91 /** @addtogroup STM32F4xx_HAL_Driver
96 #ifdef HAL_NAND_MODULE_ENABLED
98 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
99 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
100 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
102 /** @defgroup NAND NAND
103 * @brief NAND HAL module driver
107 /* Private typedef -----------------------------------------------------------*/
108 /* Private define ------------------------------------------------------------*/
109 /** @defgroup NAND_Private_Constants NAND Private Constants
117 /* Private macro -------------------------------------------------------------*/
118 /** @defgroup NAND_Private_Macros NAND Private Macros
125 /* Private variables ---------------------------------------------------------*/
126 /* Private function prototypes -----------------------------------------------*/
127 /* Exported functions --------------------------------------------------------*/
128 /** @defgroup NAND_Exported_Functions NAND Exported Functions
132 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
133 * @brief Initialization and Configuration functions
136 ==============================================================================
137 ##### NAND Initialization and de-initialization functions #####
138 ==============================================================================
140 This section provides functions allowing to initialize/de-initialize
148 * @brief Perform NAND memory Initialization sequence
149 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
150 * the configuration information for NAND module.
151 * @param ComSpace_Timing: pointer to Common space timing structure
152 * @param AttSpace_Timing: pointer to Attribute space timing structure
155 HAL_StatusTypeDef
HAL_NAND_Init(NAND_HandleTypeDef
*hnand
, FMC_NAND_PCC_TimingTypeDef
*ComSpace_Timing
, FMC_NAND_PCC_TimingTypeDef
*AttSpace_Timing
)
157 /* Check the NAND handle state */
163 if(hnand
->State
== HAL_NAND_STATE_RESET
)
165 /* Allocate lock resource and initialize it */
166 hnand
->Lock
= HAL_UNLOCKED
;
167 /* Initialize the low level hardware (MSP) */
168 HAL_NAND_MspInit(hnand
);
171 /* Initialize NAND control Interface */
172 FMC_NAND_Init(hnand
->Instance
, &(hnand
->Init
));
174 /* Initialize NAND common space timing Interface */
175 FMC_NAND_CommonSpace_Timing_Init(hnand
->Instance
, ComSpace_Timing
, hnand
->Init
.NandBank
);
177 /* Initialize NAND attribute space timing Interface */
178 FMC_NAND_AttributeSpace_Timing_Init(hnand
->Instance
, AttSpace_Timing
, hnand
->Init
.NandBank
);
180 /* Enable the NAND device */
181 __FMC_NAND_ENABLE(hnand
->Instance
, hnand
->Init
.NandBank
);
183 /* Update the NAND controller state */
184 hnand
->State
= HAL_NAND_STATE_READY
;
190 * @brief Perform NAND memory De-Initialization sequence
191 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
192 * the configuration information for NAND module.
195 HAL_StatusTypeDef
HAL_NAND_DeInit(NAND_HandleTypeDef
*hnand
)
197 /* Initialize the low level hardware (MSP) */
198 HAL_NAND_MspDeInit(hnand
);
200 /* Configure the NAND registers with their reset values */
201 FMC_NAND_DeInit(hnand
->Instance
, hnand
->Init
.NandBank
);
203 /* Reset the NAND controller state */
204 hnand
->State
= HAL_NAND_STATE_RESET
;
213 * @brief NAND MSP Init
214 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
215 * the configuration information for NAND module.
218 __weak
void HAL_NAND_MspInit(NAND_HandleTypeDef
*hnand
)
220 /* Prevent unused argument(s) compilation warning */
222 /* NOTE : This function Should not be modified, when the callback is needed,
223 the HAL_NAND_MspInit could be implemented in the user file
228 * @brief NAND MSP DeInit
229 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
230 * the configuration information for NAND module.
233 __weak
void HAL_NAND_MspDeInit(NAND_HandleTypeDef
*hnand
)
235 /* Prevent unused argument(s) compilation warning */
237 /* NOTE : This function Should not be modified, when the callback is needed,
238 the HAL_NAND_MspDeInit could be implemented in the user file
244 * @brief This function handles NAND device interrupt request.
245 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
246 * the configuration information for NAND module.
249 void HAL_NAND_IRQHandler(NAND_HandleTypeDef
*hnand
)
251 /* Check NAND interrupt Rising edge flag */
252 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
))
254 /* NAND interrupt callback*/
255 HAL_NAND_ITCallback(hnand
);
257 /* Clear NAND interrupt Rising edge pending bit */
258 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
);
261 /* Check NAND interrupt Level flag */
262 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
))
264 /* NAND interrupt callback*/
265 HAL_NAND_ITCallback(hnand
);
267 /* Clear NAND interrupt Level pending bit */
268 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
);
271 /* Check NAND interrupt Falling edge flag */
272 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
))
274 /* NAND interrupt callback*/
275 HAL_NAND_ITCallback(hnand
);
277 /* Clear NAND interrupt Falling edge pending bit */
278 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
);
281 /* Check NAND interrupt FIFO empty flag */
282 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
))
284 /* NAND interrupt callback*/
285 HAL_NAND_ITCallback(hnand
);
287 /* Clear NAND interrupt FIFO empty pending bit */
288 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
);
293 * @brief NAND interrupt feature callback
294 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
295 * the configuration information for NAND module.
298 __weak
void HAL_NAND_ITCallback(NAND_HandleTypeDef
*hnand
)
300 /* Prevent unused argument(s) compilation warning */
302 /* NOTE : This function Should not be modified, when the callback is needed,
303 the HAL_NAND_ITCallback could be implemented in the user file
311 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
312 * @brief Input Output and memory control functions
315 ==============================================================================
316 ##### NAND Input and Output functions #####
317 ==============================================================================
319 This section provides functions allowing to use and control the NAND
327 * @brief Read the NAND memory electronic signature
328 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
329 * the configuration information for NAND module.
330 * @param pNAND_ID: NAND ID structure
333 HAL_StatusTypeDef
HAL_NAND_Read_ID(NAND_HandleTypeDef
*hnand
, NAND_IDTypeDef
*pNAND_ID
)
335 __IO
uint32_t data
= 0U;
336 __IO
uint32_t data1
= 0U;
337 uint32_t deviceaddress
= 0U;
342 /* Check the NAND controller state */
343 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
348 /* Identify the device address */
349 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
351 deviceaddress
= NAND_DEVICE1
;
355 deviceaddress
= NAND_DEVICE2
;
358 /* Update the NAND controller state */
359 hnand
->State
= HAL_NAND_STATE_BUSY
;
361 /* Send Read ID command sequence */
362 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_READID
;
363 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
365 /* Read the electronic signature from NAND flash */
366 #ifdef FSMC_PCR2_PWID
367 if (hnand
->Init
.MemoryDataWidth
== FSMC_NAND_PCC_MEM_BUS_WIDTH_8
)
368 #else /* FMC_PCR2_PWID is defined */
369 if (hnand
->Init
.MemoryDataWidth
== FMC_NAND_PCC_MEM_BUS_WIDTH_8
)
372 data
= *(__IO
uint32_t *)deviceaddress
;
374 /* Return the data read */
375 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
376 pNAND_ID
->Device_Id
= ADDR_2ND_CYCLE(data
);
377 pNAND_ID
->Third_Id
= ADDR_3RD_CYCLE(data
);
378 pNAND_ID
->Fourth_Id
= ADDR_4TH_CYCLE(data
);
382 data
= *(__IO
uint32_t *)deviceaddress
;
383 data1
= *((__IO
uint32_t *)deviceaddress
+ 4U);
385 /* Return the data read */
386 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
387 pNAND_ID
->Device_Id
= ADDR_3RD_CYCLE(data
);
388 pNAND_ID
->Third_Id
= ADDR_1ST_CYCLE(data1
);
389 pNAND_ID
->Fourth_Id
= ADDR_3RD_CYCLE(data1
);
392 /* Update the NAND controller state */
393 hnand
->State
= HAL_NAND_STATE_READY
;
395 /* Process unlocked */
402 * @brief NAND memory reset
403 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
404 * the configuration information for NAND module.
407 HAL_StatusTypeDef
HAL_NAND_Reset(NAND_HandleTypeDef
*hnand
)
409 uint32_t deviceaddress
= 0U;
414 /* Check the NAND controller state */
415 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
420 /* Identify the device address */
421 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
423 deviceaddress
= NAND_DEVICE1
;
427 deviceaddress
= NAND_DEVICE2
;
430 /* Update the NAND controller state */
431 hnand
->State
= HAL_NAND_STATE_BUSY
;
433 /* Send NAND reset command */
434 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = 0xFF;
437 /* Update the NAND controller state */
438 hnand
->State
= HAL_NAND_STATE_READY
;
440 /* Process unlocked */
448 * @brief Configure the device: Enter the physical parameters of the device
449 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
450 * the configuration information for NAND module.
451 * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
454 HAL_StatusTypeDef
HAL_NAND_ConfigDevice(NAND_HandleTypeDef
*hnand
, NAND_DeviceConfigTypeDef
*pDeviceConfig
)
456 hnand
->Config
.PageSize
= pDeviceConfig
->PageSize
;
457 hnand
->Config
.SpareAreaSize
= pDeviceConfig
->SpareAreaSize
;
458 hnand
->Config
.BlockSize
= pDeviceConfig
->BlockSize
;
459 hnand
->Config
.BlockNbr
= pDeviceConfig
->BlockNbr
;
460 hnand
->Config
.PlaneSize
= pDeviceConfig
->PlaneSize
;
461 hnand
->Config
.PlaneNbr
= pDeviceConfig
->PlaneNbr
;
462 hnand
->Config
.ExtraCommandEnable
= pDeviceConfig
->ExtraCommandEnable
;
468 * @brief Read Page(s) from NAND memory block (8-bits addressing)
469 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
470 * the configuration information for NAND module.
471 * @param pAddress : pointer to NAND address structure
472 * @param pBuffer : pointer to destination read buffer
473 * @param NumPageToRead : number of pages to read from block
476 HAL_StatusTypeDef
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToRead
)
478 __IO
uint32_t index
= 0U;
479 uint32_t tickstart
= 0U;
480 uint32_t deviceaddress
= 0U, size
= 0U, numPagesRead
= 0U, nandaddress
= 0U;
485 /* Check the NAND controller state */
486 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
491 /* Identify the device address */
492 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
494 deviceaddress
= NAND_DEVICE1
;
498 deviceaddress
= NAND_DEVICE2
;
501 /* Update the NAND controller state */
502 hnand
->State
= HAL_NAND_STATE_BUSY
;
504 /* NAND raw address calculation */
505 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
507 /* Page(s) read loop */
508 while((NumPageToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
510 /* update the buffer size */
511 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
513 /* Send read page command sequence */
514 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
516 /* Cards with page size <= 512 bytes */
517 if((hnand
->Config
.PageSize
) <= 512U)
519 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
521 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
522 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
523 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
525 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
527 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
528 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
529 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
530 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
533 else /* (hnand->Config.PageSize) > 512 */
535 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
537 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
538 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
539 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
540 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
542 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
544 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
545 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
546 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
547 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
548 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
552 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
554 /* Check if an extra command is needed for reading pages */
555 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
558 tickstart
= HAL_GetTick();
560 /* Read status until NAND is ready */
561 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
563 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
569 /* Go back to read mode */
570 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
574 /* Get Data into Buffer */
575 for(; index
< size
; index
++)
577 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceaddress
;
580 /* Increment read pages number */
583 /* Decrement pages to read */
586 /* Increment the NAND address */
587 nandaddress
= (uint32_t)(nandaddress
+ 1U);
590 /* Update the NAND controller state */
591 hnand
->State
= HAL_NAND_STATE_READY
;
593 /* Process unlocked */
600 * @brief Read Page(s) from NAND memory block (16-bits addressing)
601 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
602 * the configuration information for NAND module.
603 * @param pAddress : pointer to NAND address structure
604 * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
605 * @param NumPageToRead : number of pages to read from block
608 HAL_StatusTypeDef
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToRead
)
610 __IO
uint32_t index
= 0U;
611 uint32_t tickstart
= 0U;
612 uint32_t deviceaddress
= 0U, size
= 0U, numPagesRead
= 0U, nandaddress
= 0U;
617 /* Check the NAND controller state */
618 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
623 /* Identify the device address */
624 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
626 deviceaddress
= NAND_DEVICE1
;
630 deviceaddress
= NAND_DEVICE2
;
633 /* Update the NAND controller state */
634 hnand
->State
= HAL_NAND_STATE_BUSY
;
636 /* NAND raw address calculation */
637 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
639 /* Page(s) read loop */
640 while((NumPageToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
642 /* update the buffer size */
643 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
645 /* Send read page command sequence */
646 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
649 /* Cards with page size <= 512 bytes */
650 if((hnand
->Config
.PageSize
) <= 512U)
652 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
654 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
655 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
656 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
658 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
660 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
661 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
662 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
663 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
666 else /* (hnand->Config.PageSize) > 512 */
668 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
670 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
671 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
672 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
673 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
675 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
677 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
678 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
679 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
680 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
681 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
685 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
687 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
690 tickstart
= HAL_GetTick();
692 /* Read status until NAND is ready */
693 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
695 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
701 /* Go back to read mode */
702 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
705 /* Get Data into Buffer */
706 for(; index
< size
; index
++)
708 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceaddress
;
711 /* Increment read pages number */
714 /* Decrement pages to read */
717 /* Increment the NAND address */
718 nandaddress
= (uint32_t)(nandaddress
+ 1U);
721 /* Update the NAND controller state */
722 hnand
->State
= HAL_NAND_STATE_READY
;
724 /* Process unlocked */
731 * @brief Write Page(s) to NAND memory block (8-bits addressing)
732 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
733 * the configuration information for NAND module.
734 * @param pAddress : pointer to NAND address structure
735 * @param pBuffer : pointer to source buffer to write
736 * @param NumPageToWrite : number of pages to write to block
739 HAL_StatusTypeDef
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToWrite
)
741 __IO
uint32_t index
= 0U;
742 uint32_t tickstart
= 0U;
743 uint32_t deviceaddress
= 0U, size
= 0U, numPagesWritten
= 0U, nandaddress
= 0U;
748 /* Check the NAND controller state */
749 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
754 /* Identify the device address */
755 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
757 deviceaddress
= NAND_DEVICE1
;
761 deviceaddress
= NAND_DEVICE2
;
764 /* Update the NAND controller state */
765 hnand
->State
= HAL_NAND_STATE_BUSY
;
767 /* NAND raw address calculation */
768 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
770 /* Page(s) write loop */
771 while((NumPageToWrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
773 /* update the buffer size */
774 size
= hnand
->Config
.PageSize
+ ((hnand
->Config
.PageSize
) * numPagesWritten
);
776 /* Send write page command sequence */
777 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
778 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
780 /* Cards with page size <= 512 bytes */
781 if((hnand
->Config
.PageSize
) <= 512U)
783 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
785 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
786 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
787 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
789 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
791 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
792 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
793 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
794 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
797 else /* (hnand->Config.PageSize) > 512 */
799 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
801 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
802 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
803 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
804 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
806 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
808 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
809 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
810 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
811 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
813 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
819 /* Write data to memory */
820 for(; index
< size
; index
++)
822 *(__IO
uint8_t *)deviceaddress
= *(uint8_t *)pBuffer
++;
825 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
827 /* Read status until NAND is ready */
828 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
831 tickstart
= HAL_GetTick();
833 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
839 /* Increment written pages number */
842 /* Decrement pages to write */
845 /* Increment the NAND address */
846 nandaddress
= (uint32_t)(nandaddress
+ 1U);
849 /* Update the NAND controller state */
850 hnand
->State
= HAL_NAND_STATE_READY
;
852 /* Process unlocked */
859 * @brief Write Page(s) to NAND memory block (16-bits addressing)
860 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
861 * the configuration information for NAND module.
862 * @param pAddress : pointer to NAND address structure
863 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
864 * @param NumPageToWrite : number of pages to write to block
867 HAL_StatusTypeDef
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToWrite
)
869 __IO
uint32_t index
= 0U;
870 uint32_t tickstart
= 0U;
871 uint32_t deviceaddress
= 0U, size
= 0U, numPagesWritten
= 0U, nandaddress
= 0U;
876 /* Check the NAND controller state */
877 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
882 /* Identify the device address */
883 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
885 deviceaddress
= NAND_DEVICE1
;
889 deviceaddress
= NAND_DEVICE2
;
892 /* Update the NAND controller state */
893 hnand
->State
= HAL_NAND_STATE_BUSY
;
895 /* NAND raw address calculation */
896 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
898 /* Page(s) write loop */
899 while((NumPageToWrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
901 /* update the buffer size */
902 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
904 /* Send write page command sequence */
905 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
907 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
910 /* Cards with page size <= 512 bytes */
911 if((hnand
->Config
.PageSize
) <= 512U)
913 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
915 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
916 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
917 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
919 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
921 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
922 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
923 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
924 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
927 else /* (hnand->Config.PageSize) > 512 */
929 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
931 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
932 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
933 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
934 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
936 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
938 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
939 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
940 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
941 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
942 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
946 /* Write data to memory */
947 for(; index
< size
; index
++)
949 *(__IO
uint16_t *)deviceaddress
= *(uint16_t *)pBuffer
++;
952 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
954 /* Read status until NAND is ready */
955 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
958 tickstart
= HAL_GetTick();
960 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
966 /* Increment written pages number */
969 /* Decrement pages to write */
972 /* Increment the NAND address */
973 nandaddress
= (uint32_t)(nandaddress
+ 1U);
976 /* Update the NAND controller state */
977 hnand
->State
= HAL_NAND_STATE_READY
;
979 /* Process unlocked */
986 * @brief Read Spare area(s) from NAND memory
987 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
988 * the configuration information for NAND module.
989 * @param pAddress : pointer to NAND address structure
990 * @param pBuffer: pointer to source buffer to write
991 * @param NumSpareAreaToRead: Number of spare area to read
994 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaToRead
)
996 __IO
uint32_t index
= 0U;
997 uint32_t tickstart
= 0U;
998 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaRead
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1000 /* Process Locked */
1003 /* Check the NAND controller state */
1004 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1009 /* Identify the device address */
1010 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1012 deviceaddress
= NAND_DEVICE1
;
1016 deviceaddress
= NAND_DEVICE2
;
1019 /* Update the NAND controller state */
1020 hnand
->State
= HAL_NAND_STATE_BUSY
;
1022 /* NAND raw address calculation */
1023 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1025 /* Column in page address */
1026 columnaddress
= COLUMN_ADDRESS(hnand
);
1028 /* Spare area(s) read loop */
1029 while((NumSpareAreaToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1031 /* update the buffer size */
1032 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1034 /* Cards with page size <= 512 bytes */
1035 if((hnand
->Config
.PageSize
) <= 512U)
1037 /* Send read spare area command sequence */
1038 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1040 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1042 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1043 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1044 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1046 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1048 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1049 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1050 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1051 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1054 else /* (hnand->Config.PageSize) > 512 */
1056 /* Send read spare area command sequence */
1057 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1059 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1061 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1062 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1063 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1064 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1066 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1068 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1069 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1070 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1071 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1072 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1076 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1078 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1081 tickstart
= HAL_GetTick();
1083 /* Read status until NAND is ready */
1084 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1086 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1092 /* Go back to read mode */
1093 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
1096 /* Get Data into Buffer */
1097 for(; index
< size
; index
++)
1099 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceaddress
;
1102 /* Increment read spare areas number */
1105 /* Decrement spare areas to read */
1106 NumSpareAreaToRead
--;
1108 /* Increment the NAND address */
1109 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1112 /* Update the NAND controller state */
1113 hnand
->State
= HAL_NAND_STATE_READY
;
1115 /* Process unlocked */
1116 __HAL_UNLOCK(hnand
);
1122 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1123 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1124 * the configuration information for NAND module.
1125 * @param pAddress : pointer to NAND address structure
1126 * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
1127 * @param NumSpareAreaToRead: Number of spare area to read
1128 * @retval HAL status
1130 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1132 __IO
uint32_t index
= 0U;
1133 uint32_t tickstart
= 0U;
1134 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaRead
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1136 /* Process Locked */
1139 /* Check the NAND controller state */
1140 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1145 /* Identify the device address */
1146 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1148 deviceaddress
= NAND_DEVICE1
;
1152 deviceaddress
= NAND_DEVICE2
;
1155 /* Update the NAND controller state */
1156 hnand
->State
= HAL_NAND_STATE_BUSY
;
1158 /* NAND raw address calculation */
1159 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1161 /* Column in page address */
1162 columnaddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2U);
1164 /* Spare area(s) read loop */
1165 while((NumSpareAreaToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1167 /* update the buffer size */
1168 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1170 /* Cards with page size <= 512 bytes */
1171 if((hnand
->Config
.PageSize
) <= 512U)
1173 /* Send read spare area command sequence */
1174 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1176 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1178 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1179 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1180 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1182 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1184 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1185 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1186 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1187 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1190 else /* (hnand->Config.PageSize) > 512 */
1192 /* Send read spare area command sequence */
1193 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1195 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1197 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1198 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1199 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1200 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1202 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1204 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1205 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1206 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1207 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1208 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1212 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1214 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1217 tickstart
= HAL_GetTick();
1219 /* Read status until NAND is ready */
1220 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1222 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1228 /* Go back to read mode */
1229 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
1232 /* Get Data into Buffer */
1233 for(; index
< size
; index
++)
1235 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceaddress
;
1238 /* Increment read spare areas number */
1241 /* Decrement spare areas to read */
1242 NumSpareAreaToRead
--;
1244 /* Increment the NAND address */
1245 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1248 /* Update the NAND controller state */
1249 hnand
->State
= HAL_NAND_STATE_READY
;
1251 /* Process unlocked */
1252 __HAL_UNLOCK(hnand
);
1258 * @brief Write Spare area(s) to NAND memory
1259 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1260 * the configuration information for NAND module.
1261 * @param pAddress : pointer to NAND address structure
1262 * @param pBuffer : pointer to source buffer to write
1263 * @param NumSpareAreaTowrite : number of spare areas to write to block
1264 * @retval HAL status
1266 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1268 __IO
uint32_t index
= 0U;
1269 uint32_t tickstart
= 0U;
1270 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaWritten
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1272 /* Process Locked */
1275 /* Check the NAND controller state */
1276 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1281 /* Identify the device address */
1282 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1284 deviceaddress
= NAND_DEVICE1
;
1288 deviceaddress
= NAND_DEVICE2
;
1291 /* Update the FMC_NAND controller state */
1292 hnand
->State
= HAL_NAND_STATE_BUSY
;
1294 /* Page address calculation */
1295 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1297 /* Column in page address */
1298 columnaddress
= COLUMN_ADDRESS(hnand
);
1300 /* Spare area(s) write loop */
1301 while((NumSpareAreaTowrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1303 /* update the buffer size */
1304 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1306 /* Cards with page size <= 512 bytes */
1307 if((hnand
->Config
.PageSize
) <= 512U)
1309 /* Send write Spare area command sequence */
1310 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1311 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1313 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1315 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1316 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1317 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1319 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1321 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1322 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1323 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1324 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1327 else /* (hnand->Config.PageSize) > 512 */
1329 /* Send write Spare area command sequence */
1330 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1331 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1333 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1335 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1336 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1337 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1338 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1340 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1342 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1343 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1344 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1345 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1346 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1350 /* Write data to memory */
1351 for(; index
< size
; index
++)
1353 *(__IO
uint8_t *)deviceaddress
= *(uint8_t *)pBuffer
++;
1356 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1359 tickstart
= HAL_GetTick();
1361 /* Read status until NAND is ready */
1362 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1364 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1370 /* Increment written spare areas number */
1371 numSpareAreaWritten
++;
1373 /* Decrement spare areas to write */
1374 NumSpareAreaTowrite
--;
1376 /* Increment the NAND address */
1377 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1380 /* Update the NAND controller state */
1381 hnand
->State
= HAL_NAND_STATE_READY
;
1383 /* Process unlocked */
1384 __HAL_UNLOCK(hnand
);
1390 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1391 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1392 * the configuration information for NAND module.
1393 * @param pAddress : pointer to NAND address structure
1394 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
1395 * @param NumSpareAreaTowrite : number of spare areas to write to block
1396 * @retval HAL status
1398 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1400 __IO
uint32_t index
= 0U;
1401 uint32_t tickstart
= 0U;
1402 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaWritten
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1404 /* Process Locked */
1407 /* Check the NAND controller state */
1408 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1413 /* Identify the device address */
1414 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1416 deviceaddress
= NAND_DEVICE1
;
1420 deviceaddress
= NAND_DEVICE2
;
1423 /* Update the FMC_NAND controller state */
1424 hnand
->State
= HAL_NAND_STATE_BUSY
;
1426 /* NAND raw address calculation */
1427 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1429 /* Column in page address */
1430 columnaddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2U);
1432 /* Spare area(s) write loop */
1433 while((NumSpareAreaTowrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1435 /* update the buffer size */
1436 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1438 /* Cards with page size <= 512 bytes */
1439 if((hnand
->Config
.PageSize
) <= 512U)
1441 /* Send write Spare area command sequence */
1442 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1443 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1445 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1447 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1448 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1449 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1451 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1453 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1454 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1455 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1456 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1459 else /* (hnand->Config.PageSize) > 512 */
1461 /* Send write Spare area command sequence */
1462 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1463 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1465 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1467 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1468 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1469 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1470 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1472 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1474 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1475 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1476 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1477 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1478 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1482 /* Write data to memory */
1483 for(; index
< size
; index
++)
1485 *(__IO
uint16_t *)deviceaddress
= *(uint16_t *)pBuffer
++;
1488 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1490 /* Read status until NAND is ready */
1491 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1494 tickstart
= HAL_GetTick();
1496 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1502 /* Increment written spare areas number */
1503 numSpareAreaWritten
++;
1505 /* Decrement spare areas to write */
1506 NumSpareAreaTowrite
--;
1508 /* Increment the NAND address */
1509 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1512 /* Update the NAND controller state */
1513 hnand
->State
= HAL_NAND_STATE_READY
;
1515 /* Process unlocked */
1516 __HAL_UNLOCK(hnand
);
1522 * @brief NAND memory Block erase
1523 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1524 * the configuration information for NAND module.
1525 * @param pAddress : pointer to NAND address structure
1526 * @retval HAL status
1528 HAL_StatusTypeDef
HAL_NAND_Erase_Block(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1530 uint32_t deviceaddress
= 0U;
1531 uint32_t tickstart
= 0U;
1533 /* Process Locked */
1536 /* Check the NAND controller state */
1537 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1542 /* Identify the device address */
1543 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1545 deviceaddress
= NAND_DEVICE1
;
1549 deviceaddress
= NAND_DEVICE2
;
1552 /* Update the NAND controller state */
1553 hnand
->State
= HAL_NAND_STATE_BUSY
;
1555 /* Send Erase block command sequence */
1556 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_ERASE0
;
1558 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1559 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1560 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1562 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_ERASE1
;
1564 /* Update the NAND controller state */
1565 hnand
->State
= HAL_NAND_STATE_READY
;
1568 tickstart
= HAL_GetTick();
1570 /* Read status until NAND is ready */
1571 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1573 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1575 /* Process unlocked */
1576 __HAL_UNLOCK(hnand
);
1582 /* Process unlocked */
1583 __HAL_UNLOCK(hnand
);
1589 * @brief NAND memory read status
1590 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1591 * the configuration information for NAND module.
1592 * @retval NAND status
1594 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef
*hnand
)
1597 uint32_t deviceaddress
= 0U;
1599 /* Identify the device address */
1600 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
1602 deviceaddress
= NAND_DEVICE1
;
1606 deviceaddress
= NAND_DEVICE2
;
1609 /* Send Read status operation command */
1610 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_STATUS
;
1612 /* Read status register data */
1613 data
= *(__IO
uint8_t *)deviceaddress
;
1615 /* Return the status */
1616 if((data
& NAND_ERROR
) == NAND_ERROR
)
1620 else if((data
& NAND_READY
) == NAND_READY
)
1629 * @brief Increment the NAND memory address
1630 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1631 * the configuration information for NAND module.
1632 * @param pAddress: pointer to NAND address structure
1633 * @retval The new status of the increment address operation. It can be:
1634 * - NAND_VALID_ADDRESS: When the new address is valid address
1635 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1637 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1639 uint32_t status
= NAND_VALID_ADDRESS
;
1641 /* Increment page address */
1644 /* Check NAND address is valid */
1645 if(pAddress
->Page
== hnand
->Config
.BlockSize
)
1647 pAddress
->Page
= 0U;
1650 if(pAddress
->Block
== hnand
->Config
.PlaneSize
)
1652 pAddress
->Block
= 0U;
1655 if(pAddress
->Plane
== (hnand
->Config
.PlaneNbr
))
1657 status
= NAND_INVALID_ADDRESS
;
1668 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1669 * @brief management functions
1672 ==============================================================================
1673 ##### NAND Control functions #####
1674 ==============================================================================
1676 This subsection provides a set of functions allowing to control dynamically
1685 * @brief Enables dynamically NAND ECC feature.
1686 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1687 * the configuration information for NAND module.
1688 * @retval HAL status
1690 HAL_StatusTypeDef
HAL_NAND_ECC_Enable(NAND_HandleTypeDef
*hnand
)
1692 /* Check the NAND controller state */
1693 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1698 /* Update the NAND state */
1699 hnand
->State
= HAL_NAND_STATE_BUSY
;
1701 /* Enable ECC feature */
1702 FMC_NAND_ECC_Enable(hnand
->Instance
, hnand
->Init
.NandBank
);
1704 /* Update the NAND state */
1705 hnand
->State
= HAL_NAND_STATE_READY
;
1711 * @brief Disables dynamically FMC_NAND ECC feature.
1712 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1713 * the configuration information for NAND module.
1714 * @retval HAL status
1716 HAL_StatusTypeDef
HAL_NAND_ECC_Disable(NAND_HandleTypeDef
*hnand
)
1718 /* Check the NAND controller state */
1719 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1724 /* Update the NAND state */
1725 hnand
->State
= HAL_NAND_STATE_BUSY
;
1727 /* Disable ECC feature */
1728 FMC_NAND_ECC_Disable(hnand
->Instance
, hnand
->Init
.NandBank
);
1730 /* Update the NAND state */
1731 hnand
->State
= HAL_NAND_STATE_READY
;
1737 * @brief Disables dynamically NAND ECC feature.
1738 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1739 * the configuration information for NAND module.
1740 * @param ECCval: pointer to ECC value
1741 * @param Timeout: maximum timeout to wait
1742 * @retval HAL status
1744 HAL_StatusTypeDef
HAL_NAND_GetECC(NAND_HandleTypeDef
*hnand
, uint32_t *ECCval
, uint32_t Timeout
)
1746 HAL_StatusTypeDef status
= HAL_OK
;
1748 /* Check the NAND controller state */
1749 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1754 /* Update the NAND state */
1755 hnand
->State
= HAL_NAND_STATE_BUSY
;
1757 /* Get NAND ECC value */
1758 status
= FMC_NAND_GetECC(hnand
->Instance
, ECCval
, hnand
->Init
.NandBank
, Timeout
);
1760 /* Update the NAND state */
1761 hnand
->State
= HAL_NAND_STATE_READY
;
1771 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1772 * @brief Peripheral State functions
1775 ==============================================================================
1776 ##### NAND State functions #####
1777 ==============================================================================
1779 This subsection permits to get in run-time the status of the NAND controller
1787 * @brief return the NAND state
1788 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1789 * the configuration information for NAND module.
1792 HAL_NAND_StateTypeDef
HAL_NAND_GetState(NAND_HandleTypeDef
*hnand
)
1794 return hnand
->State
;
1809 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
1810 STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\
1811 STM32F446xx || STM32F469xx || STM32F479xx */
1812 #endif /* HAL_NAND_MODULE_ENABLED */
1818 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/