2 ******************************************************************************
3 * @file stm32f1xx_hal_nand.c
4 * @author MCD Application Team
6 * @date 15-December-2014
7 * @brief NAND HAL module driver.
8 * This file provides a generic firmware to drive NAND memories mounted
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
16 This driver is a generic layered driver which contains a set of APIs used to
17 control NAND flash memories. It uses the FSMC/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()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
29 to read/write page(s)/spare area(s). These functions use specific device
30 information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
31 structure. The read/write address information is contained by the Nand_Address_Typedef
32 structure passed as parameter.
34 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
36 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
37 The erase block address information is contained in the Nand_Address_Typedef
38 structure passed as parameter.
40 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
42 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
43 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
44 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
46 (+) You can monitor the NAND device HAL state by calling the function
50 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
51 If a NAND flash device contains different operations and/or implementations,
52 it should be implemented separately.
55 ******************************************************************************
58 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
60 * Redistribution and use in source and binary forms, with or without modification,
61 * are permitted provided that the following conditions are met:
62 * 1. Redistributions of source code must retain the above copyright notice,
63 * this list of conditions and the following disclaimer.
64 * 2. Redistributions in binary form must reproduce the above copyright notice,
65 * this list of conditions and the following disclaimer in the documentation
66 * and/or other materials provided with the distribution.
67 * 3. Neither the name of STMicroelectronics nor the names of its contributors
68 * may be used to endorse or promote products derived from this software
69 * without specific prior written permission.
71 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
72 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
73 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
75 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
76 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
78 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
79 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 ******************************************************************************
85 /* Includes ------------------------------------------------------------------*/
86 #include "stm32f1xx_hal.h"
88 /** @addtogroup STM32F1xx_HAL_Driver
92 #ifdef HAL_NAND_MODULE_ENABLED
94 #if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
96 /** @defgroup NAND NAND
97 * @brief NAND HAL module driver
101 /* Private typedef -----------------------------------------------------------*/
102 /* Private define ------------------------------------------------------------*/
103 /** @defgroup NAND_Private_Constants NAND Private Constants
111 /* Private macro -------------------------------------------------------------*/
112 /** @defgroup NAND_Private_Macros NAND Private Macros
120 /* Private variables ---------------------------------------------------------*/
121 /* Private function prototypes -----------------------------------------------*/
122 /** @defgroup NAND_Private_Functions NAND Private Functions
125 static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address);
130 /* Exported functions ---------------------------------------------------------*/
132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
137 * @brief Initialization and Configuration functions
140 ==============================================================================
141 ##### NAND Initialization and de-initialization functions #####
142 ==============================================================================
144 This section provides functions allowing to initialize/de-initialize
152 * @brief Perform NAND memory Initialization sequence
153 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
154 * the configuration information for NAND module.
155 * @param ComSpace_Timing: pointer to Common space timing structure
156 * @param AttSpace_Timing: pointer to Attribute space timing structure
159 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
161 /* Check the NAND handle state */
167 if(hnand->State == HAL_NAND_STATE_RESET)
169 /* Allocate lock resource and initialize it */
170 hnand-> Lock = HAL_UNLOCKED;
172 /* Initialize the low level hardware (MSP) */
173 HAL_NAND_MspInit(hnand);
176 /* Initialize NAND control Interface */
177 FSMC_NAND_Init(hnand->Instance, &(hnand->Init));
179 /* Initialize NAND common space timing Interface */
180 FSMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
182 /* Initialize NAND attribute space timing Interface */
183 FSMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
185 /* Enable the NAND device */
186 __FSMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
188 /* Update the NAND controller state */
189 hnand->State = HAL_NAND_STATE_READY;
195 * @brief Perform NAND memory De-Initialization sequence
196 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
197 * the configuration information for NAND module.
200 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
202 /* Initialize the low level hardware (MSP) */
203 HAL_NAND_MspDeInit(hnand);
205 /* Configure the NAND registers with their reset values */
206 FSMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
208 /* Reset the NAND controller state */
209 hnand->State = HAL_NAND_STATE_RESET;
218 * @brief NAND MSP Init
219 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
220 * the configuration information for NAND module.
223 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
225 /* NOTE : This function Should not be modified, when the callback is needed,
226 the HAL_NAND_MspInit could be implemented in the user file
231 * @brief NAND MSP DeInit
232 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
233 * the configuration information for NAND module.
236 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
238 /* NOTE : This function Should not be modified, when the callback is needed,
239 the HAL_NAND_MspDeInit could be implemented in the user file
245 * @brief This function handles NAND device interrupt request.
246 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
247 * the configuration information for NAND module.
250 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
252 /* Check NAND interrupt Rising edge flag */
253 if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
255 /* NAND interrupt callback*/
256 HAL_NAND_ITCallback(hnand);
258 /* Clear NAND interrupt Rising edge pending bit */
259 __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
262 /* Check NAND interrupt Level flag */
263 if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
265 /* NAND interrupt callback*/
266 HAL_NAND_ITCallback(hnand);
268 /* Clear NAND interrupt Level pending bit */
269 __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
272 /* Check NAND interrupt Falling edge flag */
273 if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
275 /* NAND interrupt callback*/
276 HAL_NAND_ITCallback(hnand);
278 /* Clear NAND interrupt Falling edge pending bit */
279 __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
282 /* Check NAND interrupt FIFO empty flag */
283 if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
285 /* NAND interrupt callback*/
286 HAL_NAND_ITCallback(hnand);
288 /* Clear NAND interrupt FIFO empty pending bit */
289 __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
295 * @brief NAND interrupt feature callback
296 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
297 * the configuration information for NAND module.
300 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
302 /* NOTE : This function Should not be modified, when the callback is needed,
303 the HAL_NAND_ITCallback could be implemented in the user file
311 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
312 * @brief Input Output and memory control functions
315 ==============================================================================
316 ##### NAND Input and Output functions #####
317 ==============================================================================
319 This section provides functions allowing to use and control the NAND
327 * @brief Read the NAND memory electronic signature
328 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
329 * the configuration information for NAND module.
330 * @param pNAND_ID: NAND ID structure
333 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
335 __IO uint32_t data = 0;
336 uint32_t deviceaddress = 0;
341 /* Check the NAND controller state */
342 if(hnand->State == HAL_NAND_STATE_BUSY)
347 /* Identify the device address */
348 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
350 deviceaddress = NAND_DEVICE1;
354 deviceaddress = NAND_DEVICE2;
357 /* Update the NAND controller state */
358 hnand->State = HAL_NAND_STATE_BUSY;
360 /* Send Read ID command sequence */
361 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
362 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
364 /* Read the electronic signature from NAND flash */
365 data = *(__IO uint32_t *)deviceaddress;
367 /* Return the data read */
368 pNAND_ID->Maker_Id = __ADDR_1st_CYCLE(data);
369 pNAND_ID->Device_Id = __ADDR_2nd_CYCLE(data);
370 pNAND_ID->Third_Id = __ADDR_3rd_CYCLE(data);
371 pNAND_ID->Fourth_Id = __ADDR_4th_CYCLE(data);
373 /* Update the NAND controller state */
374 hnand->State = HAL_NAND_STATE_READY;
376 /* Process unlocked */
383 * @brief NAND memory reset
384 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
385 * the configuration information for NAND module.
388 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
390 uint32_t deviceaddress = 0;
395 /* Check the NAND controller state */
396 if(hnand->State == HAL_NAND_STATE_BUSY)
401 /* Identify the device address */
402 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
404 deviceaddress = NAND_DEVICE1;
408 deviceaddress = NAND_DEVICE2;
411 /* Update the NAND controller state */
412 hnand->State = HAL_NAND_STATE_BUSY;
414 /* Send NAND reset command */
415 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
418 /* Update the NAND controller state */
419 hnand->State = HAL_NAND_STATE_READY;
421 /* Process unlocked */
429 * @brief Read Page(s) from NAND memory block
430 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
431 * the configuration information for NAND module.
432 * @param pAddress : pointer to NAND address structure
433 * @param pBuffer : pointer to destination read buffer
434 * @param NumPageToRead : number of pages to read from block
437 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
439 __IO uint32_t index = 0;
440 uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
441 NAND_AddressTypeDef nandaddress;
442 uint32_t addressoffset = 0;
447 /* Check the NAND controller state */
448 if(hnand->State == HAL_NAND_STATE_BUSY)
453 /* Identify the device address */
454 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
456 deviceaddress = NAND_DEVICE1;
460 deviceaddress = NAND_DEVICE2;
463 /* Update the NAND controller state */
464 hnand->State = HAL_NAND_STATE_BUSY;
466 /* Save the content of pAddress as it will be modified */
467 nandaddress.Block = pAddress->Block;
468 nandaddress.Page = pAddress->Page;
469 nandaddress.Zone = pAddress->Zone;
471 /* Page(s) read loop */
472 while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
474 /* update the buffer size */
475 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
477 /* Get the address offset */
478 addressoffset = __ARRAY_ADDRESS(&nandaddress, hnand);
480 /* Send read page command sequence */
481 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
483 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
484 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_1st_CYCLE(addressoffset);
485 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(addressoffset);
486 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(addressoffset);
488 /* for 512 and 1 GB devices, 4th cycle is required */
489 if(hnand->Info.BlockNbr >= 1024)
491 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_4th_CYCLE(addressoffset);
494 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
496 /* Get Data into Buffer */
497 for(; index < size; index++)
499 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
502 /* Increment read pages number */
505 /* Decrement pages to read */
508 /* Increment the NAND address */
509 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
512 /* Update the NAND controller state */
513 hnand->State = HAL_NAND_STATE_READY;
515 /* Process unlocked */
523 * @brief Write Page(s) to NAND memory block
524 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
525 * the configuration information for NAND module.
526 * @param pAddress : pointer to NAND address structure
527 * @param pBuffer : pointer to source buffer to write
528 * @param NumPageToWrite : number of pages to write to block
531 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
533 __IO uint32_t index = 0;
534 uint32_t tickstart = 0;
535 uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
536 NAND_AddressTypeDef nandaddress;
537 uint32_t addressoffset = 0;
542 /* Check the NAND controller state */
543 if(hnand->State == HAL_NAND_STATE_BUSY)
548 /* Identify the device address */
549 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
551 deviceaddress = NAND_DEVICE1;
555 deviceaddress = NAND_DEVICE2;
558 /* Update the NAND controller state */
559 hnand->State = HAL_NAND_STATE_BUSY;
561 /* Save the content of pAddress as it will be modified */
562 nandaddress.Block = pAddress->Block;
563 nandaddress.Page = pAddress->Page;
564 nandaddress.Zone = pAddress->Zone;
566 /* Page(s) write loop */
567 while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
569 /* update the buffer size */
570 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
572 /* Get the address offset */
573 addressoffset = __ARRAY_ADDRESS(&nandaddress, hnand);
575 /* Send write page command sequence */
576 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
577 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
579 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
580 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_1st_CYCLE(addressoffset);
581 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(addressoffset);
582 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(addressoffset);
584 /* for 512 and 1 GB devices, 4th cycle is required */
585 if(hnand->Info.BlockNbr >= 1024)
587 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_4th_CYCLE(addressoffset);
590 /* Write data to memory */
591 for(; index < size; index++)
593 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
596 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
599 tickstart = HAL_GetTick();
601 /* Read status until NAND is ready */
602 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
604 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
610 /* Increment written pages number */
613 /* Decrement pages to write */
616 /* Increment the NAND address */
617 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
620 /* Update the NAND controller state */
621 hnand->State = HAL_NAND_STATE_READY;
623 /* Process unlocked */
630 * @brief Read Spare area(s) from NAND memory
631 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
632 * the configuration information for NAND module.
633 * @param pAddress : pointer to NAND address structure
634 * @param pBuffer: pointer to source buffer to write
635 * @param NumSpareAreaToRead: Number of spare area to read
638 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
640 __IO uint32_t index = 0;
641 uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
642 NAND_AddressTypeDef nandaddress;
643 uint32_t addressoffset = 0;
648 /* Check the NAND controller state */
649 if(hnand->State == HAL_NAND_STATE_BUSY)
654 /* Identify the device address */
655 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
657 deviceaddress = NAND_DEVICE1;
661 deviceaddress = NAND_DEVICE2;
664 /* Update the NAND controller state */
665 hnand->State = HAL_NAND_STATE_BUSY;
667 /* Save the content of pAddress as it will be modified */
668 nandaddress.Block = pAddress->Block;
669 nandaddress.Page = pAddress->Page;
670 nandaddress.Zone = pAddress->Zone;
672 /* Spare area(s) read loop */
673 while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
675 /* update the buffer size */
676 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);
678 /* Get the address offset */
679 addressoffset = __ARRAY_ADDRESS(&nandaddress, hnand);
681 /* Send read spare area command sequence */
682 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
684 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
685 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_1st_CYCLE(addressoffset);
686 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(addressoffset);
687 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(addressoffset);
689 /* for 512 and 1 GB devices, 4th cycle is required */
690 if(hnand->Info.BlockNbr >= 1024)
692 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_4th_CYCLE(addressoffset);
695 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
697 /* Get Data into Buffer */
698 for ( ;index < size; index++)
700 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
703 /* Increment read spare areas number */
704 num_spare_area_read++;
706 /* Decrement spare areas to read */
707 NumSpareAreaToRead--;
709 /* Increment the NAND address */
710 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
713 /* Update the NAND controller state */
714 hnand->State = HAL_NAND_STATE_READY;
716 /* Process unlocked */
723 * @brief Write Spare area(s) to NAND memory
724 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
725 * the configuration information for NAND module.
726 * @param pAddress : pointer to NAND address structure
727 * @param pBuffer : pointer to source buffer to write
728 * @param NumSpareAreaTowrite : number of spare areas to write to block
731 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
733 __IO uint32_t index = 0;
734 uint32_t tickstart = 0;
735 uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
736 NAND_AddressTypeDef nandaddress;
737 uint32_t addressoffset = 0;
742 /* Check the NAND controller state */
743 if(hnand->State == HAL_NAND_STATE_BUSY)
748 /* Identify the device address */
749 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
751 deviceaddress = NAND_DEVICE1;
755 deviceaddress = NAND_DEVICE2;
758 /* Update the FMC_NAND controller state */
759 hnand->State = HAL_NAND_STATE_BUSY;
761 /* Save the content of pAddress as it will be modified */
762 nandaddress.Block = pAddress->Block;
763 nandaddress.Page = pAddress->Page;
764 nandaddress.Zone = pAddress->Zone;
766 /* Spare area(s) write loop */
767 while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
769 /* update the buffer size */
770 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
772 /* Get the address offset */
773 addressoffset = __ARRAY_ADDRESS(&nandaddress, hnand);
775 /* Send write Spare area command sequence */
776 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
777 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
779 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
780 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_1st_CYCLE(addressoffset);
781 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(addressoffset);
782 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(addressoffset);
784 /* for 512 and 1 GB devices, 4th cycle is required */
785 if(hnand->Info.BlockNbr >= 1024)
787 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_4th_CYCLE(addressoffset);
790 /* Write data to memory */
791 for(; index < size; index++)
793 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
796 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
799 tickstart = HAL_GetTick();
801 /* Read status until NAND is ready */
802 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
804 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
810 /* Increment written spare areas number */
811 num_spare_area_written++;
813 /* Decrement spare areas to write */
814 NumSpareAreaTowrite--;
816 /* Increment the NAND address */
817 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
820 /* Update the NAND controller state */
821 hnand->State = HAL_NAND_STATE_READY;
823 /* Process unlocked */
830 * @brief NAND memory Block erase
831 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
832 * the configuration information for NAND module.
833 * @param pAddress : pointer to NAND address structure
836 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
838 uint32_t deviceaddress = 0;
839 uint32_t tickstart = 0;
844 /* Check the NAND controller state */
845 if(hnand->State == HAL_NAND_STATE_BUSY)
850 /* Identify the device address */
851 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
853 deviceaddress = NAND_DEVICE1;
857 deviceaddress = NAND_DEVICE2;
860 /* Update the NAND controller state */
861 hnand->State = HAL_NAND_STATE_BUSY;
863 /* Send Erase block command sequence */
864 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
866 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_1st_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
867 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
868 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
870 /* for 512 and 1 GB devices, 4th cycle is required */
871 if(hnand->Info.BlockNbr >= 1024)
873 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = __ADDR_4th_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
876 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
878 /* Update the NAND controller state */
879 hnand->State = HAL_NAND_STATE_READY;
882 tickstart = HAL_GetTick();
884 /* Read status until NAND is ready */
885 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
887 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
889 /* Process unlocked */
896 /* Process unlocked */
903 * @brief NAND memory read status
904 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
905 * the configuration information for NAND module.
906 * @retval NAND status
908 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
911 uint32_t deviceaddress = 0;
913 /* Identify the device address */
914 if(hnand->Init.NandBank == FSMC_NAND_BANK2)
916 deviceaddress = NAND_DEVICE1;
920 deviceaddress = NAND_DEVICE2;
923 /* Send Read status operation command */
924 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
926 /* Read status register data */
927 data = *(__IO uint8_t *)deviceaddress;
929 /* Return the status */
930 if((data & NAND_ERROR) == NAND_ERROR)
934 else if((data & NAND_READY) == NAND_READY)
943 * @brief Increment the NAND memory address
944 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
945 * the configuration information for NAND module.
946 * @param pAddress: pointer to NAND address structure
947 * @retval The new status of the increment address operation. It can be:
948 * - NAND_VALID_ADDRESS: When the new address is valid address
949 * - NAND_INVALID_ADDRESS: When the new address is invalid address
951 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
953 uint32_t status = NAND_VALID_ADDRESS;
955 /* Increment page address */
958 /* Check NAND address is valid */
959 if(pAddress->Page == hnand->Info.BlockSize)
964 if(pAddress->Block == hnand->Info.ZoneSize)
969 if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
971 status = NAND_INVALID_ADDRESS;
982 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
983 * @brief management functions
986 ==============================================================================
987 ##### NAND Control functions #####
988 ==============================================================================
990 This subsection provides a set of functions allowing to control dynamically
999 * @brief Enables dynamically NAND ECC feature.
1000 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1001 * the configuration information for NAND module.
1002 * @retval HAL status
1004 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
1006 /* Check the NAND controller state */
1007 if(hnand->State == HAL_NAND_STATE_BUSY)
1012 /* Update the NAND state */
1013 hnand->State = HAL_NAND_STATE_BUSY;
1015 /* Enable ECC feature */
1016 FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1018 /* Update the NAND state */
1019 hnand->State = HAL_NAND_STATE_READY;
1025 * @brief Disables dynamically FSMC_NAND ECC feature.
1026 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1027 * the configuration information for NAND module.
1028 * @retval HAL status
1030 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
1032 /* Check the NAND controller state */
1033 if(hnand->State == HAL_NAND_STATE_BUSY)
1038 /* Update the NAND state */
1039 hnand->State = HAL_NAND_STATE_BUSY;
1041 /* Disable ECC feature */
1042 FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1044 /* Update the NAND state */
1045 hnand->State = HAL_NAND_STATE_READY;
1051 * @brief Disables dynamically NAND ECC feature.
1052 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1053 * the configuration information for NAND module.
1054 * @param ECCval: pointer to ECC value
1055 * @param Timeout: maximum timeout to wait
1056 * @retval HAL status
1058 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1060 HAL_StatusTypeDef status = HAL_OK;
1062 /* Check the NAND controller state */
1063 if(hnand->State == HAL_NAND_STATE_BUSY)
1068 /* Update the NAND state */
1069 hnand->State = HAL_NAND_STATE_BUSY;
1071 /* Get NAND ECC value */
1072 status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1074 /* Update the NAND state */
1075 hnand->State = HAL_NAND_STATE_READY;
1085 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1086 * @brief Peripheral State functions
1089 ==============================================================================
1090 ##### NAND State functions #####
1091 ==============================================================================
1093 This subsection permits to get in run-time the status of the NAND controller
1101 * @brief return the NAND state
1102 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1103 * the configuration information for NAND module.
1106 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1108 return hnand->State;
1119 /** @addtogroup NAND_Private_Functions
1124 * @brief Increment the NAND memory address.
1125 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1126 * the configuration information for NAND module.
1127 * @param Address: address to be incremented.
1128 * @retval The new status of the increment address operation. It can be:
1129 * - NAND_VALID_ADDRESS: When the new address is valid address
1130 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1132 static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address)
1134 uint32_t status = NAND_VALID_ADDRESS;
1138 if(Address->Page == hnand->Info.BlockSize)
1143 if(Address->Block == hnand->Info.ZoneSize)
1148 if(Address->Zone == hnand->Info.BlockNbr)
1150 status = NAND_INVALID_ADDRESS;
1166 #endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
1167 #endif /* HAL_NAND_MODULE_ENABLED */
1173 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/