2 ******************************************************************************
3 * @file stm32f3xx_hal_nand.c
4 * @author MCD Application Team
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 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()/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 "stm32f3xx_hal.h"
88 /** @addtogroup STM32F3xx_HAL_Driver
92 /** @defgroup NAND NAND HAL module driver
93 * @brief NAND HAL module driver
96 #ifdef HAL_NAND_MODULE_ENABLED
98 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx)
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /* Private macro -------------------------------------------------------------*/
103 /* Private variables ---------------------------------------------------------*/
104 /* Private function prototypes -----------------------------------------------*/
105 /* Exported functions ---------------------------------------------------------*/
107 /** @defgroup NAND_Exported_Functions NAND Exported Functions
111 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
112 * @brief Initialization and Configuration functions
115 ==============================================================================
116 ##### NAND Initialization and de-initialization functions #####
117 ==============================================================================
119 This section provides functions allowing to initialize/de-initialize
127 * @brief Perform NAND memory Initialization sequence
128 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
129 * the configuration information for NAND module.
130 * @param ComSpace_Timing: pointer to Common space timing structure
131 * @param AttSpace_Timing: pointer to Attribute space timing structure
134 HAL_StatusTypeDef
HAL_NAND_Init(NAND_HandleTypeDef
*hnand
, FMC_NAND_PCC_TimingTypeDef
*ComSpace_Timing
, FMC_NAND_PCC_TimingTypeDef
*AttSpace_Timing
)
136 /* Check the NAND handle state */
137 if(hnand
== HAL_NULL
)
142 if(hnand
->State
== HAL_NAND_STATE_RESET
)
144 /* Initialize the low level hardware (MSP) */
145 HAL_NAND_MspInit(hnand
);
148 /* Initialize NAND control Interface */
149 FMC_NAND_Init(hnand
->Instance
, &(hnand
->Init
));
151 /* Initialize NAND common space timing Interface */
152 FMC_NAND_CommonSpace_Timing_Init(hnand
->Instance
, ComSpace_Timing
, hnand
->Init
.NandBank
);
154 /* Initialize NAND attribute space timing Interface */
155 FMC_NAND_AttributeSpace_Timing_Init(hnand
->Instance
, AttSpace_Timing
, hnand
->Init
.NandBank
);
157 /* Enable the NAND device */
158 __FMC_NAND_ENABLE(hnand
->Instance
, hnand
->Init
.NandBank
);
160 /* Update the NAND controller state */
161 hnand
->State
= HAL_NAND_STATE_READY
;
167 * @brief Perform NAND memory De-Initialization sequence
168 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
169 * the configuration information for NAND module.
172 HAL_StatusTypeDef
HAL_NAND_DeInit(NAND_HandleTypeDef
*hnand
)
174 /* Initialize the low level hardware (MSP) */
175 HAL_NAND_MspDeInit(hnand
);
177 /* Configure the NAND registers with their reset values */
178 FMC_NAND_DeInit(hnand
->Instance
, hnand
->Init
.NandBank
);
180 /* Reset the NAND controller state */
181 hnand
->State
= HAL_NAND_STATE_RESET
;
190 * @brief NAND MSP Init
191 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
192 * the configuration information for NAND module.
195 __weak
void HAL_NAND_MspInit(NAND_HandleTypeDef
*hnand
)
197 /* NOTE : This function Should not be modified, when the callback is needed,
198 the HAL_NAND_MspInit could be implemented in the user file
203 * @brief NAND MSP DeInit
204 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
205 * the configuration information for NAND module.
208 __weak
void HAL_NAND_MspDeInit(NAND_HandleTypeDef
*hnand
)
210 /* NOTE : This function Should not be modified, when the callback is needed,
211 the HAL_NAND_MspDeInit could be implemented in the user file
217 * @brief This function handles NAND device interrupt request.
218 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
219 * the configuration information for NAND module.
222 void HAL_NAND_IRQHandler(NAND_HandleTypeDef
*hnand
)
224 /* Check NAND interrupt Rising edge flag */
225 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
))
227 /* NAND interrupt callback*/
228 HAL_NAND_ITCallback(hnand
);
230 /* Clear NAND interrupt Rising edge pending bit */
231 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
);
234 /* Check NAND interrupt Level flag */
235 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
))
237 /* NAND interrupt callback*/
238 HAL_NAND_ITCallback(hnand
);
240 /* Clear NAND interrupt Level pending bit */
241 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
);
244 /* Check NAND interrupt Falling edge flag */
245 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
))
247 /* NAND interrupt callback*/
248 HAL_NAND_ITCallback(hnand
);
250 /* Clear NAND interrupt Falling edge pending bit */
251 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
);
254 /* Check NAND interrupt FIFO empty flag */
255 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
))
257 /* NAND interrupt callback*/
258 HAL_NAND_ITCallback(hnand
);
260 /* Clear NAND interrupt FIFO empty pending bit */
261 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
);
267 * @brief NAND interrupt feature callback
268 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
269 * the configuration information for NAND module.
272 __weak
void HAL_NAND_ITCallback(NAND_HandleTypeDef
*hnand
)
274 /* NOTE : This function Should not be modified, when the callback is needed,
275 the HAL_NAND_ITCallback could be implemented in the user file
283 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
284 * @brief Input Output and memory control functions
287 ==============================================================================
288 ##### NAND Input and Output functions #####
289 ==============================================================================
291 This section provides functions allowing to use and control the NAND
299 * @brief Read the NAND memory electronic signature
300 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
301 * the configuration information for NAND module.
302 * @param pNAND_ID: NAND ID structure
305 HAL_StatusTypeDef
HAL_NAND_Read_ID(NAND_HandleTypeDef
*hnand
, NAND_IDTypeDef
*pNAND_ID
)
307 __IO
uint32_t data
= 0;
308 uint32_t deviceAddress
= 0;
313 /* Check the NAND controller state */
314 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
319 /* Identify the device address */
320 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
322 deviceAddress
= NAND_DEVICE1
;
326 deviceAddress
= NAND_DEVICE2
;
329 /* Update the NAND controller state */
330 hnand
->State
= HAL_NAND_STATE_BUSY
;
332 /* Send Read ID command sequence */
333 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x90;
334 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
336 /* Read the electronic signature from NAND flash */
337 data
= *(__IO
uint32_t *)deviceAddress
;
339 /* Return the data read */
340 pNAND_ID
->Maker_Id
= ADDR_1st_CYCLE(data
);
341 pNAND_ID
->Device_Id
= ADDR_2nd_CYCLE(data
);
342 pNAND_ID
->Third_Id
= ADDR_3rd_CYCLE(data
);
343 pNAND_ID
->Fourth_Id
= ADDR_4th_CYCLE(data
);
345 /* Update the NAND controller state */
346 hnand
->State
= HAL_NAND_STATE_READY
;
348 /* Process unlocked */
355 * @brief NAND memory reset
356 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
357 * the configuration information for NAND module.
360 HAL_StatusTypeDef
HAL_NAND_Reset(NAND_HandleTypeDef
*hnand
)
362 uint32_t deviceAddress
= 0;
367 /* Check the NAND controller state */
368 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
373 /* Identify the device address */
374 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
376 deviceAddress
= NAND_DEVICE1
;
380 deviceAddress
= NAND_DEVICE2
;
383 /* Update the NAND controller state */
384 hnand
->State
= HAL_NAND_STATE_BUSY
;
386 /* Send NAND reset command */
387 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0xFF;
390 /* Update the NAND controller state */
391 hnand
->State
= HAL_NAND_STATE_READY
;
393 /* Process unlocked */
402 * @brief Read Page(s) from NAND memory block
403 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
404 * the configuration information for NAND module.
405 * @param pAddress : pointer to NAND address structure
406 * @param pBuffer : pointer to destination read buffer
407 * @param NumPageToRead : number of pages to read from block
410 HAL_StatusTypeDef
HAL_NAND_Read_Page(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToRead
)
412 __IO
uint32_t index
= 0;
413 uint32_t deviceAddress
= 0, size
= 0, numPagesRead
= 0, nandAddress
= 0;
418 /* Check the NAND controller state */
419 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
424 /* Identify the device address */
425 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
427 deviceAddress
= NAND_DEVICE1
;
431 deviceAddress
= NAND_DEVICE2
;
434 /* Update the NAND controller state */
435 hnand
->State
= HAL_NAND_STATE_BUSY
;
437 /* NAND raw address calculation */
438 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
440 /* Page(s) read loop */
441 while((NumPageToRead
!= 0) && (nandAddress
< ((hnand
->Info
.BlockSize
) * (hnand
->Info
.PageSize
) * (hnand
->Info
.ZoneSize
))))
443 /* update the buffer size */
444 size
= (hnand
->Info
.PageSize
) + ((hnand
->Info
.PageSize
) * numPagesRead
);
446 /* Send read page command sequence */
447 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
449 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
450 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1st_CYCLE(nandAddress
);
451 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2nd_CYCLE(nandAddress
);
452 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3rd_CYCLE(nandAddress
);
454 /* for 512 and 1 GB devices, 4th cycle is required */
455 if(hnand
->Info
.BlockNbr
>= 1024)
457 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_4th_CYCLE(nandAddress
);
460 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x30;
462 /* Get Data into Buffer */
463 for(; index
< size
; index
++)
465 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
468 /* Increment read pages number */
471 /* Decrement pages to read */
474 /* Increment the NAND address */
475 nandAddress
= (uint32_t)(nandAddress
+ (hnand
->Info
.PageSize
* 8));
479 /* Update the NAND controller state */
480 hnand
->State
= HAL_NAND_STATE_READY
;
482 /* Process unlocked */
490 * @brief Write Page(s) to NAND memory block
491 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
492 * the configuration information for NAND module.
493 * @param pAddress : pointer to NAND address structure
494 * @param pBuffer : pointer to source buffer to write
495 * @param NumPageToWrite : number of pages to write to block
498 HAL_StatusTypeDef
HAL_NAND_Write_Page(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToWrite
)
500 __IO
uint32_t index
= 0;
501 uint32_t timeout
= 0;
502 uint32_t deviceAddress
= 0, size
= 0 , numPagesWritten
= 0, nandAddress
= 0;
507 /* Check the NAND controller state */
508 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
513 /* Identify the device address */
514 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
516 deviceAddress
= NAND_DEVICE1
;
520 deviceAddress
= NAND_DEVICE2
;
523 /* Update the NAND controller state */
524 hnand
->State
= HAL_NAND_STATE_BUSY
;
526 /* NAND raw address calculation */
527 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
529 /* Page(s) write loop */
530 while((NumPageToWrite
!= 0) && (nandAddress
< ((hnand
->Info
.BlockSize
) * (hnand
->Info
.PageSize
) * (hnand
->Info
.ZoneSize
))))
532 /* update the buffer size */
533 size
= (hnand
->Info
.PageSize
) + ((hnand
->Info
.PageSize
) * numPagesWritten
);
535 /* Send write page command sequence */
536 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
537 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x80;
539 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
540 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1st_CYCLE(nandAddress
);
541 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2nd_CYCLE(nandAddress
);
542 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3rd_CYCLE(nandAddress
);
544 /* for 512 and 1 GB devices, 4th cycle is required */
545 if(hnand
->Info
.BlockNbr
>= 1024)
547 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_4th_CYCLE(nandAddress
);
550 /* Write data to memory */
551 for(; index
< size
; index
++)
553 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
556 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x10;
558 /* Read status until NAND is ready */
559 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
561 /* Check for timeout value */
562 timeout
= HAL_GetTick() + NAND_WRITE_TIMEOUT
;
564 if(HAL_GetTick() >= timeout
)
570 /* Increment written pages number */
573 /* Decrement pages to write */
576 /* Increment the NAND address */
577 nandAddress
= (uint32_t)(nandAddress
+ (hnand
->Info
.PageSize
* 8));
581 /* Update the NAND controller state */
582 hnand
->State
= HAL_NAND_STATE_READY
;
584 /* Process unlocked */
592 * @brief Read Spare area(s) from NAND memory
593 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
594 * the configuration information for NAND module.
595 * @param pAddress : pointer to NAND address structure
596 * @param pBuffer: pointer to source buffer to write
597 * @param NumSpareAreaToRead: Number of spare area to read
600 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaToRead
)
602 __IO
uint32_t index
= 0;
603 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaRead
= 0, nandAddress
= 0;
608 /* Check the NAND controller state */
609 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
614 /* Identify the device address */
615 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
617 deviceAddress
= NAND_DEVICE1
;
621 deviceAddress
= NAND_DEVICE2
;
624 /* Update the NAND controller state */
625 hnand
->State
= HAL_NAND_STATE_BUSY
;
627 /* NAND raw address calculation */
628 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
630 /* Spare area(s) read loop */
631 while((NumSpareAreaToRead
!= 0) && (nandAddress
< ((hnand
->Info
.BlockSize
) * (hnand
->Info
.SpareAreaSize
) * (hnand
->Info
.ZoneSize
))))
634 /* update the buffer size */
635 size
= (hnand
->Info
.SpareAreaSize
) + ((hnand
->Info
.SpareAreaSize
) * numSpareAreaRead
);
637 /* Send read spare area command sequence */
638 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
640 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
641 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1st_CYCLE(nandAddress
);
642 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2nd_CYCLE(nandAddress
);
643 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3rd_CYCLE(nandAddress
);
645 /* for 512 and 1 GB devices, 4th cycle is required */
646 if(hnand
->Info
.BlockNbr
>= 1024)
648 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_4th_CYCLE(nandAddress
);
651 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x30;
653 /* Get Data into Buffer */
654 for ( ;index
< size
; index
++)
656 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
659 /* Increment read spare areas number */
662 /* Decrement spare areas to read */
663 NumSpareAreaToRead
--;
665 /* Increment the NAND address */
666 nandAddress
= (uint32_t)(nandAddress
+ (hnand
->Info
.SpareAreaSize
));
669 /* Update the NAND controller state */
670 hnand
->State
= HAL_NAND_STATE_READY
;
672 /* Process unlocked */
679 * @brief Write Spare area(s) to NAND memory
680 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
681 * the configuration information for NAND module.
682 * @param pAddress : pointer to NAND address structure
683 * @param pBuffer : pointer to source buffer to write
684 * @param NumSpareAreaTowrite : number of spare areas to write to block
687 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
689 __IO
uint32_t index
= 0;
690 uint32_t timeout
= 0;
691 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaWritten
= 0, nandAddress
= 0;
696 /* Check the NAND controller state */
697 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
702 /* Identify the device address */
703 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
705 deviceAddress
= NAND_DEVICE1
;
709 deviceAddress
= NAND_DEVICE2
;
712 /* Update the FMC_NAND controller state */
713 hnand
->State
= HAL_NAND_STATE_BUSY
;
715 /* NAND raw address calculation */
716 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
718 /* Spare area(s) write loop */
719 while((NumSpareAreaTowrite
!= 0) && (nandAddress
< ((hnand
->Info
.BlockSize
) * (hnand
->Info
.SpareAreaSize
) * (hnand
->Info
.ZoneSize
))))
721 /* update the buffer size */
722 size
= (hnand
->Info
.SpareAreaSize
) + ((hnand
->Info
.SpareAreaSize
) * numSpareAreaWritten
);
724 /* Send write Spare area command sequence */
725 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
726 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x80;
728 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
729 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1st_CYCLE(nandAddress
);
730 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2nd_CYCLE(nandAddress
);
731 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3rd_CYCLE(nandAddress
);
733 /* for 512 and 1 GB devices, 4th cycle is required */
734 if(hnand
->Info
.BlockNbr
>= 1024)
736 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_4th_CYCLE(nandAddress
);
739 /* Write data to memory */
740 for(; index
< size
; index
++)
742 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
745 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0x10;
748 /* Read status until NAND is ready */
749 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
751 /* Check for timeout value */
752 timeout
= HAL_GetTick() + NAND_WRITE_TIMEOUT
;
754 if(HAL_GetTick() >= timeout
)
760 /* Increment written spare areas number */
761 numSpareAreaWritten
++;
763 /* Decrement spare areas to write */
764 NumSpareAreaTowrite
--;
766 /* Increment the NAND address */
767 nandAddress
= (uint32_t)(nandAddress
+ (hnand
->Info
.PageSize
));
771 /* Update the NAND controller state */
772 hnand
->State
= HAL_NAND_STATE_READY
;
774 /* Process unlocked */
781 * @brief NAND memory Block erase
782 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
783 * the configuration information for NAND module.
784 * @param pAddress : pointer to NAND address structure
787 HAL_StatusTypeDef
HAL_NAND_Erase_Block(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
)
789 uint32_t DeviceAddress
= 0;
794 /* Check the NAND controller state */
795 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
800 /* Identify the device address */
801 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
803 DeviceAddress
= NAND_DEVICE1
;
807 DeviceAddress
= NAND_DEVICE2
;
810 /* Update the NAND controller state */
811 hnand
->State
= HAL_NAND_STATE_BUSY
;
813 /* Send Erase block command sequence */
814 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = 0x60;
816 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_1st_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
817 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_2nd_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
818 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_3rd_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
820 /* for 512 and 1 GB devices, 4th cycle is required */
821 if(hnand
->Info
.BlockNbr
>= 1024)
823 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_4th_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
826 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = 0xD0;
828 /* Update the NAND controller state */
829 hnand
->State
= HAL_NAND_STATE_READY
;
831 /* Process unlocked */
839 * @brief NAND memory read status
840 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
841 * the configuration information for NAND module.
842 * @retval NAND status
844 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef
*hnand
)
847 uint32_t DeviceAddress
= 0;
849 /* Identify the device address */
850 if(hnand
->Init
.NandBank
== FMC_NAND_BANK2
)
852 DeviceAddress
= NAND_DEVICE1
;
856 DeviceAddress
= NAND_DEVICE2
;
859 /* Send Read status operation command */
860 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = 0x70;
862 /* Read status register data */
863 data
= *(__IO
uint8_t *)DeviceAddress
;
865 /* Return the status */
866 if((data
& NAND_ERROR
) == NAND_ERROR
)
870 else if((data
& NAND_READY
) == NAND_READY
)
880 * @brief Increment the NAND memory address
881 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
882 * the configuration information for NAND module.
883 * @param pAddress: pointer to NAND adress structure
884 * @retval The new status of the increment address operation. It can be:
885 * - NAND_VALID_ADDRESS: When the new address is valid address
886 * - NAND_INVALID_ADDRESS: When the new address is invalid address
888 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef
*hnand
, NAND_AddressTypedef
*pAddress
)
890 uint32_t status
= NAND_VALID_ADDRESS
;
892 /* Increment page address */
895 /* Check NAND address is valid */
896 if(pAddress
->Page
== hnand
->Info
.BlockSize
)
901 if(pAddress
->Block
== hnand
->Info
.ZoneSize
)
906 if(pAddress
->Zone
== (hnand
->Info
.ZoneSize
/ hnand
->Info
.BlockNbr
))
908 status
= NAND_INVALID_ADDRESS
;
921 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
922 * @brief management functions
925 ==============================================================================
926 ##### NAND Control functions #####
927 ==============================================================================
929 This subsection provides a set of functions allowing to control dynamically
938 * @brief Enables dynamically NAND ECC feature.
939 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
940 * the configuration information for NAND module.
943 HAL_StatusTypeDef
HAL_NAND_ECC_Enable(NAND_HandleTypeDef
*hnand
)
945 /* Check the NAND controller state */
946 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
951 /* Update the NAND state */
952 hnand
->State
= HAL_NAND_STATE_BUSY
;
954 /* Enable ECC feature */
955 FMC_NAND_ECC_Enable(hnand
->Instance
, hnand
->Init
.NandBank
);
957 /* Update the NAND state */
958 hnand
->State
= HAL_NAND_STATE_READY
;
965 * @brief Disables dynamically FMC_NAND ECC feature.
966 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
967 * the configuration information for NAND module.
970 HAL_StatusTypeDef
HAL_NAND_ECC_Disable(NAND_HandleTypeDef
*hnand
)
972 /* Check the NAND controller state */
973 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
978 /* Update the NAND state */
979 hnand
->State
= HAL_NAND_STATE_BUSY
;
981 /* Disable ECC feature */
982 FMC_NAND_ECC_Disable(hnand
->Instance
, hnand
->Init
.NandBank
);
984 /* Update the NAND state */
985 hnand
->State
= HAL_NAND_STATE_READY
;
991 * @brief Disables dynamically NAND ECC feature.
992 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
993 * the configuration information for NAND module.
994 * @param ECCval: pointer to ECC value
995 * @param Timeout: maximum timeout to wait
998 HAL_StatusTypeDef
HAL_NAND_GetECC(NAND_HandleTypeDef
*hnand
, uint32_t *ECCval
, uint32_t Timeout
)
1000 HAL_StatusTypeDef status
= HAL_OK
;
1002 /* Check the NAND controller state */
1003 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1008 /* Update the NAND state */
1009 hnand
->State
= HAL_NAND_STATE_BUSY
;
1011 /* Get NAND ECC value */
1012 status
= FMC_NAND_GetECC(hnand
->Instance
, ECCval
, hnand
->Init
.NandBank
, Timeout
);
1014 /* Update the NAND state */
1015 hnand
->State
= HAL_NAND_STATE_READY
;
1025 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1026 * @brief Peripheral State functions
1029 ==============================================================================
1030 ##### NAND State functions #####
1031 ==============================================================================
1033 This subsection permits to get in run-time the status of the NAND controller
1041 * @brief return the NAND state
1042 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1043 * the configuration information for NAND module.
1046 HAL_NAND_StateTypeDef
HAL_NAND_GetState(NAND_HandleTypeDef
*hnand
)
1048 return hnand
->State
;
1058 #endif /* STM32F302xE || STM32F303xE || STM32F398xx */
1059 #endif /* HAL_NAND_MODULE_ENABLED */
1069 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/