2 ******************************************************************************
3 * @file stm32f1xx_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 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 NAND_DeviceConfigTypeDef
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 "stm32f1xx_hal.h"
91 /** @addtogroup STM32F1xx_HAL_Driver
95 #ifdef HAL_NAND_MODULE_ENABLED
97 #if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
99 /** @defgroup NAND NAND
100 * @brief NAND HAL module driver
104 /* Private typedef -----------------------------------------------------------*/
105 /* Private define ------------------------------------------------------------*/
106 /** @defgroup NAND_Private_Constants NAND Private Constants
114 /* Private macro -------------------------------------------------------------*/
115 /** @defgroup NAND_Private_Macros NAND Private Macros
123 /* Private variables ---------------------------------------------------------*/
124 /* Private function prototypes -----------------------------------------------*/
125 /* Exported functions --------------------------------------------------------*/
126 /** @defgroup NAND_Exported_Functions NAND Exported Functions
130 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
131 * @brief Initialization and Configuration functions
134 ==============================================================================
135 ##### NAND Initialization and de-initialization functions #####
136 ==============================================================================
138 This section provides functions allowing to initialize/de-initialize
146 * @brief Perform NAND memory Initialization sequence
147 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
148 * the configuration information for NAND module.
149 * @param ComSpace_Timing: pointer to Common space timing structure
150 * @param AttSpace_Timing: pointer to Attribute space timing structure
153 HAL_StatusTypeDef
HAL_NAND_Init(NAND_HandleTypeDef
*hnand
, FSMC_NAND_PCC_TimingTypeDef
*ComSpace_Timing
, FSMC_NAND_PCC_TimingTypeDef
*AttSpace_Timing
)
155 /* Check the NAND handle state */
161 if(hnand
->State
== HAL_NAND_STATE_RESET
)
163 /* Allocate lock resource and initialize it */
164 hnand
->Lock
= HAL_UNLOCKED
;
165 /* Initialize the low level hardware (MSP) */
166 HAL_NAND_MspInit(hnand
);
169 /* Initialize NAND control Interface */
170 FSMC_NAND_Init(hnand
->Instance
, &(hnand
->Init
));
172 /* Initialize NAND common space timing Interface */
173 FSMC_NAND_CommonSpace_Timing_Init(hnand
->Instance
, ComSpace_Timing
, hnand
->Init
.NandBank
);
175 /* Initialize NAND attribute space timing Interface */
176 FSMC_NAND_AttributeSpace_Timing_Init(hnand
->Instance
, AttSpace_Timing
, hnand
->Init
.NandBank
);
178 /* Enable the NAND device */
179 __FSMC_NAND_ENABLE(hnand
->Instance
, hnand
->Init
.NandBank
);
181 /* Update the NAND controller state */
182 hnand
->State
= HAL_NAND_STATE_READY
;
188 * @brief Perform NAND memory De-Initialization sequence
189 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
190 * the configuration information for NAND module.
193 HAL_StatusTypeDef
HAL_NAND_DeInit(NAND_HandleTypeDef
*hnand
)
195 /* Initialize the low level hardware (MSP) */
196 HAL_NAND_MspDeInit(hnand
);
198 /* Configure the NAND registers with their reset values */
199 FSMC_NAND_DeInit(hnand
->Instance
, hnand
->Init
.NandBank
);
201 /* Reset the NAND controller state */
202 hnand
->State
= HAL_NAND_STATE_RESET
;
211 * @brief NAND MSP Init
212 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
213 * the configuration information for NAND module.
216 __weak
void HAL_NAND_MspInit(NAND_HandleTypeDef
*hnand
)
218 /* Prevent unused argument(s) compilation warning */
220 /* NOTE : This function Should not be modified, when the callback is needed,
221 the HAL_NAND_MspInit could be implemented in the user file
226 * @brief NAND MSP DeInit
227 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
228 * the configuration information for NAND module.
231 __weak
void HAL_NAND_MspDeInit(NAND_HandleTypeDef
*hnand
)
233 /* Prevent unused argument(s) compilation warning */
235 /* NOTE : This function Should not be modified, when the callback is needed,
236 the HAL_NAND_MspDeInit could be implemented in the user file
242 * @brief This function handles NAND device interrupt request.
243 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
244 * the configuration information for NAND module.
247 void HAL_NAND_IRQHandler(NAND_HandleTypeDef
*hnand
)
249 /* Check NAND interrupt Rising edge flag */
250 if(__FSMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_RISING_EDGE
))
252 /* NAND interrupt callback*/
253 HAL_NAND_ITCallback(hnand
);
255 /* Clear NAND interrupt Rising edge pending bit */
256 __FSMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_RISING_EDGE
);
259 /* Check NAND interrupt Level flag */
260 if(__FSMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_LEVEL
))
262 /* NAND interrupt callback*/
263 HAL_NAND_ITCallback(hnand
);
265 /* Clear NAND interrupt Level pending bit */
266 __FSMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_LEVEL
);
269 /* Check NAND interrupt Falling edge flag */
270 if(__FSMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_FALLING_EDGE
))
272 /* NAND interrupt callback*/
273 HAL_NAND_ITCallback(hnand
);
275 /* Clear NAND interrupt Falling edge pending bit */
276 __FSMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_FALLING_EDGE
);
279 /* Check NAND interrupt FIFO empty flag */
280 if(__FSMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_FEMPT
))
282 /* NAND interrupt callback*/
283 HAL_NAND_ITCallback(hnand
);
285 /* Clear NAND interrupt FIFO empty pending bit */
286 __FSMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FSMC_FLAG_FEMPT
);
291 * @brief NAND interrupt feature callback
292 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
293 * the configuration information for NAND module.
296 __weak
void HAL_NAND_ITCallback(NAND_HandleTypeDef
*hnand
)
298 /* Prevent unused argument(s) compilation warning */
300 /* NOTE : This function Should not be modified, when the callback is needed,
301 the HAL_NAND_ITCallback could be implemented in the user file
309 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
310 * @brief Input Output and memory control functions
313 ==============================================================================
314 ##### NAND Input and Output functions #####
315 ==============================================================================
317 This section provides functions allowing to use and control the NAND
325 * @brief Read the NAND memory electronic signature
326 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
327 * the configuration information for NAND module.
328 * @param pNAND_ID: NAND ID structure
331 HAL_StatusTypeDef
HAL_NAND_Read_ID(NAND_HandleTypeDef
*hnand
, NAND_IDTypeDef
*pNAND_ID
)
333 __IO
uint32_t data
= 0U;
334 __IO
uint32_t data1
= 0U;
335 uint32_t deviceaddress
= 0U;
340 /* Check the NAND controller state */
341 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
346 /* Identify the device address */
347 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
349 deviceaddress
= NAND_DEVICE1
;
353 deviceaddress
= NAND_DEVICE2
;
356 /* Update the NAND controller state */
357 hnand
->State
= HAL_NAND_STATE_BUSY
;
359 /* Send Read ID command sequence */
360 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_READID
;
361 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
363 /* Read the electronic signature from NAND flash */
364 if (hnand
->Init
.MemoryDataWidth
== FSMC_NAND_PCC_MEM_BUS_WIDTH_8
)
366 data
= *(__IO
uint32_t *)deviceaddress
;
368 /* Return the data read */
369 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
370 pNAND_ID
->Device_Id
= ADDR_2ND_CYCLE(data
);
371 pNAND_ID
->Third_Id
= ADDR_3RD_CYCLE(data
);
372 pNAND_ID
->Fourth_Id
= ADDR_4TH_CYCLE(data
);
376 data
= *(__IO
uint32_t *)deviceaddress
;
377 data1
= *((__IO
uint32_t *)deviceaddress
+ 4U);
379 /* Return the data read */
380 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
381 pNAND_ID
->Device_Id
= ADDR_3RD_CYCLE(data
);
382 pNAND_ID
->Third_Id
= ADDR_1ST_CYCLE(data1
);
383 pNAND_ID
->Fourth_Id
= ADDR_3RD_CYCLE(data1
);
386 /* Update the NAND controller state */
387 hnand
->State
= HAL_NAND_STATE_READY
;
389 /* Process unlocked */
396 * @brief NAND memory reset
397 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
398 * the configuration information for NAND module.
401 HAL_StatusTypeDef
HAL_NAND_Reset(NAND_HandleTypeDef
*hnand
)
403 uint32_t deviceaddress
= 0U;
408 /* Check the NAND controller state */
409 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
414 /* Identify the device address */
415 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
417 deviceaddress
= NAND_DEVICE1
;
421 deviceaddress
= NAND_DEVICE2
;
424 /* Update the NAND controller state */
425 hnand
->State
= HAL_NAND_STATE_BUSY
;
427 /* Send NAND reset command */
428 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = 0xFF;
431 /* Update the NAND controller state */
432 hnand
->State
= HAL_NAND_STATE_READY
;
434 /* Process unlocked */
442 * @brief Configure the device: Enter the physical parameters of the device
443 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
444 * the configuration information for NAND module.
445 * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
448 HAL_StatusTypeDef
HAL_NAND_ConfigDevice(NAND_HandleTypeDef
*hnand
, NAND_DeviceConfigTypeDef
*pDeviceConfig
)
450 hnand
->Config
.PageSize
= pDeviceConfig
->PageSize
;
451 hnand
->Config
.SpareAreaSize
= pDeviceConfig
->SpareAreaSize
;
452 hnand
->Config
.BlockSize
= pDeviceConfig
->BlockSize
;
453 hnand
->Config
.BlockNbr
= pDeviceConfig
->BlockNbr
;
454 hnand
->Config
.PlaneSize
= pDeviceConfig
->PlaneSize
;
455 hnand
->Config
.PlaneNbr
= pDeviceConfig
->PlaneNbr
;
456 hnand
->Config
.ExtraCommandEnable
= pDeviceConfig
->ExtraCommandEnable
;
462 * @brief Read Page(s) from NAND memory block (8-bits addressing)
463 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
464 * the configuration information for NAND module.
465 * @param pAddress : pointer to NAND address structure
466 * @param pBuffer : pointer to destination read buffer
467 * @param NumPageToRead : number of pages to read from block
470 HAL_StatusTypeDef
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToRead
)
472 __IO
uint32_t index
= 0U;
473 uint32_t tickstart
= 0U;
474 uint32_t deviceaddress
= 0U, size
= 0U, numPagesRead
= 0U, nandaddress
= 0U;
479 /* Check the NAND controller state */
480 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
485 /* Identify the device address */
486 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
488 deviceaddress
= NAND_DEVICE1
;
492 deviceaddress
= NAND_DEVICE2
;
495 /* Update the NAND controller state */
496 hnand
->State
= HAL_NAND_STATE_BUSY
;
498 /* NAND raw address calculation */
499 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
501 /* Page(s) read loop */
502 while((NumPageToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
504 /* update the buffer size */
505 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
507 /* Send read page command sequence */
508 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
510 /* Cards with page size <= 512 bytes */
511 if((hnand
->Config
.PageSize
) <= 512U)
513 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
515 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
516 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
517 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
519 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
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
);
524 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
527 else /* (hnand->Config.PageSize) > 512 */
529 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
531 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
532 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
533 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
534 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
536 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
538 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
539 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
540 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
541 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
542 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
546 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
548 /* Check if an extra command is needed for reading pages */
549 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
552 tickstart
= HAL_GetTick();
554 /* Read status until NAND is ready */
555 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
557 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
563 /* Go back to read mode */
564 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
567 /* Get Data into Buffer */
568 for(; index
< size
; index
++)
570 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceaddress
;
573 /* Increment read pages number */
576 /* Decrement pages to read */
579 /* Increment the NAND address */
580 nandaddress
= (uint32_t)(nandaddress
+ 1U);
583 /* Update the NAND controller state */
584 hnand
->State
= HAL_NAND_STATE_READY
;
586 /* Process unlocked */
593 * @brief Read Page(s) from NAND memory block (16-bits addressing)
594 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
595 * the configuration information for NAND module.
596 * @param pAddress : pointer to NAND address structure
597 * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
598 * @param NumPageToRead : number of pages to read from block
601 HAL_StatusTypeDef
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToRead
)
603 __IO
uint32_t index
= 0U;
604 uint32_t tickstart
= 0U;
605 uint32_t deviceaddress
= 0U, size
= 0U, numPagesRead
= 0U, nandaddress
= 0U;
610 /* Check the NAND controller state */
611 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
616 /* Identify the device address */
617 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
619 deviceaddress
= NAND_DEVICE1
;
623 deviceaddress
= NAND_DEVICE2
;
626 /* Update the NAND controller state */
627 hnand
->State
= HAL_NAND_STATE_BUSY
;
629 /* NAND raw address calculation */
630 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
632 /* Page(s) read loop */
633 while((NumPageToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
635 /* update the buffer size */
636 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
638 /* Send read page command sequence */
639 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
641 /* Cards with page size <= 512 bytes */
642 if((hnand
->Config
.PageSize
) <= 512U)
644 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
646 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
647 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
648 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
650 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
652 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
653 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
654 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
655 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
658 else /* (hnand->Config.PageSize) > 512 */
660 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
662 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
663 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
664 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
665 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
667 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
669 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
670 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
671 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
672 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
673 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
677 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
679 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
682 tickstart
= HAL_GetTick();
684 /* Read status until NAND is ready */
685 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
687 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
693 /* Go back to read mode */
694 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
697 /* Get Data into Buffer */
698 for(; index
< size
; index
++)
700 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceaddress
;
703 /* Increment read pages number */
706 /* Decrement pages to read */
709 /* Increment the NAND address */
710 nandaddress
= (uint32_t)(nandaddress
+ 1U);
713 /* Update the NAND controller state */
714 hnand
->State
= HAL_NAND_STATE_READY
;
716 /* Process unlocked */
723 * @brief Write Page(s) to NAND memory block (8-bits addressing)
724 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
725 * the configuration information for NAND module.
726 * @param pAddress : pointer to NAND address structure
727 * @param pBuffer : pointer to source buffer to write
728 * @param NumPageToWrite : number of pages to write to block
731 HAL_StatusTypeDef
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToWrite
)
733 __IO
uint32_t index
= 0U;
734 uint32_t tickstart
= 0U;
735 uint32_t deviceaddress
= 0U, size
= 0U, numPagesWritten
= 0U, nandaddress
= 0U;
740 /* Check the NAND controller state */
741 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
746 /* Identify the device address */
747 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
749 deviceaddress
= NAND_DEVICE1
;
753 deviceaddress
= NAND_DEVICE2
;
756 /* Update the NAND controller state */
757 hnand
->State
= HAL_NAND_STATE_BUSY
;
759 /* NAND raw address calculation */
760 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
762 /* Page(s) write loop */
763 while((NumPageToWrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
765 /* update the buffer size */
766 size
= hnand
->Config
.PageSize
+ ((hnand
->Config
.PageSize
) * numPagesWritten
);
768 /* Send write page command sequence */
769 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
770 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
772 /* Cards with page size <= 512 bytes */
773 if((hnand
->Config
.PageSize
) <= 512U)
775 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
777 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
778 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
779 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
781 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
783 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
784 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
785 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
786 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
789 else /* (hnand->Config.PageSize) > 512 */
791 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
793 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
794 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
795 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
796 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
798 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
800 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
801 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
802 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
803 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
804 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
809 /* Write data to memory */
810 for(; index
< size
; index
++)
812 *(__IO
uint8_t *)deviceaddress
= *(uint8_t *)pBuffer
++;
815 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
817 /* Read status until NAND is ready */
818 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
821 tickstart
= HAL_GetTick();
823 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
829 /* Increment written pages number */
832 /* Decrement pages to write */
835 /* Increment the NAND address */
836 nandaddress
= (uint32_t)(nandaddress
+ 1U);
839 /* Update the NAND controller state */
840 hnand
->State
= HAL_NAND_STATE_READY
;
842 /* Process unlocked */
849 * @brief Write Page(s) to NAND memory block (16-bits addressing)
850 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
851 * the configuration information for NAND module.
852 * @param pAddress : pointer to NAND address structure
853 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
854 * @param NumPageToWrite : number of pages to write to block
857 HAL_StatusTypeDef
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToWrite
)
859 __IO
uint32_t index
= 0U;
860 uint32_t tickstart
= 0U;
861 uint32_t deviceaddress
= 0U, size
= 0U, numPagesWritten
= 0U, nandaddress
= 0U;
866 /* Check the NAND controller state */
867 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
872 /* Identify the device address */
873 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
875 deviceaddress
= NAND_DEVICE1
;
879 deviceaddress
= NAND_DEVICE2
;
882 /* Update the NAND controller state */
883 hnand
->State
= HAL_NAND_STATE_BUSY
;
885 /* NAND raw address calculation */
886 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
888 /* Page(s) write loop */
889 while((NumPageToWrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
891 /* update the buffer size */
892 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
894 /* Send write page command sequence */
895 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
896 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
898 /* Cards with page size <= 512 bytes */
899 if((hnand
->Config
.PageSize
) <= 512U)
901 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
903 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
904 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
905 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
907 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
909 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
910 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
911 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
912 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
915 else /* (hnand->Config.PageSize) > 512 */
917 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
919 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
920 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
921 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
922 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
924 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
926 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
927 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
928 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
929 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
930 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
934 /* Write data to memory */
935 for(; index
< size
; index
++)
937 *(__IO
uint16_t *)deviceaddress
= *(uint16_t *)pBuffer
++;
940 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
942 /* Read status until NAND is ready */
943 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
946 tickstart
= HAL_GetTick();
948 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
954 /* Increment written pages number */
957 /* Decrement pages to write */
960 /* Increment the NAND address */
961 nandaddress
= (uint32_t)(nandaddress
+ 1U);
964 /* Update the NAND controller state */
965 hnand
->State
= HAL_NAND_STATE_READY
;
967 /* Process unlocked */
974 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
975 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
976 * the configuration information for NAND module.
977 * @param pAddress : pointer to NAND address structure
978 * @param pBuffer: pointer to source buffer to write
979 * @param NumSpareAreaToRead: Number of spare area to read
982 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaToRead
)
984 __IO
uint32_t index
= 0U;
985 uint32_t tickstart
= 0U;
986 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaRead
= 0U, nandaddress
= 0U, columnaddress
= 0U;
991 /* Check the NAND controller state */
992 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
997 /* Identify the device address */
998 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1000 deviceaddress
= NAND_DEVICE1
;
1004 deviceaddress
= NAND_DEVICE2
;
1007 /* Update the NAND controller state */
1008 hnand
->State
= HAL_NAND_STATE_BUSY
;
1010 /* NAND raw address calculation */
1011 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1013 /* Column in page address */
1014 columnaddress
= COLUMN_ADDRESS(hnand
);
1016 /* Spare area(s) read loop */
1017 while((NumSpareAreaToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1019 /* update the buffer size */
1020 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1022 /* Cards with page size <= 512 bytes */
1023 if((hnand
->Config
.PageSize
) <= 512U)
1025 /* Send read spare area command sequence */
1026 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1028 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1030 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1031 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1032 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1034 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1036 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1037 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1038 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1039 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1042 else /* (hnand->Config.PageSize) > 512 */
1044 /* Send read spare area command sequence */
1045 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1047 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1049 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1050 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1051 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1052 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1054 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1056 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1057 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1058 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1059 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1060 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1064 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1066 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1069 tickstart
= HAL_GetTick();
1071 /* Read status until NAND is ready */
1072 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1074 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1080 /* Go back to read mode */
1081 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
1084 /* Get Data into Buffer */
1085 for(; index
< size
; index
++)
1087 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceaddress
;
1090 /* Increment read spare areas number */
1093 /* Decrement spare areas to read */
1094 NumSpareAreaToRead
--;
1096 /* Increment the NAND address */
1097 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1100 /* Update the NAND controller state */
1101 hnand
->State
= HAL_NAND_STATE_READY
;
1103 /* Process unlocked */
1104 __HAL_UNLOCK(hnand
);
1110 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1111 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1112 * the configuration information for NAND module.
1113 * @param pAddress : pointer to NAND address structure
1114 * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
1115 * @param NumSpareAreaToRead: Number of spare area to read
1116 * @retval HAL status
1118 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1120 __IO
uint32_t index
= 0U;
1121 uint32_t tickstart
= 0U;
1122 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaRead
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1124 /* Process Locked */
1127 /* Check the NAND controller state */
1128 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1133 /* Identify the device address */
1134 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1136 deviceaddress
= NAND_DEVICE1
;
1140 deviceaddress
= NAND_DEVICE2
;
1143 /* Update the NAND controller state */
1144 hnand
->State
= HAL_NAND_STATE_BUSY
;
1146 /* NAND raw address calculation */
1147 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1149 /* Column in page address */
1150 columnaddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2U);
1152 /* Spare area(s) read loop */
1153 while((NumSpareAreaToRead
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1155 /* update the buffer size */
1156 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1158 /* Cards with page size <= 512 bytes */
1159 if((hnand
->Config
.PageSize
) <= 512U)
1161 /* Send read spare area command sequence */
1162 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1164 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1166 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1167 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1168 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1170 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1172 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1173 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1174 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1175 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1178 else /* (hnand->Config.PageSize) > 512 */
1180 /* Send read spare area command sequence */
1181 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1183 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1185 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1186 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1187 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1188 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1190 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1192 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1193 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1194 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1195 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1196 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1200 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1202 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1205 tickstart
= HAL_GetTick();
1207 /* Read status until NAND is ready */
1208 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1210 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1216 /* Go back to read mode */
1217 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = ((uint8_t)0x00);
1220 /* Get Data into Buffer */
1221 for(; index
< size
; index
++)
1223 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceaddress
;
1226 /* Increment read spare areas number */
1229 /* Decrement spare areas to read */
1230 NumSpareAreaToRead
--;
1232 /* Increment the NAND address */
1233 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1236 /* Update the NAND controller state */
1237 hnand
->State
= HAL_NAND_STATE_READY
;
1239 /* Process unlocked */
1240 __HAL_UNLOCK(hnand
);
1246 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1247 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1248 * the configuration information for NAND module.
1249 * @param pAddress : pointer to NAND address structure
1250 * @param pBuffer : pointer to source buffer to write
1251 * @param NumSpareAreaTowrite : number of spare areas to write to block
1252 * @retval HAL status
1254 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1256 __IO
uint32_t index
= 0U;
1257 uint32_t tickstart
= 0U;
1258 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaWritten
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1260 /* Process Locked */
1263 /* Check the NAND controller state */
1264 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1269 /* Identify the device address */
1270 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1272 deviceaddress
= NAND_DEVICE1
;
1276 deviceaddress
= NAND_DEVICE2
;
1279 /* Update the FSMC_NAND controller state */
1280 hnand
->State
= HAL_NAND_STATE_BUSY
;
1282 /* Page address calculation */
1283 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1285 /* Column in page address */
1286 columnaddress
= COLUMN_ADDRESS(hnand
);
1288 /* Spare area(s) write loop */
1289 while((NumSpareAreaTowrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1291 /* update the buffer size */
1292 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1294 /* Cards with page size <= 512 bytes */
1295 if((hnand
->Config
.PageSize
) <= 512U)
1297 /* Send write Spare area command sequence */
1298 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1299 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1301 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1303 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1304 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1305 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1307 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1309 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1310 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1311 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1312 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1315 else /* (hnand->Config.PageSize) > 512 */
1317 /* Send write Spare area command sequence */
1318 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1319 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1321 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1323 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1324 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1325 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1326 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1328 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1330 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1331 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1332 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1333 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1334 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1338 /* Write data to memory */
1339 for(; index
< size
; index
++)
1341 *(__IO
uint8_t *)deviceaddress
= *(uint8_t *)pBuffer
++;
1344 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1347 tickstart
= HAL_GetTick();
1349 /* Read status until NAND is ready */
1350 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1352 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1358 /* Increment written spare areas number */
1359 numSpareAreaWritten
++;
1361 /* Decrement spare areas to write */
1362 NumSpareAreaTowrite
--;
1364 /* Increment the NAND address */
1365 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1368 /* Update the NAND controller state */
1369 hnand
->State
= HAL_NAND_STATE_READY
;
1371 /* Process unlocked */
1372 __HAL_UNLOCK(hnand
);
1378 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1379 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1380 * the configuration information for NAND module.
1381 * @param pAddress : pointer to NAND address structure
1382 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
1383 * @param NumSpareAreaTowrite : number of spare areas to write to block
1384 * @retval HAL status
1386 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1388 __IO
uint32_t index
= 0U;
1389 uint32_t tickstart
= 0U;
1390 uint32_t deviceaddress
= 0U, size
= 0U, numSpareAreaWritten
= 0U, nandaddress
= 0U, columnaddress
= 0U;
1392 /* Process Locked */
1395 /* Check the NAND controller state */
1396 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1401 /* Identify the device address */
1402 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1404 deviceaddress
= NAND_DEVICE1
;
1408 deviceaddress
= NAND_DEVICE2
;
1411 /* Update the FSMC_NAND controller state */
1412 hnand
->State
= HAL_NAND_STATE_BUSY
;
1414 /* NAND raw address calculation */
1415 nandaddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1417 /* Column in page address */
1418 columnaddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2U);
1420 /* Spare area(s) write loop */
1421 while((NumSpareAreaTowrite
!= 0U) && (nandaddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1423 /* update the buffer size */
1424 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1426 /* Cards with page size <= 512 bytes */
1427 if((hnand
->Config
.PageSize
) <= 512U)
1429 /* Send write Spare area command sequence */
1430 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1431 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1433 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1435 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1436 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1437 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1439 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1441 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = 0x00;
1442 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1443 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1444 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1447 else /* (hnand->Config.PageSize) > 512 */
1449 /* Send write Spare area command sequence */
1450 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1451 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1453 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535U)
1455 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1456 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1457 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1458 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1460 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1462 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnaddress
);
1463 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnaddress
);
1464 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandaddress
);
1465 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandaddress
);
1466 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandaddress
);
1470 /* Write data to memory */
1471 for(; index
< size
; index
++)
1473 *(__IO
uint16_t *)deviceaddress
= *(uint16_t *)pBuffer
++;
1476 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1478 /* Read status until NAND is ready */
1479 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1482 tickstart
= HAL_GetTick();
1484 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1490 /* Increment written spare areas number */
1491 numSpareAreaWritten
++;
1493 /* Decrement spare areas to write */
1494 NumSpareAreaTowrite
--;
1496 /* Increment the NAND address */
1497 nandaddress
= (uint32_t)(nandaddress
+ 1U);
1500 /* Update the NAND controller state */
1501 hnand
->State
= HAL_NAND_STATE_READY
;
1503 /* Process unlocked */
1504 __HAL_UNLOCK(hnand
);
1510 * @brief NAND memory Block erase
1511 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1512 * the configuration information for NAND module.
1513 * @param pAddress : pointer to NAND address structure
1514 * @retval HAL status
1516 HAL_StatusTypeDef
HAL_NAND_Erase_Block(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1518 uint32_t deviceaddress
= 0U;
1519 uint32_t tickstart
= 0U;
1521 /* Process Locked */
1524 /* Check the NAND controller state */
1525 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1530 /* Identify the device address */
1531 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1533 deviceaddress
= NAND_DEVICE1
;
1537 deviceaddress
= NAND_DEVICE2
;
1540 /* Update the NAND controller state */
1541 hnand
->State
= HAL_NAND_STATE_BUSY
;
1543 /* Send Erase block command sequence */
1544 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_ERASE0
;
1546 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1547 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1548 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1550 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_ERASE1
;
1552 /* Update the NAND controller state */
1553 hnand
->State
= HAL_NAND_STATE_READY
;
1556 tickstart
= HAL_GetTick();
1558 /* Read status until NAND is ready */
1559 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1561 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1563 /* Process unlocked */
1564 __HAL_UNLOCK(hnand
);
1570 /* Process unlocked */
1571 __HAL_UNLOCK(hnand
);
1577 * @brief NAND memory read status
1578 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1579 * the configuration information for NAND module.
1580 * @retval NAND status
1582 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef
*hnand
)
1585 uint32_t deviceaddress
= 0U;
1587 /* Identify the device address */
1588 if(hnand
->Init
.NandBank
== FSMC_NAND_BANK2
)
1590 deviceaddress
= NAND_DEVICE1
;
1594 deviceaddress
= NAND_DEVICE2
;
1597 /* Send Read status operation command */
1598 *(__IO
uint8_t *)((uint32_t)(deviceaddress
| CMD_AREA
)) = NAND_CMD_STATUS
;
1600 /* Read status register data */
1601 data
= *(__IO
uint8_t *)deviceaddress
;
1603 /* Return the status */
1604 if((data
& NAND_ERROR
) == NAND_ERROR
)
1608 else if((data
& NAND_READY
) == NAND_READY
)
1617 * @brief Increment the NAND memory address
1618 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1619 * the configuration information for NAND module.
1620 * @param pAddress: pointer to NAND address structure
1621 * @retval The new status of the increment address operation. It can be:
1622 * - NAND_VALID_ADDRESS: When the new address is valid address
1623 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1625 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1627 uint32_t status
= NAND_VALID_ADDRESS
;
1629 /* Increment page address */
1632 /* Check NAND address is valid */
1633 if(pAddress
->Page
== hnand
->Config
.BlockSize
)
1635 pAddress
->Page
= 0U;
1638 if(pAddress
->Block
== hnand
->Config
.PlaneSize
)
1640 pAddress
->Block
= 0U;
1643 if(pAddress
->Plane
== (hnand
->Config
.PlaneNbr
))
1645 status
= NAND_INVALID_ADDRESS
;
1656 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1657 * @brief management functions
1660 ==============================================================================
1661 ##### NAND Control functions #####
1662 ==============================================================================
1664 This subsection provides a set of functions allowing to control dynamically
1673 * @brief Enables dynamically NAND ECC feature.
1674 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1675 * the configuration information for NAND module.
1676 * @retval HAL status
1678 HAL_StatusTypeDef
HAL_NAND_ECC_Enable(NAND_HandleTypeDef
*hnand
)
1680 /* Check the NAND controller state */
1681 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1686 /* Update the NAND state */
1687 hnand
->State
= HAL_NAND_STATE_BUSY
;
1689 /* Enable ECC feature */
1690 FSMC_NAND_ECC_Enable(hnand
->Instance
, hnand
->Init
.NandBank
);
1692 /* Update the NAND state */
1693 hnand
->State
= HAL_NAND_STATE_READY
;
1699 * @brief Disables dynamically FSMC_NAND ECC feature.
1700 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1701 * the configuration information for NAND module.
1702 * @retval HAL status
1704 HAL_StatusTypeDef
HAL_NAND_ECC_Disable(NAND_HandleTypeDef
*hnand
)
1706 /* Check the NAND controller state */
1707 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1712 /* Update the NAND state */
1713 hnand
->State
= HAL_NAND_STATE_BUSY
;
1715 /* Disable ECC feature */
1716 FSMC_NAND_ECC_Disable(hnand
->Instance
, hnand
->Init
.NandBank
);
1718 /* Update the NAND state */
1719 hnand
->State
= HAL_NAND_STATE_READY
;
1725 * @brief Disables dynamically NAND ECC feature.
1726 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1727 * the configuration information for NAND module.
1728 * @param ECCval: pointer to ECC value
1729 * @param Timeout: maximum timeout to wait
1730 * @retval HAL status
1732 HAL_StatusTypeDef
HAL_NAND_GetECC(NAND_HandleTypeDef
*hnand
, uint32_t *ECCval
, uint32_t Timeout
)
1734 HAL_StatusTypeDef status
= HAL_OK
;
1736 /* Check the NAND controller state */
1737 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1742 /* Update the NAND state */
1743 hnand
->State
= HAL_NAND_STATE_BUSY
;
1745 /* Get NAND ECC value */
1746 status
= FSMC_NAND_GetECC(hnand
->Instance
, ECCval
, hnand
->Init
.NandBank
, Timeout
);
1748 /* Update the NAND state */
1749 hnand
->State
= HAL_NAND_STATE_READY
;
1759 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1760 * @brief Peripheral State functions
1763 ==============================================================================
1764 ##### NAND State functions #####
1765 ==============================================================================
1767 This subsection permits to get in run-time the status of the NAND controller
1775 * @brief return the NAND state
1776 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1777 * the configuration information for NAND module.
1780 HAL_NAND_StateTypeDef
HAL_NAND_GetState(NAND_HandleTypeDef
*hnand
)
1782 return hnand
->State
;
1797 #endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
1798 #endif /* HAL_NAND_MODULE_ENABLED */
1804 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/