before merging master
[inav.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_nand.c
blob29df0894bf6d51378752b14db5f52459833525e9
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_nand.c
4 * @author MCD Application Team
5 * @version V1.2.2
6 * @date 14-April-2017
7 * @brief NAND HAL module driver.
8 * This file provides a generic firmware to drive NAND memories mounted
9 * as external device.
11 @verbatim
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
15 [..]
16 This driver is a generic layered driver which contains a set of APIs used to
17 control NAND flash memories. It uses the FMC/FSMC layer functions to interface
18 with NAND devices. This driver is used as follows:
20 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
21 with control and timing parameters for both common and attribute spaces.
23 (+) Read NAND flash memory maker and device IDs using the function
24 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
25 structure declared by the function caller.
27 (+) Access NAND flash memory by read/write operations using the functions
28 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
29 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
30 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
31 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
32 to read/write page(s)/spare area(s). These functions use specific device
33 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
34 structure. The read/write address information is contained by the Nand_Address_Typedef
35 structure passed as parameter.
37 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
39 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
40 The erase block address information is contained in the Nand_Address_Typedef
41 structure passed as parameter.
43 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
45 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
46 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
47 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
49 (+) You can monitor the NAND device HAL state by calling the function
50 HAL_NAND_GetState()
52 [..]
53 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
54 If a NAND flash device contains different operations and/or implementations,
55 it should be implemented separately.
57 @endverbatim
58 ******************************************************************************
59 * @attention
61 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
63 * Redistribution and use in source and binary forms, with or without modification,
64 * are permitted provided that the following conditions are met:
65 * 1. Redistributions of source code must retain the above copyright notice,
66 * this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright notice,
68 * this list of conditions and the following disclaimer in the documentation
69 * and/or other materials provided with the distribution.
70 * 3. Neither the name of STMicroelectronics nor the names of its contributors
71 * may be used to endorse or promote products derived from this software
72 * without specific prior written permission.
74 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
78 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
80 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
81 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
82 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 ******************************************************************************
86 */
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32f7xx_hal.h"
91 /** @addtogroup STM32F7xx_HAL_Driver
92 * @{
96 #ifdef HAL_NAND_MODULE_ENABLED
98 /** @defgroup NAND NAND
99 * @brief NAND HAL module driver
100 * @{
103 /* Private typedef -----------------------------------------------------------*/
104 /* Private Constants ------------------------------------------------------------*/
105 /* Private macro -------------------------------------------------------------*/
106 /* Private variables ---------------------------------------------------------*/
107 /* Private function prototypes -----------------------------------------------*/
108 /* Exported functions ---------------------------------------------------------*/
110 /** @defgroup NAND_Exported_Functions NAND Exported Functions
111 * @{
114 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
115 * @brief Initialization and Configuration functions
117 @verbatim
118 ==============================================================================
119 ##### NAND Initialization and de-initialization functions #####
120 ==============================================================================
121 [..]
122 This section provides functions allowing to initialize/de-initialize
123 the NAND memory
125 @endverbatim
126 * @{
130 * @brief Perform NAND memory Initialization sequence
131 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
132 * the configuration information for NAND module.
133 * @param ComSpace_Timing: pointer to Common space timing structure
134 * @param AttSpace_Timing: pointer to Attribute space timing structure
135 * @retval HAL status
137 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
139 /* Check the NAND handle state */
140 if(hnand == NULL)
142 return HAL_ERROR;
145 if(hnand->State == HAL_NAND_STATE_RESET)
147 /* Allocate lock resource and initialize it */
148 hnand->Lock = HAL_UNLOCKED;
149 /* Initialize the low level hardware (MSP) */
150 HAL_NAND_MspInit(hnand);
153 /* Initialize NAND control Interface */
154 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
156 /* Initialize NAND common space timing Interface */
157 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
159 /* Initialize NAND attribute space timing Interface */
160 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
162 /* Enable the NAND device */
163 __FMC_NAND_ENABLE(hnand->Instance);
165 /* Update the NAND controller state */
166 hnand->State = HAL_NAND_STATE_READY;
168 return HAL_OK;
172 * @brief Perform NAND memory De-Initialization sequence
173 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
174 * the configuration information for NAND module.
175 * @retval HAL status
177 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
179 /* Initialize the low level hardware (MSP) */
180 HAL_NAND_MspDeInit(hnand);
182 /* Configure the NAND registers with their reset values */
183 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
185 /* Reset the NAND controller state */
186 hnand->State = HAL_NAND_STATE_RESET;
188 /* Release Lock */
189 __HAL_UNLOCK(hnand);
191 return HAL_OK;
195 * @brief NAND MSP Init
196 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
197 * the configuration information for NAND module.
198 * @retval None
200 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
202 /* Prevent unused argument(s) compilation warning */
203 UNUSED(hnand);
205 /* NOTE : This function Should not be modified, when the callback is needed,
206 the HAL_NAND_MspInit could be implemented in the user file
211 * @brief NAND MSP DeInit
212 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
213 * the configuration information for NAND module.
214 * @retval None
216 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
218 /* Prevent unused argument(s) compilation warning */
219 UNUSED(hnand);
221 /* NOTE : This function Should not be modified, when the callback is needed,
222 the HAL_NAND_MspDeInit could be implemented in the user file
228 * @brief This function handles NAND device interrupt request.
229 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
230 * the configuration information for NAND module.
231 * @retval HAL status
233 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
235 /* Check NAND interrupt Rising edge flag */
236 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
238 /* NAND interrupt callback*/
239 HAL_NAND_ITCallback(hnand);
241 /* Clear NAND interrupt Rising edge pending bit */
242 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
245 /* Check NAND interrupt Level flag */
246 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
248 /* NAND interrupt callback*/
249 HAL_NAND_ITCallback(hnand);
251 /* Clear NAND interrupt Level pending bit */
252 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
255 /* Check NAND interrupt Falling edge flag */
256 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
258 /* NAND interrupt callback*/
259 HAL_NAND_ITCallback(hnand);
261 /* Clear NAND interrupt Falling edge pending bit */
262 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
265 /* Check NAND interrupt FIFO empty flag */
266 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
268 /* NAND interrupt callback*/
269 HAL_NAND_ITCallback(hnand);
271 /* Clear NAND interrupt FIFO empty pending bit */
272 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
278 * @brief NAND interrupt feature callback
279 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
280 * the configuration information for NAND module.
281 * @retval None
283 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
285 /* Prevent unused argument(s) compilation warning */
286 UNUSED(hnand);
288 /* NOTE : This function Should not be modified, when the callback is needed,
289 the HAL_NAND_ITCallback could be implemented in the user file
294 * @}
297 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
298 * @brief Input Output and memory control functions
300 @verbatim
301 ==============================================================================
302 ##### NAND Input and Output functions #####
303 ==============================================================================
304 [..]
305 This section provides functions allowing to use and control the NAND
306 memory
308 @endverbatim
309 * @{
313 * @brief Read the NAND memory electronic signature
314 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
315 * the configuration information for NAND module.
316 * @param pNAND_ID: NAND ID structure
317 * @retval HAL status
319 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
321 __IO uint32_t data = 0;
322 __IO uint32_t data1 = 0;
323 uint32_t deviceAddress = 0;
325 /* Process Locked */
326 __HAL_LOCK(hnand);
328 /* Check the NAND controller state */
329 if(hnand->State == HAL_NAND_STATE_BUSY)
331 return HAL_BUSY;
334 /* Identify the device address */
335 deviceAddress = NAND_DEVICE;
337 /* Update the NAND controller state */
338 hnand->State = HAL_NAND_STATE_BUSY;
340 /* Send Read ID command sequence */
341 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
342 __DSB();
343 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
344 __DSB();
346 /* Read the electronic signature from NAND flash */
347 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
349 data = *(__IO uint32_t *)deviceAddress;
351 /* Return the data read */
352 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
353 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
354 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
355 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
357 else
359 data = *(__IO uint32_t *)deviceAddress;
360 data1 = *((__IO uint32_t *)deviceAddress + 4);
362 /* Return the data read */
363 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
364 pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
365 pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
366 pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
369 /* Update the NAND controller state */
370 hnand->State = HAL_NAND_STATE_READY;
372 /* Process unlocked */
373 __HAL_UNLOCK(hnand);
375 return HAL_OK;
379 * @brief NAND memory reset
380 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
381 * the configuration information for NAND module.
382 * @retval HAL status
384 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
386 uint32_t deviceAddress = 0;
388 /* Process Locked */
389 __HAL_LOCK(hnand);
391 /* Check the NAND controller state */
392 if(hnand->State == HAL_NAND_STATE_BUSY)
394 return HAL_BUSY;
397 /* Identify the device address */
398 deviceAddress = NAND_DEVICE;
400 /* Update the NAND controller state */
401 hnand->State = HAL_NAND_STATE_BUSY;
403 /* Send NAND reset command */
404 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
406 /* Update the NAND controller state */
407 hnand->State = HAL_NAND_STATE_READY;
409 /* Process unlocked */
410 __HAL_UNLOCK(hnand);
412 return HAL_OK;
417 * @brief Configure the device: Enter the physical parameters of the device
418 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
419 * the configuration information for NAND module.
420 * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
421 * @retval HAL status
423 HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
425 hnand->Config.PageSize = pDeviceConfig->PageSize;
426 hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
427 hnand->Config.BlockSize = pDeviceConfig->BlockSize;
428 hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
429 hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
430 hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
431 hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
433 return HAL_OK;
438 * @brief Read Page(s) from NAND memory block (8-bits addressing)
439 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
440 * the configuration information for NAND module.
441 * @param pAddress : pointer to NAND address structure
442 * @param pBuffer : pointer to destination read buffer
443 * @param NumPageToRead : number of pages to read from block
444 * @retval HAL status
446 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
448 __IO uint32_t index = 0;
449 uint32_t tickstart = 0U;
450 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
452 /* Process Locked */
453 __HAL_LOCK(hnand);
455 /* Check the NAND controller state */
456 if(hnand->State == HAL_NAND_STATE_BUSY)
458 return HAL_BUSY;
461 /* Identify the device address */
462 deviceAddress = NAND_DEVICE;
464 /* Update the NAND controller state */
465 hnand->State = HAL_NAND_STATE_BUSY;
467 /* NAND raw address calculation */
468 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
470 /* Page(s) read loop */
471 while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
473 /* update the buffer size */
474 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
476 /* Send read page command sequence */
477 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
478 __DSB();
480 /* Cards with page size <= 512 bytes */
481 if((hnand->Config.PageSize) <= 512)
483 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
485 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
486 __DSB();
487 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
488 __DSB();
489 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
490 __DSB();
492 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
494 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
495 __DSB();
496 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
497 __DSB();
498 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
499 __DSB();
500 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
501 __DSB();
504 else /* (hnand->Config.PageSize) > 512 */
506 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
508 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
509 __DSB();
510 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
511 __DSB();
512 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
513 __DSB();
514 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
515 __DSB();
517 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
519 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
520 __DSB();
521 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
522 __DSB();
523 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
524 __DSB();
525 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
526 __DSB();
527 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
528 __DSB();
532 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
533 __DSB();
536 if(hnand->Config.ExtraCommandEnable == ENABLE)
538 /* Get tick */
539 tickstart = HAL_GetTick();
541 /* Read status until NAND is ready */
542 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
544 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
546 return HAL_TIMEOUT;
550 /* Go back to read mode */
551 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
552 __DSB();
555 /* Get Data into Buffer */
556 for(; index < size; index++)
558 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
561 /* Increment read pages number */
562 numPagesRead++;
564 /* Decrement pages to read */
565 NumPageToRead--;
567 /* Increment the NAND address */
568 nandAddress = (uint32_t)(nandAddress + 1);
571 /* Update the NAND controller state */
572 hnand->State = HAL_NAND_STATE_READY;
574 /* Process unlocked */
575 __HAL_UNLOCK(hnand);
577 return HAL_OK;
582 * @brief Read Page(s) from NAND memory block (16-bits addressing)
583 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
584 * the configuration information for NAND module.
585 * @param pAddress : pointer to NAND address structure
586 * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
587 * @param NumPageToRead : number of pages to read from block
588 * @retval HAL status
590 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
592 __IO uint32_t index = 0;
593 uint32_t tickstart = 0;
594 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
596 /* Process Locked */
597 __HAL_LOCK(hnand);
599 /* Check the NAND controller state */
600 if(hnand->State == HAL_NAND_STATE_BUSY)
602 return HAL_BUSY;
605 /* Identify the device address */
606 deviceAddress = NAND_DEVICE;
608 /* Update the NAND controller state */
609 hnand->State = HAL_NAND_STATE_BUSY;
611 /* NAND raw address calculation */
612 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
614 /* Page(s) read loop */
615 while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
617 /* update the buffer size */
618 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
620 /* Send read page command sequence */
621 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
622 __DSB();
624 /* Cards with page size <= 512 bytes */
625 if((hnand->Config.PageSize) <= 512)
627 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
629 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
630 __DSB();
631 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
632 __DSB();
633 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
634 __DSB();
636 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
638 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
639 __DSB();
640 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
641 __DSB();
642 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
643 __DSB();
644 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
645 __DSB();
648 else /* (hnand->Config.PageSize) > 512 */
650 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
652 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
653 __DSB();
654 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
655 __DSB();
656 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
657 __DSB();
658 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
659 __DSB();
661 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
663 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
664 __DSB();
665 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
666 __DSB();
667 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
668 __DSB();
669 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
670 __DSB();
671 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
672 __DSB();
676 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
677 __DSB();
679 if(hnand->Config.ExtraCommandEnable == ENABLE)
681 /* Get tick */
682 tickstart = HAL_GetTick();
684 /* Read status until NAND is ready */
685 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
687 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
689 return HAL_TIMEOUT;
693 /* Go back to read mode */
694 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
695 __DSB();
698 /* Get Data into Buffer */
699 for(; index < size; index++)
701 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
704 /* Increment read pages number */
705 numPagesRead++;
707 /* Decrement pages to read */
708 NumPageToRead--;
710 /* Increment the NAND address */
711 nandAddress = (uint32_t)(nandAddress + 1);
714 /* Update the NAND controller state */
715 hnand->State = HAL_NAND_STATE_READY;
717 /* Process unlocked */
718 __HAL_UNLOCK(hnand);
720 return HAL_OK;
724 * @brief Write Page(s) to NAND memory block (8-bits addressing)
725 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
726 * the configuration information for NAND module.
727 * @param pAddress : pointer to NAND address structure
728 * @param pBuffer : pointer to source buffer to write
729 * @param NumPageToWrite : number of pages to write to block
730 * @retval HAL status
732 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
734 __IO uint32_t index = 0;
735 uint32_t tickstart = 0;
736 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
738 /* Process Locked */
739 __HAL_LOCK(hnand);
741 /* Check the NAND controller state */
742 if(hnand->State == HAL_NAND_STATE_BUSY)
744 return HAL_BUSY;
747 /* Identify the device address */
748 deviceAddress = NAND_DEVICE;
750 /* Update the NAND controller state */
751 hnand->State = HAL_NAND_STATE_BUSY;
753 /* NAND raw address calculation */
754 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
756 /* Page(s) write loop */
757 while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
759 /* update the buffer size */
760 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
762 /* Send write page command sequence */
763 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
764 __DSB();
765 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
766 __DSB();
768 /* Cards with page size <= 512 bytes */
769 if((hnand->Config.PageSize) <= 512)
771 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
773 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
774 __DSB();
775 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
776 __DSB();
777 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
778 __DSB();
780 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
782 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
783 __DSB();
784 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
785 __DSB();
786 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
787 __DSB();
788 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
789 __DSB();
792 else /* (hnand->Config.PageSize) > 512 */
794 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
796 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
797 __DSB();
798 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
799 __DSB();
800 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
801 __DSB();
802 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
803 __DSB();
805 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
807 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
808 __DSB();
809 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
810 __DSB();
811 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
812 __DSB();
813 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
814 __DSB();
815 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
816 __DSB();
820 /* Write data to memory */
821 for(; index < size; index++)
823 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
824 __DSB();
827 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
828 __DSB();
830 /* Read status until NAND is ready */
831 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
833 /* Get tick */
834 tickstart = HAL_GetTick();
836 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
838 return HAL_TIMEOUT;
842 /* Increment written pages number */
843 numPagesWritten++;
845 /* Decrement pages to write */
846 NumPageToWrite--;
848 /* Increment the NAND address */
849 nandAddress = (uint32_t)(nandAddress + 1);
852 /* Update the NAND controller state */
853 hnand->State = HAL_NAND_STATE_READY;
855 /* Process unlocked */
856 __HAL_UNLOCK(hnand);
858 return HAL_OK;
862 * @brief Write Page(s) to NAND memory block (16-bits addressing)
863 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
864 * the configuration information for NAND module.
865 * @param pAddress : pointer to NAND address structure
866 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
867 * @param NumPageToWrite : number of pages to write to block
868 * @retval HAL status
870 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
872 __IO uint32_t index = 0;
873 uint32_t tickstart = 0;
874 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
876 /* Process Locked */
877 __HAL_LOCK(hnand);
879 /* Check the NAND controller state */
880 if(hnand->State == HAL_NAND_STATE_BUSY)
882 return HAL_BUSY;
885 /* Identify the device address */
886 deviceAddress = NAND_DEVICE;
888 /* Update the NAND controller state */
889 hnand->State = HAL_NAND_STATE_BUSY;
891 /* NAND raw address calculation */
892 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
894 /* Page(s) write loop */
895 while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
897 /* update the buffer size */
898 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
900 /* Send write page command sequence */
901 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
902 __DSB();
903 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
904 __DSB();
906 /* Cards with page size <= 512 bytes */
907 if((hnand->Config.PageSize) <= 512)
909 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
911 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
912 __DSB();
913 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
914 __DSB();
915 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
916 __DSB();
918 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
920 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
921 __DSB();
922 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
923 __DSB();
924 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
925 __DSB();
926 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
927 __DSB();
930 else /* (hnand->Config.PageSize) > 512 */
932 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
934 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
935 __DSB();
936 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
937 __DSB();
938 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
939 __DSB();
940 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
941 __DSB();
943 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
945 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
946 __DSB();
947 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
948 __DSB();
949 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
950 __DSB();
951 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
952 __DSB();
953 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
954 __DSB();
958 /* Write data to memory */
959 for(; index < size; index++)
961 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
962 __DSB();
965 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
966 __DSB();
968 /* Read status until NAND is ready */
969 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
971 /* Get tick */
972 tickstart = HAL_GetTick();
974 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
976 return HAL_TIMEOUT;
980 /* Increment written pages number */
981 numPagesWritten++;
983 /* Decrement pages to write */
984 NumPageToWrite--;
986 /* Increment the NAND address */
987 nandAddress = (uint32_t)(nandAddress + 1);
990 /* Update the NAND controller state */
991 hnand->State = HAL_NAND_STATE_READY;
993 /* Process unlocked */
994 __HAL_UNLOCK(hnand);
996 return HAL_OK;
1000 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
1001 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1002 * the configuration information for NAND module.
1003 * @param pAddress : pointer to NAND address structure
1004 * @param pBuffer: pointer to source buffer to write
1005 * @param NumSpareAreaToRead: Number of spare area to read
1006 * @retval HAL status
1008 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1010 __IO uint32_t index = 0;
1011 uint32_t tickstart = 0U;
1012 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1014 /* Process Locked */
1015 __HAL_LOCK(hnand);
1017 /* Check the NAND controller state */
1018 if(hnand->State == HAL_NAND_STATE_BUSY)
1020 return HAL_BUSY;
1023 /* Identify the device address */
1024 deviceAddress = NAND_DEVICE;
1026 /* Update the NAND controller state */
1027 hnand->State = HAL_NAND_STATE_BUSY;
1029 /* NAND raw address calculation */
1030 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1032 /* Column in page address */
1033 columnAddress = COLUMN_ADDRESS(hnand);
1035 /* Spare area(s) read loop */
1036 while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1038 /* update the buffer size */
1039 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1041 /* Cards with page size <= 512 bytes */
1042 if((hnand->Config.PageSize) <= 512)
1044 /* Send read spare area command sequence */
1045 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1046 __DSB();
1048 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1050 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
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();
1057 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1059 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1060 __DSB();
1061 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1062 __DSB();
1063 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1064 __DSB();
1065 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1066 __DSB();
1069 else /* (hnand->Config.PageSize) > 512 */
1071 /* Send read spare area command sequence */
1072 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1073 __DSB();
1075 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1077 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1078 __DSB();
1079 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1080 __DSB();
1081 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1082 __DSB();
1083 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1084 __DSB();
1086 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1088 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1089 __DSB();
1090 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1091 __DSB();
1092 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1093 __DSB();
1094 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1095 __DSB();
1096 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1097 __DSB();
1101 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1102 __DSB();
1104 if(hnand->Config.ExtraCommandEnable == ENABLE)
1106 /* Get tick */
1107 tickstart = HAL_GetTick();
1109 /* Read status until NAND is ready */
1110 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1112 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1114 return HAL_TIMEOUT;
1118 /* Go back to read mode */
1119 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1120 __DSB();
1123 /* Get Data into Buffer */
1124 for(; index < size; index++)
1126 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
1129 /* Increment read spare areas number */
1130 numSpareAreaRead++;
1132 /* Decrement spare areas to read */
1133 NumSpareAreaToRead--;
1135 /* Increment the NAND address */
1136 nandAddress = (uint32_t)(nandAddress + 1);
1139 /* Update the NAND controller state */
1140 hnand->State = HAL_NAND_STATE_READY;
1142 /* Process unlocked */
1143 __HAL_UNLOCK(hnand);
1145 return HAL_OK;
1149 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1150 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1151 * the configuration information for NAND module.
1152 * @param pAddress : pointer to NAND address structure
1153 * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
1154 * @param NumSpareAreaToRead: Number of spare area to read
1155 * @retval HAL status
1157 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1159 __IO uint32_t index = 0;
1160 uint32_t tickstart = 0U;
1161 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1163 /* Process Locked */
1164 __HAL_LOCK(hnand);
1166 /* Check the NAND controller state */
1167 if(hnand->State == HAL_NAND_STATE_BUSY)
1169 return HAL_BUSY;
1172 /* Identify the device address */
1173 deviceAddress = NAND_DEVICE;
1175 /* Update the NAND controller state */
1176 hnand->State = HAL_NAND_STATE_BUSY;
1178 /* NAND raw address calculation */
1179 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1181 /* Column in page address */
1182 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1184 /* Spare area(s) read loop */
1185 while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1187 /* update the buffer size */
1188 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1190 /* Cards with page size <= 512 bytes */
1191 if((hnand->Config.PageSize) <= 512)
1193 /* Send read spare area command sequence */
1194 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1195 __DSB();
1197 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1199 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1200 __DSB();
1201 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1202 __DSB();
1203 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1204 __DSB();
1206 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1208 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1209 __DSB();
1210 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1211 __DSB();
1212 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1213 __DSB();
1214 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1215 __DSB();
1218 else /* (hnand->Config.PageSize) > 512 */
1220 /* Send read spare area command sequence */
1221 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1222 __DSB();
1224 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1226 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1227 __DSB();
1228 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1229 __DSB();
1230 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1231 __DSB();
1232 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1233 __DSB();
1235 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1237 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1238 __DSB();
1239 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1240 __DSB();
1241 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1242 __DSB();
1243 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1244 __DSB();
1245 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1246 __DSB();
1250 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1251 __DSB();
1253 if(hnand->Config.ExtraCommandEnable == ENABLE)
1255 /* Get tick */
1256 tickstart = HAL_GetTick();
1258 /* Read status until NAND is ready */
1259 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1261 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1263 return HAL_TIMEOUT;
1267 /* Go back to read mode */
1268 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1269 __DSB();
1272 /* Get Data into Buffer */
1273 for(; index < size; index++)
1275 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
1278 /* Increment read spare areas number */
1279 numSpareAreaRead++;
1281 /* Decrement spare areas to read */
1282 NumSpareAreaToRead--;
1284 /* Increment the NAND address */
1285 nandAddress = (uint32_t)(nandAddress + 1);
1288 /* Update the NAND controller state */
1289 hnand->State = HAL_NAND_STATE_READY;
1291 /* Process unlocked */
1292 __HAL_UNLOCK(hnand);
1294 return HAL_OK;
1298 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1299 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1300 * the configuration information for NAND module.
1301 * @param pAddress : pointer to NAND address structure
1302 * @param pBuffer : pointer to source buffer to write
1303 * @param NumSpareAreaTowrite : number of spare areas to write to block
1304 * @retval HAL status
1306 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1308 __IO uint32_t index = 0;
1309 uint32_t tickstart = 0;
1310 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress =0;
1312 /* Process Locked */
1313 __HAL_LOCK(hnand);
1315 /* Check the NAND controller state */
1316 if(hnand->State == HAL_NAND_STATE_BUSY)
1318 return HAL_BUSY;
1321 /* Identify the device address */
1322 deviceAddress = NAND_DEVICE;
1324 /* Update the FMC_NAND controller state */
1325 hnand->State = HAL_NAND_STATE_BUSY;
1327 /* Page address calculation */
1328 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1330 /* Column in page address */
1331 columnAddress = COLUMN_ADDRESS(hnand);
1333 /* Spare area(s) write loop */
1334 while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1336 /* update the buffer size */
1337 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1339 /* Cards with page size <= 512 bytes */
1340 if((hnand->Config.PageSize) <= 512)
1342 /* Send write Spare area command sequence */
1343 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1344 __DSB();
1345 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1346 __DSB();
1348 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1350 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1351 __DSB();
1352 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1353 __DSB();
1354 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1355 __DSB();
1357 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1359 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1360 __DSB();
1361 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1362 __DSB();
1363 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1364 __DSB();
1365 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1366 __DSB();
1369 else /* (hnand->Config.PageSize) > 512 */
1371 /* Send write Spare area command sequence */
1372 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1373 __DSB();
1374 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1375 __DSB();
1377 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1379 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1380 __DSB();
1381 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1382 __DSB();
1383 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1384 __DSB();
1385 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1386 __DSB();
1388 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1390 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1391 __DSB();
1392 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1393 __DSB();
1394 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1395 __DSB();
1396 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1397 __DSB();
1398 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1399 __DSB();
1403 /* Write data to memory */
1404 for(; index < size; index++)
1406 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
1407 __DSB();
1410 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1411 __DSB();
1413 /* Read status until NAND is ready */
1414 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1416 /* Get tick */
1417 tickstart = HAL_GetTick();
1419 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1421 return HAL_TIMEOUT;
1425 /* Increment written spare areas number */
1426 numSpareAreaWritten++;
1428 /* Decrement spare areas to write */
1429 NumSpareAreaTowrite--;
1431 /* Increment the NAND address */
1432 nandAddress = (uint32_t)(nandAddress + 1);
1435 /* Update the NAND controller state */
1436 hnand->State = HAL_NAND_STATE_READY;
1438 /* Process unlocked */
1439 __HAL_UNLOCK(hnand);
1441 return HAL_OK;
1445 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1446 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1447 * the configuration information for NAND module.
1448 * @param pAddress : pointer to NAND address structure
1449 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
1450 * @param NumSpareAreaTowrite : number of spare areas to write to block
1451 * @retval HAL status
1453 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1455 __IO uint32_t index = 0;
1456 uint32_t tickstart = 0;
1457 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
1459 /* Process Locked */
1460 __HAL_LOCK(hnand);
1462 /* Check the NAND controller state */
1463 if(hnand->State == HAL_NAND_STATE_BUSY)
1465 return HAL_BUSY;
1468 /* Identify the device address */
1469 deviceAddress = NAND_DEVICE;
1471 /* Update the FMC_NAND controller state */
1472 hnand->State = HAL_NAND_STATE_BUSY;
1474 /* NAND raw address calculation */
1475 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1477 /* Column in page address */
1478 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1480 /* Spare area(s) write loop */
1481 while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1483 /* update the buffer size */
1484 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1486 /* Cards with page size <= 512 bytes */
1487 if((hnand->Config.PageSize) <= 512)
1489 /* Send write Spare area command sequence */
1490 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1491 __DSB();
1492 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1493 __DSB();
1495 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
1497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1498 __DSB();
1499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1500 __DSB();
1501 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1502 __DSB();
1504 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1506 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1507 __DSB();
1508 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1509 __DSB();
1510 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1511 __DSB();
1512 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1513 __DSB();
1516 else /* (hnand->Config.PageSize) > 512 */
1518 /* Send write Spare area command sequence */
1519 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1520 __DSB();
1521 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1522 __DSB();
1524 if (((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();
1535 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1537 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1538 __DSB();
1539 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1540 __DSB();
1541 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1542 __DSB();
1543 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1544 __DSB();
1545 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1546 __DSB();
1550 /* Write data to memory */
1551 for(; index < size; index++)
1553 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
1554 __DSB();
1557 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1558 __DSB();
1560 /* Read status until NAND is ready */
1561 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1563 /* Get tick */
1564 tickstart = HAL_GetTick();
1566 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1568 return HAL_TIMEOUT;
1572 /* Increment written spare areas number */
1573 numSpareAreaWritten++;
1575 /* Decrement spare areas to write */
1576 NumSpareAreaTowrite--;
1578 /* Increment the NAND address */
1579 nandAddress = (uint32_t)(nandAddress + 1);
1582 /* Update the NAND controller state */
1583 hnand->State = HAL_NAND_STATE_READY;
1585 /* Process unlocked */
1586 __HAL_UNLOCK(hnand);
1588 return HAL_OK;
1592 * @brief NAND memory Block erase
1593 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1594 * the configuration information for NAND module.
1595 * @param pAddress : pointer to NAND address structure
1596 * @retval HAL status
1598 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1600 uint32_t DeviceAddress = 0;
1602 /* Process Locked */
1603 __HAL_LOCK(hnand);
1605 /* Check the NAND controller state */
1606 if(hnand->State == HAL_NAND_STATE_BUSY)
1608 return HAL_BUSY;
1611 /* Identify the device address */
1612 DeviceAddress = NAND_DEVICE;
1614 /* Update the NAND controller state */
1615 hnand->State = HAL_NAND_STATE_BUSY;
1617 /* Send Erase block command sequence */
1618 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
1619 __DSB();
1620 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1621 __DSB();
1622 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1623 __DSB();
1624 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1625 __DSB();
1627 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1628 __DSB();
1630 /* Update the NAND controller state */
1631 hnand->State = HAL_NAND_STATE_READY;
1633 /* Process unlocked */
1634 __HAL_UNLOCK(hnand);
1636 return HAL_OK;
1640 * @brief Increment the NAND memory address
1641 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1642 * the configuration information for NAND module.
1643 * @param pAddress: pointer to NAND address structure
1644 * @retval The new status of the increment address operation. It can be:
1645 * - NAND_VALID_ADDRESS: When the new address is valid address
1646 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1648 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1650 uint32_t status = NAND_VALID_ADDRESS;
1652 /* Increment page address */
1653 pAddress->Page++;
1655 /* Check NAND address is valid */
1656 if(pAddress->Page == hnand->Config.BlockSize)
1658 pAddress->Page = 0;
1659 pAddress->Block++;
1661 if(pAddress->Block == hnand->Config.PlaneSize)
1663 pAddress->Block = 0;
1664 pAddress->Plane++;
1666 if(pAddress->Plane == (hnand->Config.PlaneNbr))
1668 status = NAND_INVALID_ADDRESS;
1673 return (status);
1676 * @}
1679 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1680 * @brief management functions
1682 @verbatim
1683 ==============================================================================
1684 ##### NAND Control functions #####
1685 ==============================================================================
1686 [..]
1687 This subsection provides a set of functions allowing to control dynamically
1688 the NAND interface.
1690 @endverbatim
1691 * @{
1696 * @brief Enables dynamically NAND ECC feature.
1697 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1698 * the configuration information for NAND module.
1699 * @retval HAL status
1701 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
1703 /* Check the NAND controller state */
1704 if(hnand->State == HAL_NAND_STATE_BUSY)
1706 return HAL_BUSY;
1709 /* Update the NAND state */
1710 hnand->State = HAL_NAND_STATE_BUSY;
1712 /* Enable ECC feature */
1713 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1715 /* Update the NAND state */
1716 hnand->State = HAL_NAND_STATE_READY;
1718 return HAL_OK;
1722 * @brief Disables dynamically FMC_NAND ECC feature.
1723 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1724 * the configuration information for NAND module.
1725 * @retval HAL status
1727 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
1729 /* Check the NAND controller state */
1730 if(hnand->State == HAL_NAND_STATE_BUSY)
1732 return HAL_BUSY;
1735 /* Update the NAND state */
1736 hnand->State = HAL_NAND_STATE_BUSY;
1738 /* Disable ECC feature */
1739 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1741 /* Update the NAND state */
1742 hnand->State = HAL_NAND_STATE_READY;
1744 return HAL_OK;
1748 * @brief Disables dynamically NAND ECC feature.
1749 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1750 * the configuration information for NAND module.
1751 * @param ECCval: pointer to ECC value
1752 * @param Timeout: maximum timeout to wait
1753 * @retval HAL status
1755 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1757 HAL_StatusTypeDef status = HAL_OK;
1759 /* Check the NAND controller state */
1760 if(hnand->State == HAL_NAND_STATE_BUSY)
1762 return HAL_BUSY;
1765 /* Update the NAND state */
1766 hnand->State = HAL_NAND_STATE_BUSY;
1768 /* Get NAND ECC value */
1769 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1771 /* Update the NAND state */
1772 hnand->State = HAL_NAND_STATE_READY;
1774 return status;
1778 * @}
1782 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1783 * @brief Peripheral State functions
1785 @verbatim
1786 ==============================================================================
1787 ##### NAND State functions #####
1788 ==============================================================================
1789 [..]
1790 This subsection permits to get in run-time the status of the NAND controller
1791 and the data flow.
1793 @endverbatim
1794 * @{
1798 * @brief return the NAND state
1799 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1800 * the configuration information for NAND module.
1801 * @retval HAL state
1803 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1805 return hnand->State;
1809 * @brief NAND memory read status
1810 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1811 * the configuration information for NAND module.
1812 * @retval NAND status
1814 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
1816 uint32_t data = 0;
1817 uint32_t DeviceAddress = 0;
1819 /* Identify the device address */
1820 DeviceAddress = NAND_DEVICE;
1822 /* Send Read status operation command */
1823 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
1825 /* Read status register data */
1826 data = *(__IO uint8_t *)DeviceAddress;
1828 /* Return the status */
1829 if((data & NAND_ERROR) == NAND_ERROR)
1831 return NAND_ERROR;
1833 else if((data & NAND_READY) == NAND_READY)
1835 return NAND_READY;
1838 return NAND_BUSY;
1842 * @}
1846 * @}
1849 #endif /* HAL_NAND_MODULE_ENABLED */
1852 * @}
1856 * @}
1859 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/