Updated and Validated
[betaflight.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_nand.c
blob7ee025de399af8631345ab7d1485faf89239dfc1
1 /**
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
7 * as external device.
8 *
9 @verbatim
10 ==============================================================================
11 ##### How to use this driver #####
12 ==============================================================================
13 [..]
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
48 HAL_NAND_GetState()
50 [..]
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 =============================================
57 [..]
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.
94 @endverbatim
95 ******************************************************************************
96 * @attention
98 * <h2><center>&copy; 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
113 * @{
117 #ifdef HAL_NAND_MODULE_ENABLED
119 /** @defgroup NAND NAND
120 * @brief NAND HAL module driver
121 * @{
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
132 * @{
135 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
136 * @brief Initialization and Configuration functions
138 @verbatim
139 ==============================================================================
140 ##### NAND Initialization and de-initialization functions #####
141 ==============================================================================
142 [..]
143 This section provides functions allowing to initialize/de-initialize
144 the NAND memory
146 @endverbatim
147 * @{
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
156 * @retval HAL status
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 */
161 if(hnand == NULL)
163 return HAL_ERROR;
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);
180 #else
181 /* Initialize the low level hardware (MSP) */
182 HAL_NAND_MspInit(hnand);
183 #endif
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;
201 return HAL_OK;
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.
208 * @retval HAL status
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);
220 #else
221 /* Initialize the low level hardware (MSP) */
222 HAL_NAND_MspDeInit(hnand);
223 #endif
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;
231 /* Release Lock */
232 __HAL_UNLOCK(hnand);
234 return HAL_OK;
238 * @brief NAND MSP Init
239 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
240 * the configuration information for NAND module.
241 * @retval None
243 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
245 /* Prevent unused argument(s) compilation warning */
246 UNUSED(hnand);
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.
257 * @retval None
259 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
261 /* Prevent unused argument(s) compilation warning */
262 UNUSED(hnand);
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.
274 * @retval HAL status
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);
284 #else
285 HAL_NAND_ITCallback(hnand);
286 #endif
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);
298 #else
299 HAL_NAND_ITCallback(hnand);
300 #endif
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);
312 #else
313 HAL_NAND_ITCallback(hnand);
314 #endif
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);
326 #else
327 HAL_NAND_ITCallback(hnand);
328 #endif
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.
340 * @retval None
342 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
344 /* Prevent unused argument(s) compilation warning */
345 UNUSED(hnand);
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
353 * @}
356 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
357 * @brief Input Output and memory control functions
359 @verbatim
360 ==============================================================================
361 ##### NAND Input and Output functions #####
362 ==============================================================================
363 [..]
364 This section provides functions allowing to use and control the NAND
365 memory
367 @endverbatim
368 * @{
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
376 * @retval HAL status
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;
384 /* Process Locked */
385 __HAL_LOCK(hnand);
387 /* Check the NAND controller state */
388 if(hnand->State == HAL_NAND_STATE_BUSY)
390 return HAL_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;
401 __DSB();
402 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
403 __DSB();
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);
416 else
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 */
432 __HAL_UNLOCK(hnand);
434 return HAL_OK;
438 * @brief NAND memory reset
439 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
440 * the configuration information for NAND module.
441 * @retval HAL status
443 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
445 uint32_t deviceAddress = 0;
447 /* Process Locked */
448 __HAL_LOCK(hnand);
450 /* Check the NAND controller state */
451 if(hnand->State == HAL_NAND_STATE_BUSY)
453 return HAL_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 */
469 __HAL_UNLOCK(hnand);
471 return HAL_OK;
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
480 * @retval HAL status
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;
492 return HAL_OK;
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
503 * @retval HAL status
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;
511 /* Process Locked */
512 __HAL_LOCK(hnand);
514 /* Check the NAND controller state */
515 if(hnand->State == HAL_NAND_STATE_BUSY)
517 return HAL_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;
537 __DSB();
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;
545 __DSB();
546 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
547 __DSB();
548 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
549 __DSB();
551 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
553 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
554 __DSB();
555 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
556 __DSB();
557 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
558 __DSB();
559 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
560 __DSB();
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;
568 __DSB();
569 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
570 __DSB();
571 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
572 __DSB();
573 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
574 __DSB();
576 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
578 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
579 __DSB();
580 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
581 __DSB();
582 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
583 __DSB();
584 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
585 __DSB();
586 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
587 __DSB();
591 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
592 __DSB();
595 if(hnand->Config.ExtraCommandEnable == ENABLE)
597 /* Get tick */
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)
605 return HAL_TIMEOUT;
609 /* Go back to read mode */
610 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
611 __DSB();
614 /* Get Data into Buffer */
615 for(; index < size; index++)
617 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
620 /* Increment read pages number */
621 numPagesRead++;
623 /* Decrement pages to read */
624 NumPageToRead--;
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 */
634 __HAL_UNLOCK(hnand);
636 return HAL_OK;
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
647 * @retval HAL status
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;
655 /* Process Locked */
656 __HAL_LOCK(hnand);
658 /* Check the NAND controller state */
659 if(hnand->State == HAL_NAND_STATE_BUSY)
661 return HAL_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;
681 __DSB();
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;
689 __DSB();
690 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
691 __DSB();
692 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
693 __DSB();
695 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
697 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
698 __DSB();
699 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
700 __DSB();
701 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
702 __DSB();
703 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
704 __DSB();
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;
712 __DSB();
713 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
714 __DSB();
715 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
716 __DSB();
717 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
718 __DSB();
720 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
722 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
723 __DSB();
724 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
725 __DSB();
726 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
727 __DSB();
728 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
729 __DSB();
730 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
731 __DSB();
735 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
736 __DSB();
738 if(hnand->Config.ExtraCommandEnable == ENABLE)
740 /* Get tick */
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)
748 return HAL_TIMEOUT;
752 /* Go back to read mode */
753 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
754 __DSB();
757 /* Get Data into Buffer */
758 for(; index < size; index++)
760 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
763 /* Increment read pages number */
764 numPagesRead++;
766 /* Decrement pages to read */
767 NumPageToRead--;
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 */
777 __HAL_UNLOCK(hnand);
779 return HAL_OK;
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
789 * @retval HAL status
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;
797 /* Process Locked */
798 __HAL_LOCK(hnand);
800 /* Check the NAND controller state */
801 if(hnand->State == HAL_NAND_STATE_BUSY)
803 return HAL_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;
823 __DSB();
824 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
825 __DSB();
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;
833 __DSB();
834 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
835 __DSB();
836 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
837 __DSB();
839 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
841 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
842 __DSB();
843 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
844 __DSB();
845 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
846 __DSB();
847 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
848 __DSB();
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;
856 __DSB();
857 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
858 __DSB();
859 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
860 __DSB();
861 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
862 __DSB();
864 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
866 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
867 __DSB();
868 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
869 __DSB();
870 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
871 __DSB();
872 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
873 __DSB();
874 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
875 __DSB();
879 /* Write data to memory */
880 for(; index < size; index++)
882 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
883 __DSB();
886 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
887 __DSB();
889 /* Get tick */
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)
897 return HAL_TIMEOUT;
901 /* Increment written pages number */
902 numPagesWritten++;
904 /* Decrement pages to write */
905 NumPageToWrite--;
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 */
915 __HAL_UNLOCK(hnand);
917 return HAL_OK;
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
927 * @retval HAL status
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;
935 /* Process Locked */
936 __HAL_LOCK(hnand);
938 /* Check the NAND controller state */
939 if(hnand->State == HAL_NAND_STATE_BUSY)
941 return HAL_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;
961 __DSB();
962 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
963 __DSB();
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;
971 __DSB();
972 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
973 __DSB();
974 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
975 __DSB();
977 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
979 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
980 __DSB();
981 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
982 __DSB();
983 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
984 __DSB();
985 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
986 __DSB();
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;
994 __DSB();
995 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
996 __DSB();
997 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
998 __DSB();
999 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1000 __DSB();
1002 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1004 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1005 __DSB();
1006 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1007 __DSB();
1008 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1009 __DSB();
1010 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1011 __DSB();
1012 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1013 __DSB();
1017 /* Write data to memory */
1018 for(; index < size; index++)
1020 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
1021 __DSB();
1024 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1025 __DSB();
1027 /* Get tick */
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)
1035 return HAL_TIMEOUT;
1039 /* Increment written pages number */
1040 numPagesWritten++;
1042 /* Decrement pages to write */
1043 NumPageToWrite--;
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);
1055 return HAL_OK;
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 */
1074 __HAL_LOCK(hnand);
1076 /* Check the NAND controller state */
1077 if(hnand->State == HAL_NAND_STATE_BUSY)
1079 return HAL_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;
1105 __DSB();
1107 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1109 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1110 __DSB();
1111 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1112 __DSB();
1113 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1114 __DSB();
1116 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1118 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1119 __DSB();
1120 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1121 __DSB();
1122 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1123 __DSB();
1124 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1125 __DSB();
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;
1132 __DSB();
1134 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1136 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1137 __DSB();
1138 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1139 __DSB();
1140 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1141 __DSB();
1142 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1143 __DSB();
1145 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1147 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1148 __DSB();
1149 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1150 __DSB();
1151 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1152 __DSB();
1153 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1154 __DSB();
1155 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1156 __DSB();
1160 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1161 __DSB();
1163 if(hnand->Config.ExtraCommandEnable == ENABLE)
1165 /* Get tick */
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)
1173 return HAL_TIMEOUT;
1177 /* Go back to read mode */
1178 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1179 __DSB();
1182 /* Get Data into Buffer */
1183 for(; index < size; index++)
1185 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
1188 /* Increment read spare areas number */
1189 numSpareAreaRead++;
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);
1204 return HAL_OK;
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 */
1223 __HAL_LOCK(hnand);
1225 /* Check the NAND controller state */
1226 if(hnand->State == HAL_NAND_STATE_BUSY)
1228 return HAL_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;
1254 __DSB();
1256 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1258 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1259 __DSB();
1260 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1261 __DSB();
1262 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1263 __DSB();
1265 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1267 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1268 __DSB();
1269 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1270 __DSB();
1271 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1272 __DSB();
1273 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1274 __DSB();
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;
1281 __DSB();
1283 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1285 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1286 __DSB();
1287 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1288 __DSB();
1289 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1290 __DSB();
1291 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1292 __DSB();
1294 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1296 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1297 __DSB();
1298 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1299 __DSB();
1300 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1301 __DSB();
1302 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1303 __DSB();
1304 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1305 __DSB();
1309 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1310 __DSB();
1312 if(hnand->Config.ExtraCommandEnable == ENABLE)
1314 /* Get tick */
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)
1322 return HAL_TIMEOUT;
1326 /* Go back to read mode */
1327 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1328 __DSB();
1331 /* Get Data into Buffer */
1332 for(; index < size; index++)
1334 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
1337 /* Increment read spare areas number */
1338 numSpareAreaRead++;
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);
1353 return HAL_OK;
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 */
1372 __HAL_LOCK(hnand);
1374 /* Check the NAND controller state */
1375 if(hnand->State == HAL_NAND_STATE_BUSY)
1377 return HAL_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;
1403 __DSB();
1404 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1405 __DSB();
1407 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1409 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1410 __DSB();
1411 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1412 __DSB();
1413 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1414 __DSB();
1416 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1418 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1419 __DSB();
1420 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1421 __DSB();
1422 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1423 __DSB();
1424 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1425 __DSB();
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;
1432 __DSB();
1433 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1434 __DSB();
1436 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1438 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1439 __DSB();
1440 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1441 __DSB();
1442 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1443 __DSB();
1444 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1445 __DSB();
1447 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1449 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1450 __DSB();
1451 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1452 __DSB();
1453 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1454 __DSB();
1455 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1456 __DSB();
1457 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1458 __DSB();
1462 /* Write data to memory */
1463 for(; index < size; index++)
1465 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
1466 __DSB();
1469 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1470 __DSB();
1472 /* Get tick */
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)
1480 return HAL_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);
1500 return HAL_OK;
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 */
1519 __HAL_LOCK(hnand);
1521 /* Check the NAND controller state */
1522 if(hnand->State == HAL_NAND_STATE_BUSY)
1524 return HAL_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;
1550 __DSB();
1551 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1552 __DSB();
1554 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1556 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1557 __DSB();
1558 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1559 __DSB();
1560 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1561 __DSB();
1563 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1565 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1566 __DSB();
1567 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1568 __DSB();
1569 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1570 __DSB();
1571 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1572 __DSB();
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;
1579 __DSB();
1580 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1581 __DSB();
1583 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1585 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1586 __DSB();
1587 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1588 __DSB();
1589 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1590 __DSB();
1591 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1592 __DSB();
1594 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1596 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1597 __DSB();
1598 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1599 __DSB();
1600 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1601 __DSB();
1602 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1603 __DSB();
1604 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1605 __DSB();
1609 /* Write data to memory */
1610 for(; index < size; index++)
1612 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
1613 __DSB();
1616 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1617 __DSB();
1619 /* Get tick */
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)
1627 return HAL_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);
1647 return HAL_OK;
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 */
1662 __HAL_LOCK(hnand);
1664 /* Check the NAND controller state */
1665 if(hnand->State == HAL_NAND_STATE_BUSY)
1667 return HAL_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;
1678 __DSB();
1679 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1680 __DSB();
1681 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1682 __DSB();
1683 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1684 __DSB();
1686 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1687 __DSB();
1689 /* Update the NAND controller state */
1690 hnand->State = HAL_NAND_STATE_READY;
1692 /* Process unlocked */
1693 __HAL_UNLOCK(hnand);
1695 return HAL_OK;
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 */
1712 pAddress->Page++;
1714 /* Check NAND address is valid */
1715 if(pAddress->Page == hnand->Config.BlockSize)
1717 pAddress->Page = 0;
1718 pAddress->Block++;
1720 if(pAddress->Block == hnand->Config.PlaneSize)
1722 pAddress->Block = 0;
1723 pAddress->Plane++;
1725 if(pAddress->Plane == (hnand->Config.PlaneNbr))
1727 status = NAND_INVALID_ADDRESS;
1732 return (status);
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
1746 * @retval status
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)
1754 return HAL_ERROR;
1757 /* Process locked */
1758 __HAL_LOCK(hnand);
1760 if(hnand->State == HAL_NAND_STATE_READY)
1762 switch (CallbackId)
1764 case HAL_NAND_MSP_INIT_CB_ID :
1765 hnand->MspInitCallback = pCallback;
1766 break;
1767 case HAL_NAND_MSP_DEINIT_CB_ID :
1768 hnand->MspDeInitCallback = pCallback;
1769 break;
1770 case HAL_NAND_IT_CB_ID :
1771 hnand->ItCallback = pCallback;
1772 break;
1773 default :
1774 /* update return status */
1775 status = HAL_ERROR;
1776 break;
1779 else if(hnand->State == HAL_NAND_STATE_RESET)
1781 switch (CallbackId)
1783 case HAL_NAND_MSP_INIT_CB_ID :
1784 hnand->MspInitCallback = pCallback;
1785 break;
1786 case HAL_NAND_MSP_DEINIT_CB_ID :
1787 hnand->MspDeInitCallback = pCallback;
1788 break;
1789 default :
1790 /* update return status */
1791 status = HAL_ERROR;
1792 break;
1795 else
1797 /* update return status */
1798 status = HAL_ERROR;
1801 /* Release Lock */
1802 __HAL_UNLOCK(hnand);
1803 return status;
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
1815 * @retval status
1817 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1819 HAL_StatusTypeDef status = HAL_OK;
1821 /* Process locked */
1822 __HAL_LOCK(hnand);
1824 if(hnand->State == HAL_NAND_STATE_READY)
1826 switch (CallbackId)
1828 case HAL_NAND_MSP_INIT_CB_ID :
1829 hnand->MspInitCallback = HAL_NAND_MspInit;
1830 break;
1831 case HAL_NAND_MSP_DEINIT_CB_ID :
1832 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1833 break;
1834 case HAL_NAND_IT_CB_ID :
1835 hnand->ItCallback = HAL_NAND_ITCallback;
1836 break;
1837 default :
1838 /* update return status */
1839 status = HAL_ERROR;
1840 break;
1843 else if(hnand->State == HAL_NAND_STATE_RESET)
1845 switch (CallbackId)
1847 case HAL_NAND_MSP_INIT_CB_ID :
1848 hnand->MspInitCallback = HAL_NAND_MspInit;
1849 break;
1850 case HAL_NAND_MSP_DEINIT_CB_ID :
1851 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1852 break;
1853 default :
1854 /* update return status */
1855 status = HAL_ERROR;
1856 break;
1859 else
1861 /* update return status */
1862 status = HAL_ERROR;
1865 /* Release Lock */
1866 __HAL_UNLOCK(hnand);
1867 return status;
1869 #endif
1872 * @}
1875 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1876 * @brief management functions
1878 @verbatim
1879 ==============================================================================
1880 ##### NAND Control functions #####
1881 ==============================================================================
1882 [..]
1883 This subsection provides a set of functions allowing to control dynamically
1884 the NAND interface.
1886 @endverbatim
1887 * @{
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)
1902 return HAL_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;
1914 return HAL_OK;
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)
1928 return HAL_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;
1940 return HAL_OK;
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)
1958 return HAL_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;
1970 return status;
1974 * @}
1978 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1979 * @brief Peripheral State functions
1981 @verbatim
1982 ==============================================================================
1983 ##### NAND State functions #####
1984 ==============================================================================
1985 [..]
1986 This subsection permits to get in run-time the status of the NAND controller
1987 and the data flow.
1989 @endverbatim
1990 * @{
1994 * @brief return the NAND state
1995 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1996 * the configuration information for NAND module.
1997 * @retval HAL state
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)
2012 uint32_t data = 0;
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)
2027 return NAND_ERROR;
2029 else if((data & NAND_READY) == NAND_READY)
2031 return NAND_READY;
2034 return NAND_BUSY;
2038 * @}
2042 * @}
2045 #endif /* HAL_NAND_MODULE_ENABLED */
2048 * @}
2052 * @}
2055 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/