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****/