Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_nand.c
blob955556bc09432948c2909b28aa67492c44367ada
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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.
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 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 "stm32h7xx_hal.h"
113 /** @addtogroup STM32H7xx_HAL_Driver
114 * @{
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 (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
189 /* Initialize NAND common space timing Interface */
190 (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
192 /* Initialize NAND attribute space timing Interface */
193 (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
195 /* Enable the NAND device */
196 __FMC_NAND_ENABLE(hnand->Instance);
198 /* Enable FMC Peripheral */
199 __FMC_ENABLE();
200 /* Update the NAND controller state */
201 hnand->State = HAL_NAND_STATE_READY;
203 return HAL_OK;
207 * @brief Perform NAND memory De-Initialization sequence
208 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
209 * the configuration information for NAND module.
210 * @retval HAL status
212 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
214 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
215 if(hnand->MspDeInitCallback == NULL)
217 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
220 /* DeInit the low level hardware */
221 hnand->MspDeInitCallback(hnand);
222 #else
223 /* Initialize the low level hardware (MSP) */
224 HAL_NAND_MspDeInit(hnand);
225 #endif
227 /* Configure the NAND registers with their reset values */
228 (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
230 /* Reset the NAND controller state */
231 hnand->State = HAL_NAND_STATE_RESET;
233 /* Release Lock */
234 __HAL_UNLOCK(hnand);
236 return HAL_OK;
240 * @brief NAND MSP Init
241 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
242 * the configuration information for NAND module.
243 * @retval None
245 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
247 /* Prevent unused argument(s) compilation warning */
248 UNUSED(hnand);
250 /* NOTE : This function Should not be modified, when the callback is needed,
251 the HAL_NAND_MspInit could be implemented in the user file
256 * @brief NAND MSP DeInit
257 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
258 * the configuration information for NAND module.
259 * @retval None
261 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
263 /* Prevent unused argument(s) compilation warning */
264 UNUSED(hnand);
266 /* NOTE : This function Should not be modified, when the callback is needed,
267 the HAL_NAND_MspDeInit could be implemented in the user file
273 * @brief This function handles NAND device interrupt request.
274 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
275 * the configuration information for NAND module.
276 * @retval HAL status
278 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
280 /* Check NAND interrupt Rising edge flag */
281 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
283 /* NAND interrupt callback*/
284 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
285 hnand->ItCallback(hnand);
286 #else
287 HAL_NAND_ITCallback(hnand);
288 #endif
290 /* Clear NAND interrupt Rising edge pending bit */
291 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
294 /* Check NAND interrupt Level flag */
295 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
297 /* NAND interrupt callback*/
298 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
299 hnand->ItCallback(hnand);
300 #else
301 HAL_NAND_ITCallback(hnand);
302 #endif
304 /* Clear NAND interrupt Level pending bit */
305 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
308 /* Check NAND interrupt Falling edge flag */
309 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
311 /* NAND interrupt callback*/
312 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
313 hnand->ItCallback(hnand);
314 #else
315 HAL_NAND_ITCallback(hnand);
316 #endif
318 /* Clear NAND interrupt Falling edge pending bit */
319 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
322 /* Check NAND interrupt FIFO empty flag */
323 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
325 /* NAND interrupt callback*/
326 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
327 hnand->ItCallback(hnand);
328 #else
329 HAL_NAND_ITCallback(hnand);
330 #endif
332 /* Clear NAND interrupt FIFO empty pending bit */
333 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
339 * @brief NAND interrupt feature callback
340 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
341 * the configuration information for NAND module.
342 * @retval None
344 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
346 /* Prevent unused argument(s) compilation warning */
347 UNUSED(hnand);
349 /* NOTE : This function Should not be modified, when the callback is needed,
350 the HAL_NAND_ITCallback could be implemented in the user file
355 * @}
358 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
359 * @brief Input Output and memory control functions
361 @verbatim
362 ==============================================================================
363 ##### NAND Input and Output functions #####
364 ==============================================================================
365 [..]
366 This section provides functions allowing to use and control the NAND
367 memory
369 @endverbatim
370 * @{
374 * @brief Read the NAND memory electronic signature
375 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
376 * the configuration information for NAND module.
377 * @param pNAND_ID NAND ID structure
378 * @retval HAL status
380 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
382 __IO uint32_t data = 0;
383 __IO uint32_t data1 = 0;
384 uint32_t deviceAddress;
386 /* Check the NAND controller state */
387 if (hnand->State == HAL_NAND_STATE_BUSY)
389 return HAL_BUSY;
391 else if (hnand->State == HAL_NAND_STATE_READY)
393 /* Process Locked */
394 __HAL_LOCK(hnand);
396 /* Update the NAND controller state */
397 hnand->State = HAL_NAND_STATE_BUSY;
399 /* Identify the device address */
400 deviceAddress = NAND_DEVICE;
402 /* Send Read ID command sequence */
403 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
404 __DSB();
405 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
406 __DSB();
408 /* Read the electronic signature from NAND flash */
409 if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
411 data = *(__IO uint32_t *)deviceAddress;
413 /* Return the data read */
414 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
415 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
416 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
417 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
419 else
421 data = *(__IO uint32_t *)deviceAddress;
422 data1 = *((__IO uint32_t *)deviceAddress + 4);
424 /* Return the data read */
425 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
426 pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
427 pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
428 pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
431 /* Update the NAND controller state */
432 hnand->State = HAL_NAND_STATE_READY;
434 /* Process unlocked */
435 __HAL_UNLOCK(hnand);
437 else
439 return HAL_ERROR;
442 return HAL_OK;
446 * @brief NAND memory reset
447 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
448 * the configuration information for NAND module.
449 * @retval HAL status
451 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
453 uint32_t deviceAddress;
455 /* Check the NAND controller state */
456 if (hnand->State == HAL_NAND_STATE_BUSY)
458 return HAL_BUSY;
460 else if (hnand->State == HAL_NAND_STATE_READY)
462 /* Process Locked */
463 __HAL_LOCK(hnand);
465 /* Update the NAND controller state */
466 hnand->State = HAL_NAND_STATE_BUSY;
468 /* Identify the device address */
469 deviceAddress = NAND_DEVICE;
471 /* Send NAND reset command */
472 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
474 /* Update the NAND controller state */
475 hnand->State = HAL_NAND_STATE_READY;
477 /* Process unlocked */
478 __HAL_UNLOCK(hnand);
480 else
482 return HAL_ERROR;
485 return HAL_OK;
490 * @brief Configure the device: Enter the physical parameters of the device
491 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
492 * the configuration information for NAND module.
493 * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure
494 * @retval HAL status
496 HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
498 hnand->Config.PageSize = pDeviceConfig->PageSize;
499 hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
500 hnand->Config.BlockSize = pDeviceConfig->BlockSize;
501 hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
502 hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
503 hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
504 hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
506 return HAL_OK;
510 * @brief Read Page(s) from NAND memory block (8-bits addressing)
511 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
512 * the configuration information for NAND module.
513 * @param pAddress pointer to NAND address structure
514 * @param pBuffer pointer to destination read buffer
515 * @param NumPageToRead number of pages to read from block
516 * @retval HAL status
518 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
520 uint32_t index;
521 uint32_t tickstart;
522 uint32_t deviceAddress, numPagesRead = 0U, nandAddress, nbpages = NumPageToRead;
523 uint8_t * buff = pBuffer;
525 /* Check the NAND controller state */
526 if (hnand->State == HAL_NAND_STATE_BUSY)
528 return HAL_BUSY;
530 else if (hnand->State == HAL_NAND_STATE_READY)
532 /* Process Locked */
533 __HAL_LOCK(hnand);
535 /* Update the NAND controller state */
536 hnand->State = HAL_NAND_STATE_BUSY;
538 /* Identify the device address */
539 deviceAddress = NAND_DEVICE;
541 /* NAND raw address calculation */
542 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
544 /* Page(s) read loop */
545 while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
547 /* Send read page command sequence */
548 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
549 __DSB();
551 /* Cards with page size <= 512 bytes */
552 if ((hnand->Config.PageSize) <= 512U)
554 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
556 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
557 __DSB();
558 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
559 __DSB();
560 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
561 __DSB();
563 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
565 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
566 __DSB();
567 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
568 __DSB();
569 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
570 __DSB();
571 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
572 __DSB();
575 else /* (hnand->Config.PageSize) > 512 */
577 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
579 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
580 __DSB();
581 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
582 __DSB();
583 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
584 __DSB();
585 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
586 __DSB();
588 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
590 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
591 __DSB();
592 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
593 __DSB();
594 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
595 __DSB();
596 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
597 __DSB();
598 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
599 __DSB();
603 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
604 __DSB();
607 if (hnand->Config.ExtraCommandEnable == ENABLE)
609 /* Get tick */
610 tickstart = HAL_GetTick();
612 /* Read status until NAND is ready */
613 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
615 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
617 /* Update the NAND controller state */
618 hnand->State = HAL_NAND_STATE_ERROR;
620 /* Process unlocked */
621 __HAL_UNLOCK(hnand);
623 return HAL_TIMEOUT;
627 /* Go back to read mode */
628 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
629 __DSB();
632 /* Get Data into Buffer */
633 for (index = 0U; index < hnand->Config.PageSize; index++)
635 *buff = *(uint8_t *)deviceAddress;
636 buff++;
639 /* Increment read pages number */
640 numPagesRead++;
642 /* Decrement pages to read */
643 nbpages--;
645 /* Increment the NAND address */
646 nandAddress = (uint32_t)(nandAddress + 1U);
649 /* Update the NAND controller state */
650 hnand->State = HAL_NAND_STATE_READY;
652 /* Process unlocked */
653 __HAL_UNLOCK(hnand);
655 else
657 return HAL_ERROR;
660 return HAL_OK;
664 * @brief Read Page(s) from NAND memory block (16-bits addressing)
665 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
666 * the configuration information for NAND module.
667 * @param pAddress pointer to NAND address structure
668 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned
669 * @param NumPageToRead number of pages to read from block
670 * @retval HAL status
672 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
674 uint32_t index;
675 uint32_t tickstart;
676 uint32_t deviceAddress, numPagesRead = 0, nandAddress, nbpages = NumPageToRead;
677 uint16_t * buff = pBuffer;
679 /* Check the NAND controller state */
680 if (hnand->State == HAL_NAND_STATE_BUSY)
682 return HAL_BUSY;
684 else if (hnand->State == HAL_NAND_STATE_READY)
686 /* Process Locked */
687 __HAL_LOCK(hnand);
689 /* Update the NAND controller state */
690 hnand->State = HAL_NAND_STATE_BUSY;
692 /* Identify the device address */
693 deviceAddress = NAND_DEVICE;
695 /* NAND raw address calculation */
696 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
698 /* Page(s) read loop */
699 while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
701 /* Send read page command sequence */
702 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
703 __DSB();
705 /* Cards with page size <= 512 bytes */
706 if ((hnand->Config.PageSize) <= 512U)
708 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
710 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
711 __DSB();
712 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
713 __DSB();
714 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
715 __DSB();
717 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
719 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
720 __DSB();
721 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
722 __DSB();
723 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
724 __DSB();
725 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
726 __DSB();
729 else /* (hnand->Config.PageSize) > 512 */
731 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
733 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
734 __DSB();
735 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
736 __DSB();
737 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
738 __DSB();
739 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
740 __DSB();
742 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
744 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
745 __DSB();
746 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
747 __DSB();
748 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
749 __DSB();
750 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
751 __DSB();
752 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
753 __DSB();
757 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
758 __DSB();
760 if (hnand->Config.ExtraCommandEnable == ENABLE)
762 /* Get tick */
763 tickstart = HAL_GetTick();
765 /* Read status until NAND is ready */
766 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
768 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
770 /* Update the NAND controller state */
771 hnand->State = HAL_NAND_STATE_ERROR;
773 /* Process unlocked */
774 __HAL_UNLOCK(hnand);
776 return HAL_TIMEOUT;
780 /* Go back to read mode */
781 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
782 __DSB();
785 /* Get Data into Buffer */
786 for (index = 0U; index < hnand->Config.PageSize; index++)
788 *buff = *(uint16_t *)deviceAddress;
789 buff++;
792 /* Increment read pages number */
793 numPagesRead++;
795 /* Decrement pages to read */
796 nbpages--;
798 /* Increment the NAND address */
799 nandAddress = (uint32_t)(nandAddress + 1U);
802 /* Update the NAND controller state */
803 hnand->State = HAL_NAND_STATE_READY;
805 /* Process unlocked */
806 __HAL_UNLOCK(hnand);
808 else
810 return HAL_ERROR;
813 return HAL_OK;
817 * @brief Write Page(s) to NAND memory block (8-bits addressing)
818 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
819 * the configuration information for NAND module.
820 * @param pAddress pointer to NAND address structure
821 * @param pBuffer pointer to source buffer to write
822 * @param NumPageToWrite number of pages to write to block
823 * @retval HAL status
825 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
827 uint32_t index;
828 uint32_t tickstart;
829 uint32_t deviceAddress, numPagesWritten = 0, nandAddress, nbpages = NumPageToWrite;
830 uint8_t * buff = pBuffer;
832 /* Check the NAND controller state */
833 if (hnand->State == HAL_NAND_STATE_BUSY)
835 return HAL_BUSY;
837 else if (hnand->State == HAL_NAND_STATE_READY)
839 /* Process Locked */
840 __HAL_LOCK(hnand);
842 /* Update the NAND controller state */
843 hnand->State = HAL_NAND_STATE_BUSY;
845 /* Identify the device address */
846 deviceAddress = NAND_DEVICE;
848 /* NAND raw address calculation */
849 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
851 /* Page(s) write loop */
852 while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
854 /* Send write page command sequence */
855 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
856 __DSB();
857 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
858 __DSB();
860 /* Cards with page size <= 512 bytes */
861 if ((hnand->Config.PageSize) <= 512U)
863 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
865 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
866 __DSB();
867 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
868 __DSB();
869 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
870 __DSB();
872 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
874 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
875 __DSB();
876 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
877 __DSB();
878 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
879 __DSB();
880 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
881 __DSB();
884 else /* (hnand->Config.PageSize) > 512 */
886 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
888 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
889 __DSB();
890 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
891 __DSB();
892 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
893 __DSB();
894 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
895 __DSB();
897 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
899 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
900 __DSB();
901 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
902 __DSB();
903 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
904 __DSB();
905 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
906 __DSB();
907 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
908 __DSB();
912 /* Write data to memory */
913 for (index = 0U; index < hnand->Config.PageSize; index++)
915 *(__IO uint8_t *)deviceAddress = *buff;
916 buff++;
917 __DSB();
920 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
921 __DSB();
923 /* Get tick */
924 tickstart = HAL_GetTick();
926 /* Read status until NAND is ready */
927 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
929 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
931 /* Update the NAND controller state */
932 hnand->State = HAL_NAND_STATE_ERROR;
934 /* Process unlocked */
935 __HAL_UNLOCK(hnand);
937 return HAL_TIMEOUT;
941 /* Increment written pages number */
942 numPagesWritten++;
944 /* Decrement pages to write */
945 nbpages--;
947 /* Increment the NAND address */
948 nandAddress = (uint32_t)(nandAddress + 1U);
951 /* Update the NAND controller state */
952 hnand->State = HAL_NAND_STATE_READY;
954 /* Process unlocked */
955 __HAL_UNLOCK(hnand);
957 else
959 return HAL_ERROR;
962 return HAL_OK;
966 * @brief Write Page(s) to NAND memory block (16-bits addressing)
967 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
968 * the configuration information for NAND module.
969 * @param pAddress pointer to NAND address structure
970 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
971 * @param NumPageToWrite number of pages to write to block
972 * @retval HAL status
974 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
976 uint32_t index;
977 uint32_t tickstart;
978 uint32_t deviceAddress, numPagesWritten = 0, nandAddress, nbpages = NumPageToWrite;
979 uint16_t * buff = pBuffer;
981 /* Check the NAND controller state */
982 if (hnand->State == HAL_NAND_STATE_BUSY)
984 return HAL_BUSY;
986 else if (hnand->State == HAL_NAND_STATE_READY)
988 /* Process Locked */
989 __HAL_LOCK(hnand);
991 /* Update the NAND controller state */
992 hnand->State = HAL_NAND_STATE_BUSY;
994 /* Identify the device address */
995 deviceAddress = NAND_DEVICE;
997 /* NAND raw address calculation */
998 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1000 /* Page(s) write loop */
1001 while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1003 /* Send write page command sequence */
1004 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1005 __DSB();
1006 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1007 __DSB();
1009 /* Cards with page size <= 512 bytes */
1010 if ((hnand->Config.PageSize) <= 512U)
1012 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1014 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1015 __DSB();
1016 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1017 __DSB();
1018 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1019 __DSB();
1021 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1023 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1024 __DSB();
1025 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1026 __DSB();
1027 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1028 __DSB();
1029 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1030 __DSB();
1033 else /* (hnand->Config.PageSize) > 512 */
1035 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1037 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1038 __DSB();
1039 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1040 __DSB();
1041 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1042 __DSB();
1043 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1044 __DSB();
1046 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1048 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1049 __DSB();
1050 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1051 __DSB();
1052 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1053 __DSB();
1054 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1055 __DSB();
1056 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1057 __DSB();
1061 /* Write data to memory */
1062 for (index = 0U; index < hnand->Config.PageSize; index++)
1064 *(__IO uint16_t *)deviceAddress = *buff;
1065 buff++;
1066 __DSB();
1069 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1070 __DSB();
1072 /* Get tick */
1073 tickstart = HAL_GetTick();
1075 /* Read status until NAND is ready */
1076 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1078 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1080 /* Update the NAND controller state */
1081 hnand->State = HAL_NAND_STATE_ERROR;
1083 /* Process unlocked */
1084 __HAL_UNLOCK(hnand);
1086 return HAL_TIMEOUT;
1090 /* Increment written pages number */
1091 numPagesWritten++;
1093 /* Decrement pages to write */
1094 nbpages--;
1096 /* Increment the NAND address */
1097 nandAddress = (uint32_t)(nandAddress + 1U);
1100 /* Update the NAND controller state */
1101 hnand->State = HAL_NAND_STATE_READY;
1103 /* Process unlocked */
1104 __HAL_UNLOCK(hnand);
1106 else
1108 return HAL_ERROR;
1111 return HAL_OK;
1115 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
1116 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1117 * the configuration information for NAND module.
1118 * @param pAddress pointer to NAND address structure
1119 * @param pBuffer pointer to source buffer to write
1120 * @param NumSpareAreaToRead Number of spare area to read
1121 * @retval HAL status
1123 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1125 uint32_t index;
1126 uint32_t tickstart;
1127 uint32_t deviceAddress, numSpareAreaRead = 0, nandAddress, columnAddress, nbspare = NumSpareAreaToRead;
1128 uint8_t * buff = pBuffer;
1130 /* Check the NAND controller state */
1131 if (hnand->State == HAL_NAND_STATE_BUSY)
1133 return HAL_BUSY;
1135 else if (hnand->State == HAL_NAND_STATE_READY)
1137 /* Process Locked */
1138 __HAL_LOCK(hnand);
1140 /* Update the NAND controller state */
1141 hnand->State = HAL_NAND_STATE_BUSY;
1143 /* Identify the device address */
1144 deviceAddress = NAND_DEVICE;
1146 /* NAND raw address calculation */
1147 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1149 /* Column in page address */
1150 columnAddress = COLUMN_ADDRESS(hnand);
1152 /* Spare area(s) read loop */
1153 while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1155 /* Cards with page size <= 512 bytes */
1156 if ((hnand->Config.PageSize) <= 512U)
1158 /* Send read spare area command sequence */
1159 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1160 __DSB();
1162 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1164 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1165 __DSB();
1166 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1167 __DSB();
1168 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1169 __DSB();
1171 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1173 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1174 __DSB();
1175 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1176 __DSB();
1177 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1178 __DSB();
1179 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1180 __DSB();
1183 else /* (hnand->Config.PageSize) > 512 */
1185 /* Send read spare area command sequence */
1186 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1187 __DSB();
1189 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1191 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1192 __DSB();
1193 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1194 __DSB();
1195 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1196 __DSB();
1197 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1198 __DSB();
1200 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1202 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1203 __DSB();
1204 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1205 __DSB();
1206 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1207 __DSB();
1208 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1209 __DSB();
1210 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1211 __DSB();
1215 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1216 __DSB();
1218 if (hnand->Config.ExtraCommandEnable == ENABLE)
1220 /* Get tick */
1221 tickstart = HAL_GetTick();
1223 /* Read status until NAND is ready */
1224 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1226 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1228 /* Update the NAND controller state */
1229 hnand->State = HAL_NAND_STATE_ERROR;
1231 /* Process unlocked */
1232 __HAL_UNLOCK(hnand);
1234 return HAL_TIMEOUT;
1238 /* Go back to read mode */
1239 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1240 __DSB();
1243 /* Get Data into Buffer */
1244 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1246 *buff = *(uint8_t *)deviceAddress;
1247 buff++;
1250 /* Increment read spare areas number */
1251 numSpareAreaRead++;
1253 /* Decrement spare areas to read */
1254 nbspare--;
1256 /* Increment the NAND address */
1257 nandAddress = (uint32_t)(nandAddress + 1U);
1260 /* Update the NAND controller state */
1261 hnand->State = HAL_NAND_STATE_READY;
1263 /* Process unlocked */
1264 __HAL_UNLOCK(hnand);
1266 else
1268 return HAL_ERROR;
1271 return HAL_OK;
1275 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1276 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1277 * the configuration information for NAND module.
1278 * @param pAddress pointer to NAND address structure
1279 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1280 * @param NumSpareAreaToRead Number of spare area to read
1281 * @retval HAL status
1283 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1285 uint32_t index;
1286 uint32_t tickstart;
1287 uint32_t deviceAddress, numSpareAreaRead = 0, nandAddress, columnAddress, nbspare = NumSpareAreaToRead;
1288 uint16_t * buff = pBuffer;
1290 /* Check the NAND controller state */
1291 if (hnand->State == HAL_NAND_STATE_BUSY)
1293 return HAL_BUSY;
1295 else if (hnand->State == HAL_NAND_STATE_READY)
1297 /* Process Locked */
1298 __HAL_LOCK(hnand);
1300 /* Update the NAND controller state */
1301 hnand->State = HAL_NAND_STATE_BUSY;
1303 /* Identify the device address */
1304 deviceAddress = NAND_DEVICE;
1306 /* NAND raw address calculation */
1307 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1309 /* Column in page address */
1310 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
1312 /* Spare area(s) read loop */
1313 while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1315 /* Cards with page size <= 512 bytes */
1316 if ((hnand->Config.PageSize) <= 512U)
1318 /* Send read spare area command sequence */
1319 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1320 __DSB();
1322 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1324 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1325 __DSB();
1326 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1327 __DSB();
1328 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1329 __DSB();
1331 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1333 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1334 __DSB();
1335 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1336 __DSB();
1337 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1338 __DSB();
1339 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1340 __DSB();
1343 else /* (hnand->Config.PageSize) > 512 */
1345 /* Send read spare area command sequence */
1346 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1347 __DSB();
1349 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1351 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1352 __DSB();
1353 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1354 __DSB();
1355 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1356 __DSB();
1357 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1358 __DSB();
1360 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1362 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1363 __DSB();
1364 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1365 __DSB();
1366 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1367 __DSB();
1368 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1369 __DSB();
1370 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1371 __DSB();
1375 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1376 __DSB();
1378 if (hnand->Config.ExtraCommandEnable == ENABLE)
1380 /* Get tick */
1381 tickstart = HAL_GetTick();
1383 /* Read status until NAND is ready */
1384 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1386 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1388 /* Update the NAND controller state */
1389 hnand->State = HAL_NAND_STATE_ERROR;
1391 /* Process unlocked */
1392 __HAL_UNLOCK(hnand);
1394 return HAL_TIMEOUT;
1398 /* Go back to read mode */
1399 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1400 __DSB();
1403 /* Get Data into Buffer */
1404 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1406 *buff = *(uint16_t *)deviceAddress;
1407 buff++;
1410 /* Increment read spare areas number */
1411 numSpareAreaRead++;
1413 /* Decrement spare areas to read */
1414 nbspare--;
1416 /* Increment the NAND address */
1417 nandAddress = (uint32_t)(nandAddress + 1U);
1420 /* Update the NAND controller state */
1421 hnand->State = HAL_NAND_STATE_READY;
1423 /* Process unlocked */
1424 __HAL_UNLOCK(hnand);
1426 else
1428 return HAL_ERROR;
1431 return HAL_OK;
1435 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1436 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1437 * the configuration information for NAND module.
1438 * @param pAddress pointer to NAND address structure
1439 * @param pBuffer pointer to source buffer to write
1440 * @param NumSpareAreaTowrite number of spare areas to write to block
1441 * @retval HAL status
1443 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1445 uint32_t index;
1446 uint32_t tickstart;
1447 uint32_t deviceAddress, numSpareAreaWritten = 0, nandAddress, columnAddress, nbspare = NumSpareAreaTowrite;
1448 uint8_t * buff = pBuffer;
1450 /* Check the NAND controller state */
1451 if (hnand->State == HAL_NAND_STATE_BUSY)
1453 return HAL_BUSY;
1455 else if (hnand->State == HAL_NAND_STATE_READY)
1457 /* Process Locked */
1458 __HAL_LOCK(hnand);
1460 /* Update the NAND controller state */
1461 hnand->State = HAL_NAND_STATE_BUSY;
1463 /* Identify the device address */
1464 deviceAddress = NAND_DEVICE;
1466 /* Page address calculation */
1467 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1469 /* Column in page address */
1470 columnAddress = COLUMN_ADDRESS(hnand);
1472 /* Spare area(s) write loop */
1473 while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1475 /* Cards with page size <= 512 bytes */
1476 if ((hnand->Config.PageSize) <= 512U)
1478 /* Send write Spare area command sequence */
1479 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1480 __DSB();
1481 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1482 __DSB();
1484 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1486 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1487 __DSB();
1488 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1489 __DSB();
1490 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1491 __DSB();
1493 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1495 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1496 __DSB();
1497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1498 __DSB();
1499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1500 __DSB();
1501 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1502 __DSB();
1505 else /* (hnand->Config.PageSize) > 512 */
1507 /* Send write Spare area command sequence */
1508 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1509 __DSB();
1510 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1511 __DSB();
1513 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1515 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1516 __DSB();
1517 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1518 __DSB();
1519 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1520 __DSB();
1521 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1522 __DSB();
1524 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1526 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1527 __DSB();
1528 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1529 __DSB();
1530 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1531 __DSB();
1532 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1533 __DSB();
1534 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1535 __DSB();
1539 /* Write data to memory */
1540 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1542 *(__IO uint8_t *)deviceAddress = *buff;
1543 buff++;
1544 __DSB();
1547 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1548 __DSB();
1550 /* Get tick */
1551 tickstart = HAL_GetTick();
1553 /* Read status until NAND is ready */
1554 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1556 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1558 /* Update the NAND controller state */
1559 hnand->State = HAL_NAND_STATE_ERROR;
1561 /* Process unlocked */
1562 __HAL_UNLOCK(hnand);
1564 return HAL_TIMEOUT;
1568 /* Increment written spare areas number */
1569 numSpareAreaWritten++;
1571 /* Decrement spare areas to write */
1572 nbspare--;
1574 /* Increment the NAND address */
1575 nandAddress = (uint32_t)(nandAddress + 1U);
1578 /* Update the NAND controller state */
1579 hnand->State = HAL_NAND_STATE_READY;
1581 /* Process unlocked */
1582 __HAL_UNLOCK(hnand);
1584 else
1586 return HAL_ERROR;
1589 return HAL_OK;
1593 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1594 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1595 * the configuration information for NAND module.
1596 * @param pAddress pointer to NAND address structure
1597 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1598 * @param NumSpareAreaTowrite number of spare areas to write to block
1599 * @retval HAL status
1601 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1603 uint32_t index;
1604 uint32_t tickstart;
1605 uint32_t deviceAddress, numSpareAreaWritten = 0, nandAddress, columnAddress, nbspare = NumSpareAreaTowrite;
1606 uint16_t * buff = pBuffer;
1608 /* Check the NAND controller state */
1609 if (hnand->State == HAL_NAND_STATE_BUSY)
1611 return HAL_BUSY;
1613 else if (hnand->State == HAL_NAND_STATE_READY)
1615 /* Process Locked */
1616 __HAL_LOCK(hnand);
1618 /* Update the NAND controller state */
1619 hnand->State = HAL_NAND_STATE_BUSY;
1621 /* Identify the device address */
1622 deviceAddress = NAND_DEVICE;
1624 /* NAND raw address calculation */
1625 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1627 /* Column in page address */
1628 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
1630 /* Spare area(s) write loop */
1631 while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1633 /* Cards with page size <= 512 bytes */
1634 if ((hnand->Config.PageSize) <= 512U)
1636 /* Send write Spare area command sequence */
1637 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1638 __DSB();
1639 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1640 __DSB();
1642 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1644 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1645 __DSB();
1646 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1647 __DSB();
1648 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1649 __DSB();
1651 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1653 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1654 __DSB();
1655 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1656 __DSB();
1657 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1658 __DSB();
1659 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1660 __DSB();
1663 else /* (hnand->Config.PageSize) > 512 */
1665 /* Send write Spare area command sequence */
1666 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1667 __DSB();
1668 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1669 __DSB();
1671 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1673 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1674 __DSB();
1675 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1676 __DSB();
1677 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1678 __DSB();
1679 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1680 __DSB();
1682 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1684 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1685 __DSB();
1686 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1687 __DSB();
1688 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1689 __DSB();
1690 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1691 __DSB();
1692 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1693 __DSB();
1697 /* Write data to memory */
1698 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1700 *(__IO uint16_t *)deviceAddress = *buff;
1701 buff++;
1702 __DSB();
1705 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1706 __DSB();
1708 /* Get tick */
1709 tickstart = HAL_GetTick();
1711 /* Read status until NAND is ready */
1712 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1714 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1716 /* Update the NAND controller state */
1717 hnand->State = HAL_NAND_STATE_ERROR;
1719 /* Process unlocked */
1720 __HAL_UNLOCK(hnand);
1722 return HAL_TIMEOUT;
1726 /* Increment written spare areas number */
1727 numSpareAreaWritten++;
1729 /* Decrement spare areas to write */
1730 nbspare--;
1732 /* Increment the NAND address */
1733 nandAddress = (uint32_t)(nandAddress + 1U);
1736 /* Update the NAND controller state */
1737 hnand->State = HAL_NAND_STATE_READY;
1739 /* Process unlocked */
1740 __HAL_UNLOCK(hnand);
1742 else
1744 return HAL_ERROR;
1747 return HAL_OK;
1751 * @brief NAND memory Block erase
1752 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1753 * the configuration information for NAND module.
1754 * @param pAddress pointer to NAND address structure
1755 * @retval HAL status
1757 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1759 uint32_t DeviceAddress;
1761 /* Check the NAND controller state */
1762 if (hnand->State == HAL_NAND_STATE_BUSY)
1764 return HAL_BUSY;
1766 else if (hnand->State == HAL_NAND_STATE_READY)
1768 /* Process Locked */
1769 __HAL_LOCK(hnand);
1771 /* Update the NAND controller state */
1772 hnand->State = HAL_NAND_STATE_BUSY;
1774 /* Identify the device address */
1775 DeviceAddress = NAND_DEVICE;
1777 /* Send Erase block command sequence */
1778 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
1779 __DSB();
1780 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1781 __DSB();
1782 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1783 __DSB();
1784 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1785 __DSB();
1787 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1788 __DSB();
1790 /* Update the NAND controller state */
1791 hnand->State = HAL_NAND_STATE_READY;
1793 /* Process unlocked */
1794 __HAL_UNLOCK(hnand);
1796 else
1798 return HAL_ERROR;
1801 return HAL_OK;
1805 * @brief Increment the NAND memory address
1806 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1807 * the configuration information for NAND module.
1808 * @param pAddress pointer to NAND address structure
1809 * @retval The new status of the increment address operation. It can be:
1810 * - NAND_VALID_ADDRESS: When the new address is valid address
1811 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1813 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1815 uint32_t status = NAND_VALID_ADDRESS;
1817 /* Increment page address */
1818 pAddress->Page++;
1820 /* Check NAND address is valid */
1821 if (pAddress->Page == hnand->Config.BlockSize)
1823 pAddress->Page = 0;
1824 pAddress->Block++;
1826 if (pAddress->Block == hnand->Config.PlaneSize)
1828 pAddress->Block = 0;
1829 pAddress->Plane++;
1831 if (pAddress->Plane == (hnand->Config.PlaneNbr))
1833 status = NAND_INVALID_ADDRESS;
1838 return (status);
1841 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1843 * @brief Register a User NAND Callback
1844 * To be used instead of the weak (surcharged) predefined callback
1845 * @param hnand : NAND handle
1846 * @param CallbackId : ID of the callback to be registered
1847 * This parameter can be one of the following values:
1848 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1849 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1850 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1851 * @param pCallback : pointer to the Callback function
1852 * @retval status
1854 HAL_StatusTypeDef HAL_NAND_RegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, pNAND_CallbackTypeDef pCallback)
1856 HAL_StatusTypeDef status = HAL_OK;
1858 if(pCallback == NULL)
1860 return HAL_ERROR;
1863 /* Process locked */
1864 __HAL_LOCK(hnand);
1866 if(hnand->State == HAL_NAND_STATE_READY)
1868 switch (CallbackId)
1870 case HAL_NAND_MSP_INIT_CB_ID :
1871 hnand->MspInitCallback = pCallback;
1872 break;
1873 case HAL_NAND_MSP_DEINIT_CB_ID :
1874 hnand->MspDeInitCallback = pCallback;
1875 break;
1876 case HAL_NAND_IT_CB_ID :
1877 hnand->ItCallback = pCallback;
1878 break;
1879 default :
1880 /* update return status */
1881 status = HAL_ERROR;
1882 break;
1885 else if(hnand->State == HAL_NAND_STATE_RESET)
1887 switch (CallbackId)
1889 case HAL_NAND_MSP_INIT_CB_ID :
1890 hnand->MspInitCallback = pCallback;
1891 break;
1892 case HAL_NAND_MSP_DEINIT_CB_ID :
1893 hnand->MspDeInitCallback = pCallback;
1894 break;
1895 default :
1896 /* update return status */
1897 status = HAL_ERROR;
1898 break;
1901 else
1903 /* update return status */
1904 status = HAL_ERROR;
1907 /* Release Lock */
1908 __HAL_UNLOCK(hnand);
1909 return status;
1913 * @brief Unregister a User NAND Callback
1914 * NAND Callback is redirected to the weak (surcharged) predefined callback
1915 * @param hnand : NAND handle
1916 * @param CallbackId : ID of the callback to be unregistered
1917 * This parameter can be one of the following values:
1918 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1919 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1920 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1921 * @retval status
1923 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1925 HAL_StatusTypeDef status = HAL_OK;
1927 /* Process locked */
1928 __HAL_LOCK(hnand);
1930 if(hnand->State == HAL_NAND_STATE_READY)
1932 switch (CallbackId)
1934 case HAL_NAND_MSP_INIT_CB_ID :
1935 hnand->MspInitCallback = HAL_NAND_MspInit;
1936 break;
1937 case HAL_NAND_MSP_DEINIT_CB_ID :
1938 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1939 break;
1940 case HAL_NAND_IT_CB_ID :
1941 hnand->ItCallback = HAL_NAND_ITCallback;
1942 break;
1943 default :
1944 /* update return status */
1945 status = HAL_ERROR;
1946 break;
1949 else if(hnand->State == HAL_NAND_STATE_RESET)
1951 switch (CallbackId)
1953 case HAL_NAND_MSP_INIT_CB_ID :
1954 hnand->MspInitCallback = HAL_NAND_MspInit;
1955 break;
1956 case HAL_NAND_MSP_DEINIT_CB_ID :
1957 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1958 break;
1959 default :
1960 /* update return status */
1961 status = HAL_ERROR;
1962 break;
1965 else
1967 /* update return status */
1968 status = HAL_ERROR;
1971 /* Release Lock */
1972 __HAL_UNLOCK(hnand);
1973 return status;
1975 #endif
1978 * @}
1981 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1982 * @brief management functions
1984 @verbatim
1985 ==============================================================================
1986 ##### NAND Control functions #####
1987 ==============================================================================
1988 [..]
1989 This subsection provides a set of functions allowing to control dynamically
1990 the NAND interface.
1992 @endverbatim
1993 * @{
1998 * @brief Enables dynamically NAND ECC feature.
1999 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2000 * the configuration information for NAND module.
2001 * @retval HAL status
2003 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2005 /* Check the NAND controller state */
2006 if (hnand->State == HAL_NAND_STATE_BUSY)
2008 return HAL_BUSY;
2010 else if (hnand->State == HAL_NAND_STATE_READY)
2012 /* Update the NAND state */
2013 hnand->State = HAL_NAND_STATE_BUSY;
2015 /* Enable ECC feature */
2016 (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2018 /* Update the NAND state */
2019 hnand->State = HAL_NAND_STATE_READY;
2021 else
2023 return HAL_ERROR;
2026 return HAL_OK;
2030 * @brief Disables dynamically FMC_NAND ECC feature.
2031 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2032 * the configuration information for NAND module.
2033 * @retval HAL status
2035 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2037 /* Check the NAND controller state */
2038 if (hnand->State == HAL_NAND_STATE_BUSY)
2040 return HAL_BUSY;
2042 else if (hnand->State == HAL_NAND_STATE_READY)
2044 /* Update the NAND state */
2045 hnand->State = HAL_NAND_STATE_BUSY;
2047 /* Disable ECC feature */
2048 (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2050 /* Update the NAND state */
2051 hnand->State = HAL_NAND_STATE_READY;
2053 else
2055 return HAL_ERROR;
2058 return HAL_OK;
2062 * @brief Disables dynamically NAND ECC feature.
2063 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2064 * the configuration information for NAND module.
2065 * @param ECCval pointer to ECC value
2066 * @param Timeout maximum timeout to wait
2067 * @retval HAL status
2069 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2071 HAL_StatusTypeDef status;
2073 /* Check the NAND controller state */
2074 if (hnand->State == HAL_NAND_STATE_BUSY)
2076 return HAL_BUSY;
2078 else if (hnand->State == HAL_NAND_STATE_READY)
2080 /* Update the NAND state */
2081 hnand->State = HAL_NAND_STATE_BUSY;
2083 /* Get NAND ECC value */
2084 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2086 /* Update the NAND state */
2087 hnand->State = HAL_NAND_STATE_READY;
2089 else
2091 return HAL_ERROR;
2094 return status;
2098 * @}
2102 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2103 * @brief Peripheral State functions
2105 @verbatim
2106 ==============================================================================
2107 ##### NAND State functions #####
2108 ==============================================================================
2109 [..]
2110 This subsection permits to get in run-time the status of the NAND controller
2111 and the data flow.
2113 @endverbatim
2114 * @{
2118 * @brief return the NAND state
2119 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2120 * the configuration information for NAND module.
2121 * @retval HAL state
2123 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2125 return hnand->State;
2129 * @brief NAND memory read status
2130 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2131 * the configuration information for NAND module.
2132 * @retval NAND status
2134 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2136 uint32_t data;
2137 uint32_t DeviceAddress;
2138 UNUSED(hnand);
2140 /* Identify the device address */
2141 DeviceAddress = NAND_DEVICE;
2143 /* Send Read status operation command */
2144 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
2146 /* Read status register data */
2147 data = *(__IO uint8_t *)DeviceAddress;
2149 /* Return the status */
2150 if ((data & NAND_ERROR) == NAND_ERROR)
2152 return NAND_ERROR;
2154 else if ((data & NAND_READY) == NAND_READY)
2156 return NAND_READY;
2158 else
2160 return NAND_BUSY;
2165 * @}
2169 * @}
2173 * @}
2176 #endif /* HAL_NAND_MODULE_ENABLED */
2179 * @}
2183 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/