2 ******************************************************************************
3 * @file stm32f7xx_hal_nand.c
4 * @author MCD Application Team
5 * @brief NAND HAL module driver.
6 * This file provides a generic firmware to drive NAND memories mounted
10 ==============================================================================
11 ##### How to use this driver #####
12 ==============================================================================
14 This driver is a generic layered driver which contains a set of APIs used to
15 control NAND flash memories. It uses the FMC/FSMC layer functions to interface
16 with NAND devices. This driver is used as follows:
18 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
19 with control and timing parameters for both common and attribute spaces.
21 (+) Read NAND flash memory maker and device IDs using the function
22 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
23 structure declared by the function caller.
25 (+) Access NAND flash memory by read/write operations using the functions
26 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
27 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
28 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
29 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
30 to read/write page(s)/spare area(s). These functions use specific device
31 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
32 structure. The read/write address information is contained by the Nand_Address_Typedef
33 structure passed as parameter.
35 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
37 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
38 The erase block address information is contained in the Nand_Address_Typedef
39 structure passed as parameter.
41 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
43 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
44 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
45 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
47 (+) You can monitor the NAND device HAL state by calling the function
51 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
52 If a NAND flash device contains different operations and/or implementations,
53 it should be implemented separately.
55 *** Callback registration ***
56 =============================================
58 The compilation define USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
59 allows the user to configure dynamically the driver callbacks.
61 Use Functions @ref HAL_NAND_RegisterCallback() to register a user callback,
62 it allows to register following callbacks:
63 (+) MspInitCallback : NAND MspInit.
64 (+) MspDeInitCallback : NAND MspDeInit.
65 This function takes as parameters the HAL peripheral handle, the Callback ID
66 and a pointer to the user callback function.
68 Use function @ref HAL_NAND_UnRegisterCallback() to reset a callback to the default
69 weak (surcharged) function. It allows to reset following callbacks:
70 (+) MspInitCallback : NAND MspInit.
71 (+) MspDeInitCallback : NAND MspDeInit.
72 This function) takes as parameters the HAL peripheral handle and the Callback ID.
74 By default, after the @ref HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
75 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
76 Exception done for MspInit and MspDeInit callbacks that are respectively
77 reset to the legacy weak (surcharged) functions in the @ref HAL_NAND_Init
78 and @ref HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
79 If not, MspInit or MspDeInit are not null, the @ref HAL_NAND_Init and @ref HAL_NAND_DeInit
80 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
82 Callbacks can be registered/unregistered in READY state only.
83 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
84 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
85 during the Init/DeInit.
86 In that case first register the MspInit/MspDeInit user callbacks
87 using @ref HAL_NAND_RegisterCallback before calling @ref HAL_NAND_DeInit
88 or @ref HAL_NAND_Init function.
90 When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
91 not defined, the callback registering feature is not available
92 and weak (surcharged) callbacks are used.
95 ******************************************************************************
98 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
99 * All rights reserved.</center></h2>
101 * This software component is licensed by ST under BSD 3-Clause license,
102 * the "License"; You may not use this file except in compliance with the
103 * License. You may obtain a copy of the License at:
104 * opensource.org/licenses/BSD-3-Clause
106 ******************************************************************************
109 /* Includes ------------------------------------------------------------------*/
110 #include "stm32f7xx_hal.h"
112 /** @addtogroup STM32F7xx_HAL_Driver
117 #ifdef HAL_NAND_MODULE_ENABLED
119 /** @defgroup NAND NAND
120 * @brief NAND HAL module driver
124 /* Private typedef -----------------------------------------------------------*/
125 /* Private Constants ------------------------------------------------------------*/
126 /* Private macro -------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /* Private function prototypes -----------------------------------------------*/
129 /* Exported functions ---------------------------------------------------------*/
131 /** @defgroup NAND_Exported_Functions NAND Exported Functions
135 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
136 * @brief Initialization and Configuration functions
139 ==============================================================================
140 ##### NAND Initialization and de-initialization functions #####
141 ==============================================================================
143 This section provides functions allowing to initialize/de-initialize
151 * @brief Perform NAND memory Initialization sequence
152 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
153 * the configuration information for NAND module.
154 * @param ComSpace_Timing pointer to Common space timing structure
155 * @param AttSpace_Timing pointer to Attribute space timing structure
158 HAL_StatusTypeDef
HAL_NAND_Init(NAND_HandleTypeDef
*hnand
, FMC_NAND_PCC_TimingTypeDef
*ComSpace_Timing
, FMC_NAND_PCC_TimingTypeDef
*AttSpace_Timing
)
160 /* Check the NAND handle state */
166 if(hnand
->State
== HAL_NAND_STATE_RESET
)
168 /* Allocate lock resource and initialize it */
169 hnand
->Lock
= HAL_UNLOCKED
;
171 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
172 if(hnand
->MspInitCallback
== NULL
)
174 hnand
->MspInitCallback
= HAL_NAND_MspInit
;
176 hnand
->ItCallback
= HAL_NAND_ITCallback
;
178 /* Init the low level hardware */
179 hnand
->MspInitCallback(hnand
);
181 /* Initialize the low level hardware (MSP) */
182 HAL_NAND_MspInit(hnand
);
186 /* Initialize NAND control Interface */
187 FMC_NAND_Init(hnand
->Instance
, &(hnand
->Init
));
189 /* Initialize NAND common space timing Interface */
190 FMC_NAND_CommonSpace_Timing_Init(hnand
->Instance
, ComSpace_Timing
, hnand
->Init
.NandBank
);
192 /* Initialize NAND attribute space timing Interface */
193 FMC_NAND_AttributeSpace_Timing_Init(hnand
->Instance
, AttSpace_Timing
, hnand
->Init
.NandBank
);
195 /* Enable the NAND device */
196 __FMC_NAND_ENABLE(hnand
->Instance
);
198 /* Update the NAND controller state */
199 hnand
->State
= HAL_NAND_STATE_READY
;
205 * @brief Perform NAND memory De-Initialization sequence
206 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
207 * the configuration information for NAND module.
210 HAL_StatusTypeDef
HAL_NAND_DeInit(NAND_HandleTypeDef
*hnand
)
212 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
213 if(hnand
->MspDeInitCallback
== NULL
)
215 hnand
->MspDeInitCallback
= HAL_NAND_MspDeInit
;
218 /* DeInit the low level hardware */
219 hnand
->MspDeInitCallback(hnand
);
221 /* Initialize the low level hardware (MSP) */
222 HAL_NAND_MspDeInit(hnand
);
225 /* Configure the NAND registers with their reset values */
226 FMC_NAND_DeInit(hnand
->Instance
, hnand
->Init
.NandBank
);
228 /* Reset the NAND controller state */
229 hnand
->State
= HAL_NAND_STATE_RESET
;
238 * @brief NAND MSP Init
239 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
240 * the configuration information for NAND module.
243 __weak
void HAL_NAND_MspInit(NAND_HandleTypeDef
*hnand
)
245 /* Prevent unused argument(s) compilation warning */
248 /* NOTE : This function Should not be modified, when the callback is needed,
249 the HAL_NAND_MspInit could be implemented in the user file
254 * @brief NAND MSP DeInit
255 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
256 * the configuration information for NAND module.
259 __weak
void HAL_NAND_MspDeInit(NAND_HandleTypeDef
*hnand
)
261 /* Prevent unused argument(s) compilation warning */
264 /* NOTE : This function Should not be modified, when the callback is needed,
265 the HAL_NAND_MspDeInit could be implemented in the user file
271 * @brief This function handles NAND device interrupt request.
272 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
273 * the configuration information for NAND module.
276 void HAL_NAND_IRQHandler(NAND_HandleTypeDef
*hnand
)
278 /* Check NAND interrupt Rising edge flag */
279 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
))
281 /* NAND interrupt callback*/
282 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
283 hnand
->ItCallback(hnand
);
285 HAL_NAND_ITCallback(hnand
);
288 /* Clear NAND interrupt Rising edge pending bit */
289 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_RISING_EDGE
);
292 /* Check NAND interrupt Level flag */
293 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
))
295 /* NAND interrupt callback*/
296 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
297 hnand
->ItCallback(hnand
);
299 HAL_NAND_ITCallback(hnand
);
302 /* Clear NAND interrupt Level pending bit */
303 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_LEVEL
);
306 /* Check NAND interrupt Falling edge flag */
307 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
))
309 /* NAND interrupt callback*/
310 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
311 hnand
->ItCallback(hnand
);
313 HAL_NAND_ITCallback(hnand
);
316 /* Clear NAND interrupt Falling edge pending bit */
317 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_FALLING_EDGE
);
320 /* Check NAND interrupt FIFO empty flag */
321 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
))
323 /* NAND interrupt callback*/
324 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
325 hnand
->ItCallback(hnand
);
327 HAL_NAND_ITCallback(hnand
);
330 /* Clear NAND interrupt FIFO empty pending bit */
331 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_FEMPT
);
337 * @brief NAND interrupt feature callback
338 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
339 * the configuration information for NAND module.
342 __weak
void HAL_NAND_ITCallback(NAND_HandleTypeDef
*hnand
)
344 /* Prevent unused argument(s) compilation warning */
347 /* NOTE : This function Should not be modified, when the callback is needed,
348 the HAL_NAND_ITCallback could be implemented in the user file
356 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
357 * @brief Input Output and memory control functions
360 ==============================================================================
361 ##### NAND Input and Output functions #####
362 ==============================================================================
364 This section provides functions allowing to use and control the NAND
372 * @brief Read the NAND memory electronic signature
373 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
374 * the configuration information for NAND module.
375 * @param pNAND_ID NAND ID structure
378 HAL_StatusTypeDef
HAL_NAND_Read_ID(NAND_HandleTypeDef
*hnand
, NAND_IDTypeDef
*pNAND_ID
)
380 __IO
uint32_t data
= 0;
381 __IO
uint32_t data1
= 0;
382 uint32_t deviceAddress
= 0;
387 /* Check the NAND controller state */
388 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
393 /* Identify the device address */
394 deviceAddress
= NAND_DEVICE
;
396 /* Update the NAND controller state */
397 hnand
->State
= HAL_NAND_STATE_BUSY
;
399 /* Send Read ID command sequence */
400 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_READID
;
402 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
405 /* Read the electronic signature from NAND flash */
406 if (hnand
->Init
.MemoryDataWidth
== FMC_NAND_PCC_MEM_BUS_WIDTH_8
)
408 data
= *(__IO
uint32_t *)deviceAddress
;
410 /* Return the data read */
411 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
412 pNAND_ID
->Device_Id
= ADDR_2ND_CYCLE(data
);
413 pNAND_ID
->Third_Id
= ADDR_3RD_CYCLE(data
);
414 pNAND_ID
->Fourth_Id
= ADDR_4TH_CYCLE(data
);
418 data
= *(__IO
uint32_t *)deviceAddress
;
419 data1
= *((__IO
uint32_t *)deviceAddress
+ 4);
421 /* Return the data read */
422 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
423 pNAND_ID
->Device_Id
= ADDR_3RD_CYCLE(data
);
424 pNAND_ID
->Third_Id
= ADDR_1ST_CYCLE(data1
);
425 pNAND_ID
->Fourth_Id
= ADDR_3RD_CYCLE(data1
);
428 /* Update the NAND controller state */
429 hnand
->State
= HAL_NAND_STATE_READY
;
431 /* Process unlocked */
438 * @brief NAND memory reset
439 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
440 * the configuration information for NAND module.
443 HAL_StatusTypeDef
HAL_NAND_Reset(NAND_HandleTypeDef
*hnand
)
445 uint32_t deviceAddress
= 0;
450 /* Check the NAND controller state */
451 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
456 /* Identify the device address */
457 deviceAddress
= NAND_DEVICE
;
459 /* Update the NAND controller state */
460 hnand
->State
= HAL_NAND_STATE_BUSY
;
462 /* Send NAND reset command */
463 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0xFF;
465 /* Update the NAND controller state */
466 hnand
->State
= HAL_NAND_STATE_READY
;
468 /* Process unlocked */
476 * @brief Configure the device: Enter the physical parameters of the device
477 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
478 * the configuration information for NAND module.
479 * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure
482 HAL_StatusTypeDef
HAL_NAND_ConfigDevice(NAND_HandleTypeDef
*hnand
, NAND_DeviceConfigTypeDef
*pDeviceConfig
)
484 hnand
->Config
.PageSize
= pDeviceConfig
->PageSize
;
485 hnand
->Config
.SpareAreaSize
= pDeviceConfig
->SpareAreaSize
;
486 hnand
->Config
.BlockSize
= pDeviceConfig
->BlockSize
;
487 hnand
->Config
.BlockNbr
= pDeviceConfig
->BlockNbr
;
488 hnand
->Config
.PlaneSize
= pDeviceConfig
->PlaneSize
;
489 hnand
->Config
.PlaneNbr
= pDeviceConfig
->PlaneNbr
;
490 hnand
->Config
.ExtraCommandEnable
= pDeviceConfig
->ExtraCommandEnable
;
497 * @brief Read Page(s) from NAND memory block (8-bits addressing)
498 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
499 * the configuration information for NAND module.
500 * @param pAddress pointer to NAND address structure
501 * @param pBuffer pointer to destination read buffer
502 * @param NumPageToRead number of pages to read from block
505 HAL_StatusTypeDef
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToRead
)
507 __IO
uint32_t index
= 0;
508 uint32_t tickstart
= 0U;
509 uint32_t deviceAddress
= 0, size
= 0, numPagesRead
= 0, nandAddress
= 0;
514 /* Check the NAND controller state */
515 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
520 /* Identify the device address */
521 deviceAddress
= NAND_DEVICE
;
523 /* Update the NAND controller state */
524 hnand
->State
= HAL_NAND_STATE_BUSY
;
526 /* NAND raw address calculation */
527 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
529 /* Page(s) read loop */
530 while((NumPageToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
532 /* update the buffer size */
533 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
535 /* Send read page command sequence */
536 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
539 /* Cards with page size <= 512 bytes */
540 if((hnand
->Config
.PageSize
) <= 512)
542 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
544 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
546 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
548 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
551 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
553 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
555 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
557 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
559 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
563 else /* (hnand->Config.PageSize) > 512 */
565 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
567 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
569 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
571 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
573 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
576 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
578 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
580 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
582 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
584 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
586 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
591 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
595 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
598 tickstart
= HAL_GetTick();
600 /* Read status until NAND is ready */
601 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
603 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
609 /* Go back to read mode */
610 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
614 /* Get Data into Buffer */
615 for(; index
< size
; index
++)
617 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
620 /* Increment read pages number */
623 /* Decrement pages to read */
626 /* Increment the NAND address */
627 nandAddress
= (uint32_t)(nandAddress
+ 1);
630 /* Update the NAND controller state */
631 hnand
->State
= HAL_NAND_STATE_READY
;
633 /* Process unlocked */
641 * @brief Read Page(s) from NAND memory block (16-bits addressing)
642 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
643 * the configuration information for NAND module.
644 * @param pAddress pointer to NAND address structure
645 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned
646 * @param NumPageToRead number of pages to read from block
649 HAL_StatusTypeDef
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToRead
)
651 __IO
uint32_t index
= 0;
652 uint32_t tickstart
= 0;
653 uint32_t deviceAddress
= 0, size
= 0, numPagesRead
= 0, nandAddress
= 0;
658 /* Check the NAND controller state */
659 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
664 /* Identify the device address */
665 deviceAddress
= NAND_DEVICE
;
667 /* Update the NAND controller state */
668 hnand
->State
= HAL_NAND_STATE_BUSY
;
670 /* NAND raw address calculation */
671 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
673 /* Page(s) read loop */
674 while((NumPageToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
676 /* update the buffer size */
677 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
679 /* Send read page command sequence */
680 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
683 /* Cards with page size <= 512 bytes */
684 if((hnand
->Config
.PageSize
) <= 512)
686 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
688 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
690 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
692 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
695 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
697 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
699 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
701 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
703 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
707 else /* (hnand->Config.PageSize) > 512 */
709 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
711 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
713 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
715 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
717 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
720 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
722 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
724 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
726 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
728 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
730 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
735 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
738 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
741 tickstart
= HAL_GetTick();
743 /* Read status until NAND is ready */
744 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
746 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
752 /* Go back to read mode */
753 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
757 /* Get Data into Buffer */
758 for(; index
< size
; index
++)
760 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceAddress
;
763 /* Increment read pages number */
766 /* Decrement pages to read */
769 /* Increment the NAND address */
770 nandAddress
= (uint32_t)(nandAddress
+ 1);
773 /* Update the NAND controller state */
774 hnand
->State
= HAL_NAND_STATE_READY
;
776 /* Process unlocked */
783 * @brief Write Page(s) to NAND memory block (8-bits addressing)
784 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
785 * the configuration information for NAND module.
786 * @param pAddress pointer to NAND address structure
787 * @param pBuffer pointer to source buffer to write
788 * @param NumPageToWrite number of pages to write to block
791 HAL_StatusTypeDef
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToWrite
)
793 __IO
uint32_t index
= 0;
794 uint32_t tickstart
= 0;
795 uint32_t deviceAddress
= 0, size
= 0, numPagesWritten
= 0, nandAddress
= 0;
800 /* Check the NAND controller state */
801 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
806 /* Identify the device address */
807 deviceAddress
= NAND_DEVICE
;
809 /* Update the NAND controller state */
810 hnand
->State
= HAL_NAND_STATE_BUSY
;
812 /* NAND raw address calculation */
813 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
815 /* Page(s) write loop */
816 while((NumPageToWrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
818 /* update the buffer size */
819 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
821 /* Send write page command sequence */
822 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
824 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
827 /* Cards with page size <= 512 bytes */
828 if((hnand
->Config
.PageSize
) <= 512)
830 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
832 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
834 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
836 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
839 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
841 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
843 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
845 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
847 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
851 else /* (hnand->Config.PageSize) > 512 */
853 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
855 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
857 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
859 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
861 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
864 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
866 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
868 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
870 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
872 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
874 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
879 /* Write data to memory */
880 for(; index
< size
; index
++)
882 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
886 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
890 tickstart
= HAL_GetTick();
892 /* Read status until NAND is ready */
893 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
895 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
901 /* Increment written pages number */
904 /* Decrement pages to write */
907 /* Increment the NAND address */
908 nandAddress
= (uint32_t)(nandAddress
+ 1);
911 /* Update the NAND controller state */
912 hnand
->State
= HAL_NAND_STATE_READY
;
914 /* Process unlocked */
921 * @brief Write Page(s) to NAND memory block (16-bits addressing)
922 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
923 * the configuration information for NAND module.
924 * @param pAddress pointer to NAND address structure
925 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
926 * @param NumPageToWrite number of pages to write to block
929 HAL_StatusTypeDef
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToWrite
)
931 __IO
uint32_t index
= 0;
932 uint32_t tickstart
= 0;
933 uint32_t deviceAddress
= 0, size
= 0, numPagesWritten
= 0, nandAddress
= 0;
938 /* Check the NAND controller state */
939 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
944 /* Identify the device address */
945 deviceAddress
= NAND_DEVICE
;
947 /* Update the NAND controller state */
948 hnand
->State
= HAL_NAND_STATE_BUSY
;
950 /* NAND raw address calculation */
951 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
953 /* Page(s) write loop */
954 while((NumPageToWrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
956 /* update the buffer size */
957 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
959 /* Send write page command sequence */
960 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
962 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
965 /* Cards with page size <= 512 bytes */
966 if((hnand
->Config
.PageSize
) <= 512)
968 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
970 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
972 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
974 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
977 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
979 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
981 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
983 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
985 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
989 else /* (hnand->Config.PageSize) > 512 */
991 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
993 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
995 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
997 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
999 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1002 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1004 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1006 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1008 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1010 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1012 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1017 /* Write data to memory */
1018 for(; index
< size
; index
++)
1020 *(__IO
uint16_t *)deviceAddress
= *(uint16_t *)pBuffer
++;
1024 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1028 tickstart
= HAL_GetTick();
1030 /* Read status until NAND is ready */
1031 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1033 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1039 /* Increment written pages number */
1042 /* Decrement pages to write */
1045 /* Increment the NAND address */
1046 nandAddress
= (uint32_t)(nandAddress
+ 1);
1049 /* Update the NAND controller state */
1050 hnand
->State
= HAL_NAND_STATE_READY
;
1052 /* Process unlocked */
1053 __HAL_UNLOCK(hnand
);
1059 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
1060 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1061 * the configuration information for NAND module.
1062 * @param pAddress pointer to NAND address structure
1063 * @param pBuffer pointer to source buffer to write
1064 * @param NumSpareAreaToRead Number of spare area to read
1065 * @retval HAL status
1067 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1069 __IO
uint32_t index
= 0;
1070 uint32_t tickstart
= 0U;
1071 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaRead
= 0, nandAddress
= 0, columnAddress
= 0;
1073 /* Process Locked */
1076 /* Check the NAND controller state */
1077 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1082 /* Identify the device address */
1083 deviceAddress
= NAND_DEVICE
;
1085 /* Update the NAND controller state */
1086 hnand
->State
= HAL_NAND_STATE_BUSY
;
1088 /* NAND raw address calculation */
1089 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1091 /* Column in page address */
1092 columnAddress
= COLUMN_ADDRESS(hnand
);
1094 /* Spare area(s) read loop */
1095 while((NumSpareAreaToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1097 /* update the buffer size */
1098 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1100 /* Cards with page size <= 512 bytes */
1101 if((hnand
->Config
.PageSize
) <= 512)
1103 /* Send read spare area command sequence */
1104 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1107 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1109 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1111 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1113 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1116 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1118 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1120 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1122 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1124 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1128 else /* (hnand->Config.PageSize) > 512 */
1130 /* Send read spare area command sequence */
1131 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1134 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1136 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1138 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1140 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1142 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1145 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1147 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1149 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1151 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1153 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1155 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1160 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1163 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1166 tickstart
= HAL_GetTick();
1168 /* Read status until NAND is ready */
1169 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1171 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1177 /* Go back to read mode */
1178 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
1182 /* Get Data into Buffer */
1183 for(; index
< size
; index
++)
1185 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
1188 /* Increment read spare areas number */
1191 /* Decrement spare areas to read */
1192 NumSpareAreaToRead
--;
1194 /* Increment the NAND address */
1195 nandAddress
= (uint32_t)(nandAddress
+ 1);
1198 /* Update the NAND controller state */
1199 hnand
->State
= HAL_NAND_STATE_READY
;
1201 /* Process unlocked */
1202 __HAL_UNLOCK(hnand
);
1208 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1209 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1210 * the configuration information for NAND module.
1211 * @param pAddress pointer to NAND address structure
1212 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1213 * @param NumSpareAreaToRead Number of spare area to read
1214 * @retval HAL status
1216 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1218 __IO
uint32_t index
= 0;
1219 uint32_t tickstart
= 0U;
1220 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaRead
= 0, nandAddress
= 0, columnAddress
= 0;
1222 /* Process Locked */
1225 /* Check the NAND controller state */
1226 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1231 /* Identify the device address */
1232 deviceAddress
= NAND_DEVICE
;
1234 /* Update the NAND controller state */
1235 hnand
->State
= HAL_NAND_STATE_BUSY
;
1237 /* NAND raw address calculation */
1238 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1240 /* Column in page address */
1241 columnAddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2);
1243 /* Spare area(s) read loop */
1244 while((NumSpareAreaToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1246 /* update the buffer size */
1247 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1249 /* Cards with page size <= 512 bytes */
1250 if((hnand
->Config
.PageSize
) <= 512)
1252 /* Send read spare area command sequence */
1253 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1256 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1258 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1260 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1262 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1265 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1267 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1269 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1271 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1273 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1277 else /* (hnand->Config.PageSize) > 512 */
1279 /* Send read spare area command sequence */
1280 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1283 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1285 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1287 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1289 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1291 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1294 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1296 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1298 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1300 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1302 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1304 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1309 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1312 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1315 tickstart
= HAL_GetTick();
1317 /* Read status until NAND is ready */
1318 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1320 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1326 /* Go back to read mode */
1327 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
1331 /* Get Data into Buffer */
1332 for(; index
< size
; index
++)
1334 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceAddress
;
1337 /* Increment read spare areas number */
1340 /* Decrement spare areas to read */
1341 NumSpareAreaToRead
--;
1343 /* Increment the NAND address */
1344 nandAddress
= (uint32_t)(nandAddress
+ 1);
1347 /* Update the NAND controller state */
1348 hnand
->State
= HAL_NAND_STATE_READY
;
1350 /* Process unlocked */
1351 __HAL_UNLOCK(hnand
);
1357 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1358 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1359 * the configuration information for NAND module.
1360 * @param pAddress pointer to NAND address structure
1361 * @param pBuffer pointer to source buffer to write
1362 * @param NumSpareAreaTowrite number of spare areas to write to block
1363 * @retval HAL status
1365 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1367 __IO
uint32_t index
= 0;
1368 uint32_t tickstart
= 0;
1369 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaWritten
= 0, nandAddress
= 0, columnAddress
=0;
1371 /* Process Locked */
1374 /* Check the NAND controller state */
1375 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1380 /* Identify the device address */
1381 deviceAddress
= NAND_DEVICE
;
1383 /* Update the FMC_NAND controller state */
1384 hnand
->State
= HAL_NAND_STATE_BUSY
;
1386 /* Page address calculation */
1387 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1389 /* Column in page address */
1390 columnAddress
= COLUMN_ADDRESS(hnand
);
1392 /* Spare area(s) write loop */
1393 while((NumSpareAreaTowrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1395 /* update the buffer size */
1396 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1398 /* Cards with page size <= 512 bytes */
1399 if((hnand
->Config
.PageSize
) <= 512)
1401 /* Send write Spare area command sequence */
1402 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1404 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1407 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1409 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1411 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1413 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1416 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1418 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1420 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1422 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1424 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1428 else /* (hnand->Config.PageSize) > 512 */
1430 /* Send write Spare area command sequence */
1431 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1433 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1436 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1438 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1440 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1442 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1444 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1447 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1449 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1451 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1453 *(__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
);
1457 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1462 /* Write data to memory */
1463 for(; index
< size
; index
++)
1465 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
1469 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1473 tickstart
= HAL_GetTick();
1475 /* Read status until NAND is ready */
1476 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1478 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1484 /* Increment written spare areas number */
1485 numSpareAreaWritten
++;
1487 /* Decrement spare areas to write */
1488 NumSpareAreaTowrite
--;
1490 /* Increment the NAND address */
1491 nandAddress
= (uint32_t)(nandAddress
+ 1);
1494 /* Update the NAND controller state */
1495 hnand
->State
= HAL_NAND_STATE_READY
;
1497 /* Process unlocked */
1498 __HAL_UNLOCK(hnand
);
1504 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1505 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1506 * the configuration information for NAND module.
1507 * @param pAddress pointer to NAND address structure
1508 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1509 * @param NumSpareAreaTowrite number of spare areas to write to block
1510 * @retval HAL status
1512 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1514 __IO
uint32_t index
= 0;
1515 uint32_t tickstart
= 0;
1516 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaWritten
= 0, nandAddress
= 0, columnAddress
= 0;
1518 /* Process Locked */
1521 /* Check the NAND controller state */
1522 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1527 /* Identify the device address */
1528 deviceAddress
= NAND_DEVICE
;
1530 /* Update the FMC_NAND controller state */
1531 hnand
->State
= HAL_NAND_STATE_BUSY
;
1533 /* NAND raw address calculation */
1534 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1536 /* Column in page address */
1537 columnAddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2);
1539 /* Spare area(s) write loop */
1540 while((NumSpareAreaTowrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1542 /* update the buffer size */
1543 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1545 /* Cards with page size <= 512 bytes */
1546 if((hnand
->Config
.PageSize
) <= 512)
1548 /* Send write Spare area command sequence */
1549 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1551 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1554 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1556 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1558 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1560 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1563 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1565 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1567 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1569 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1571 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1575 else /* (hnand->Config.PageSize) > 512 */
1577 /* Send write Spare area command sequence */
1578 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1580 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1583 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1585 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1587 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1589 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1591 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1594 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1596 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1598 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1600 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1602 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1604 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1609 /* Write data to memory */
1610 for(; index
< size
; index
++)
1612 *(__IO
uint16_t *)deviceAddress
= *(uint16_t *)pBuffer
++;
1616 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1620 tickstart
= HAL_GetTick();
1622 /* Read status until NAND is ready */
1623 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1625 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1631 /* Increment written spare areas number */
1632 numSpareAreaWritten
++;
1634 /* Decrement spare areas to write */
1635 NumSpareAreaTowrite
--;
1637 /* Increment the NAND address */
1638 nandAddress
= (uint32_t)(nandAddress
+ 1);
1641 /* Update the NAND controller state */
1642 hnand
->State
= HAL_NAND_STATE_READY
;
1644 /* Process unlocked */
1645 __HAL_UNLOCK(hnand
);
1651 * @brief NAND memory Block erase
1652 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1653 * the configuration information for NAND module.
1654 * @param pAddress pointer to NAND address structure
1655 * @retval HAL status
1657 HAL_StatusTypeDef
HAL_NAND_Erase_Block(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1659 uint32_t DeviceAddress
= 0;
1661 /* Process Locked */
1664 /* Check the NAND controller state */
1665 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1670 /* Identify the device address */
1671 DeviceAddress
= NAND_DEVICE
;
1673 /* Update the NAND controller state */
1674 hnand
->State
= HAL_NAND_STATE_BUSY
;
1676 /* Send Erase block command sequence */
1677 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_ERASE0
;
1679 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1681 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1683 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1686 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_ERASE1
;
1689 /* Update the NAND controller state */
1690 hnand
->State
= HAL_NAND_STATE_READY
;
1692 /* Process unlocked */
1693 __HAL_UNLOCK(hnand
);
1699 * @brief Increment the NAND memory address
1700 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1701 * the configuration information for NAND module.
1702 * @param pAddress pointer to NAND address structure
1703 * @retval The new status of the increment address operation. It can be:
1704 * - NAND_VALID_ADDRESS: When the new address is valid address
1705 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1707 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1709 uint32_t status
= NAND_VALID_ADDRESS
;
1711 /* Increment page address */
1714 /* Check NAND address is valid */
1715 if(pAddress
->Page
== hnand
->Config
.BlockSize
)
1720 if(pAddress
->Block
== hnand
->Config
.PlaneSize
)
1722 pAddress
->Block
= 0;
1725 if(pAddress
->Plane
== (hnand
->Config
.PlaneNbr
))
1727 status
= NAND_INVALID_ADDRESS
;
1735 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1737 * @brief Register a User NAND Callback
1738 * To be used instead of the weak (surcharged) predefined callback
1739 * @param hnand : NAND handle
1740 * @param CallbackId : ID of the callback to be registered
1741 * This parameter can be one of the following values:
1742 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1743 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1744 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1745 * @param pCallback : pointer to the Callback function
1748 HAL_StatusTypeDef
HAL_NAND_RegisterCallback (NAND_HandleTypeDef
*hnand
, HAL_NAND_CallbackIDTypeDef CallbackId
, pNAND_CallbackTypeDef pCallback
)
1750 HAL_StatusTypeDef status
= HAL_OK
;
1752 if(pCallback
== NULL
)
1757 /* Process locked */
1760 if(hnand
->State
== HAL_NAND_STATE_READY
)
1764 case HAL_NAND_MSP_INIT_CB_ID
:
1765 hnand
->MspInitCallback
= pCallback
;
1767 case HAL_NAND_MSP_DEINIT_CB_ID
:
1768 hnand
->MspDeInitCallback
= pCallback
;
1770 case HAL_NAND_IT_CB_ID
:
1771 hnand
->ItCallback
= pCallback
;
1774 /* update return status */
1779 else if(hnand
->State
== HAL_NAND_STATE_RESET
)
1783 case HAL_NAND_MSP_INIT_CB_ID
:
1784 hnand
->MspInitCallback
= pCallback
;
1786 case HAL_NAND_MSP_DEINIT_CB_ID
:
1787 hnand
->MspDeInitCallback
= pCallback
;
1790 /* update return status */
1797 /* update return status */
1802 __HAL_UNLOCK(hnand
);
1807 * @brief Unregister a User NAND Callback
1808 * NAND Callback is redirected to the weak (surcharged) predefined callback
1809 * @param hnand : NAND handle
1810 * @param CallbackId : ID of the callback to be unregistered
1811 * This parameter can be one of the following values:
1812 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1813 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1814 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1817 HAL_StatusTypeDef
HAL_NAND_UnRegisterCallback (NAND_HandleTypeDef
*hnand
, HAL_NAND_CallbackIDTypeDef CallbackId
)
1819 HAL_StatusTypeDef status
= HAL_OK
;
1821 /* Process locked */
1824 if(hnand
->State
== HAL_NAND_STATE_READY
)
1828 case HAL_NAND_MSP_INIT_CB_ID
:
1829 hnand
->MspInitCallback
= HAL_NAND_MspInit
;
1831 case HAL_NAND_MSP_DEINIT_CB_ID
:
1832 hnand
->MspDeInitCallback
= HAL_NAND_MspDeInit
;
1834 case HAL_NAND_IT_CB_ID
:
1835 hnand
->ItCallback
= HAL_NAND_ITCallback
;
1838 /* update return status */
1843 else if(hnand
->State
== HAL_NAND_STATE_RESET
)
1847 case HAL_NAND_MSP_INIT_CB_ID
:
1848 hnand
->MspInitCallback
= HAL_NAND_MspInit
;
1850 case HAL_NAND_MSP_DEINIT_CB_ID
:
1851 hnand
->MspDeInitCallback
= HAL_NAND_MspDeInit
;
1854 /* update return status */
1861 /* update return status */
1866 __HAL_UNLOCK(hnand
);
1875 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1876 * @brief management functions
1879 ==============================================================================
1880 ##### NAND Control functions #####
1881 ==============================================================================
1883 This subsection provides a set of functions allowing to control dynamically
1892 * @brief Enables dynamically NAND ECC feature.
1893 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1894 * the configuration information for NAND module.
1895 * @retval HAL status
1897 HAL_StatusTypeDef
HAL_NAND_ECC_Enable(NAND_HandleTypeDef
*hnand
)
1899 /* Check the NAND controller state */
1900 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1905 /* Update the NAND state */
1906 hnand
->State
= HAL_NAND_STATE_BUSY
;
1908 /* Enable ECC feature */
1909 FMC_NAND_ECC_Enable(hnand
->Instance
, hnand
->Init
.NandBank
);
1911 /* Update the NAND state */
1912 hnand
->State
= HAL_NAND_STATE_READY
;
1918 * @brief Disables dynamically FMC_NAND ECC feature.
1919 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1920 * the configuration information for NAND module.
1921 * @retval HAL status
1923 HAL_StatusTypeDef
HAL_NAND_ECC_Disable(NAND_HandleTypeDef
*hnand
)
1925 /* Check the NAND controller state */
1926 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1931 /* Update the NAND state */
1932 hnand
->State
= HAL_NAND_STATE_BUSY
;
1934 /* Disable ECC feature */
1935 FMC_NAND_ECC_Disable(hnand
->Instance
, hnand
->Init
.NandBank
);
1937 /* Update the NAND state */
1938 hnand
->State
= HAL_NAND_STATE_READY
;
1944 * @brief Disables dynamically NAND ECC feature.
1945 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1946 * the configuration information for NAND module.
1947 * @param ECCval pointer to ECC value
1948 * @param Timeout maximum timeout to wait
1949 * @retval HAL status
1951 HAL_StatusTypeDef
HAL_NAND_GetECC(NAND_HandleTypeDef
*hnand
, uint32_t *ECCval
, uint32_t Timeout
)
1953 HAL_StatusTypeDef status
= HAL_OK
;
1955 /* Check the NAND controller state */
1956 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1961 /* Update the NAND state */
1962 hnand
->State
= HAL_NAND_STATE_BUSY
;
1964 /* Get NAND ECC value */
1965 status
= FMC_NAND_GetECC(hnand
->Instance
, ECCval
, hnand
->Init
.NandBank
, Timeout
);
1967 /* Update the NAND state */
1968 hnand
->State
= HAL_NAND_STATE_READY
;
1978 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1979 * @brief Peripheral State functions
1982 ==============================================================================
1983 ##### NAND State functions #####
1984 ==============================================================================
1986 This subsection permits to get in run-time the status of the NAND controller
1994 * @brief return the NAND state
1995 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1996 * the configuration information for NAND module.
1999 HAL_NAND_StateTypeDef
HAL_NAND_GetState(NAND_HandleTypeDef
*hnand
)
2001 return hnand
->State
;
2005 * @brief NAND memory read status
2006 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2007 * the configuration information for NAND module.
2008 * @retval NAND status
2010 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef
*hnand
)
2013 uint32_t DeviceAddress
= 0;
2015 /* Identify the device address */
2016 DeviceAddress
= NAND_DEVICE
;
2018 /* Send Read status operation command */
2019 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_STATUS
;
2021 /* Read status register data */
2022 data
= *(__IO
uint8_t *)DeviceAddress
;
2024 /* Return the status */
2025 if((data
& NAND_ERROR
) == NAND_ERROR
)
2029 else if((data
& NAND_READY
) == NAND_READY
)
2045 #endif /* HAL_NAND_MODULE_ENABLED */
2055 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/