2 ******************************************************************************
3 * @file stm32f7xx_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_8b()/HAL_NAND_Read_SpareArea_8b(),
29 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
30 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
31 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
32 to read/write page(s)/spare area(s). These functions use specific device
33 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
34 structure. The read/write address information is contained by the Nand_Address_Typedef
35 structure passed as parameter.
37 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
39 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
40 The erase block address information is contained in the Nand_Address_Typedef
41 structure passed as parameter.
43 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
45 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
46 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
47 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
49 (+) You can monitor the NAND device HAL state by calling the function
53 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
54 If a NAND flash device contains different operations and/or implementations,
55 it should be implemented separately.
58 ******************************************************************************
61 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
63 * Redistribution and use in source and binary forms, with or without modification,
64 * are permitted provided that the following conditions are met:
65 * 1. Redistributions of source code must retain the above copyright notice,
66 * this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright notice,
68 * this list of conditions and the following disclaimer in the documentation
69 * and/or other materials provided with the distribution.
70 * 3. Neither the name of STMicroelectronics nor the names of its contributors
71 * may be used to endorse or promote products derived from this software
72 * without specific prior written permission.
74 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
75 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
78 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
80 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
81 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
82 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 ******************************************************************************
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32f7xx_hal.h"
91 /** @addtogroup STM32F7xx_HAL_Driver
96 #ifdef HAL_NAND_MODULE_ENABLED
98 /** @defgroup NAND NAND
99 * @brief NAND HAL module driver
103 /* Private typedef -----------------------------------------------------------*/
104 /* Private Constants ------------------------------------------------------------*/
105 /* Private macro -------------------------------------------------------------*/
106 /* Private variables ---------------------------------------------------------*/
107 /* Private function prototypes -----------------------------------------------*/
108 /* Exported functions ---------------------------------------------------------*/
110 /** @defgroup NAND_Exported_Functions NAND Exported Functions
114 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
115 * @brief Initialization and Configuration functions
118 ==============================================================================
119 ##### NAND Initialization and de-initialization functions #####
120 ==============================================================================
122 This section provides functions allowing to initialize/de-initialize
130 * @brief Perform NAND memory Initialization sequence
131 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
132 * the configuration information for NAND module.
133 * @param ComSpace_Timing: pointer to Common space timing structure
134 * @param AttSpace_Timing: pointer to Attribute space timing structure
137 HAL_StatusTypeDef
HAL_NAND_Init(NAND_HandleTypeDef
*hnand
, FMC_NAND_PCC_TimingTypeDef
*ComSpace_Timing
, FMC_NAND_PCC_TimingTypeDef
*AttSpace_Timing
)
139 /* Check the NAND handle state */
145 if(hnand
->State
== HAL_NAND_STATE_RESET
)
147 /* Allocate lock resource and initialize it */
148 hnand
->Lock
= HAL_UNLOCKED
;
149 /* Initialize the low level hardware (MSP) */
150 HAL_NAND_MspInit(hnand
);
153 /* Initialize NAND control Interface */
154 FMC_NAND_Init(hnand
->Instance
, &(hnand
->Init
));
156 /* Initialize NAND common space timing Interface */
157 FMC_NAND_CommonSpace_Timing_Init(hnand
->Instance
, ComSpace_Timing
, hnand
->Init
.NandBank
);
159 /* Initialize NAND attribute space timing Interface */
160 FMC_NAND_AttributeSpace_Timing_Init(hnand
->Instance
, AttSpace_Timing
, hnand
->Init
.NandBank
);
162 /* Enable the NAND device */
163 __FMC_NAND_ENABLE(hnand
->Instance
);
165 /* Update the NAND controller state */
166 hnand
->State
= HAL_NAND_STATE_READY
;
172 * @brief Perform NAND memory De-Initialization sequence
173 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
174 * the configuration information for NAND module.
177 HAL_StatusTypeDef
HAL_NAND_DeInit(NAND_HandleTypeDef
*hnand
)
179 /* Initialize the low level hardware (MSP) */
180 HAL_NAND_MspDeInit(hnand
);
182 /* Configure the NAND registers with their reset values */
183 FMC_NAND_DeInit(hnand
->Instance
, hnand
->Init
.NandBank
);
185 /* Reset the NAND controller state */
186 hnand
->State
= HAL_NAND_STATE_RESET
;
195 * @brief NAND MSP Init
196 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
197 * the configuration information for NAND module.
200 __weak
void HAL_NAND_MspInit(NAND_HandleTypeDef
*hnand
)
202 /* Prevent unused argument(s) compilation warning */
205 /* NOTE : This function Should not be modified, when the callback is needed,
206 the HAL_NAND_MspInit could be implemented in the user file
211 * @brief NAND MSP DeInit
212 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
213 * the configuration information for NAND module.
216 __weak
void HAL_NAND_MspDeInit(NAND_HandleTypeDef
*hnand
)
218 /* Prevent unused argument(s) compilation warning */
221 /* NOTE : This function Should not be modified, when the callback is needed,
222 the HAL_NAND_MspDeInit could be implemented in the user file
228 * @brief This function handles NAND device interrupt request.
229 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
230 * the configuration information for NAND module.
233 void HAL_NAND_IRQHandler(NAND_HandleTypeDef
*hnand
)
235 /* Check NAND interrupt Rising edge flag */
236 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_RISING_EDGE
))
238 /* NAND interrupt callback*/
239 HAL_NAND_ITCallback(hnand
);
241 /* Clear NAND interrupt Rising edge pending bit */
242 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_RISING_EDGE
);
245 /* Check NAND interrupt Level flag */
246 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_LEVEL
))
248 /* NAND interrupt callback*/
249 HAL_NAND_ITCallback(hnand
);
251 /* Clear NAND interrupt Level pending bit */
252 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_LEVEL
);
255 /* Check NAND interrupt Falling edge flag */
256 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FALLING_EDGE
))
258 /* NAND interrupt callback*/
259 HAL_NAND_ITCallback(hnand
);
261 /* Clear NAND interrupt Falling edge pending bit */
262 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_FALLING_EDGE
);
265 /* Check NAND interrupt FIFO empty flag */
266 if(__FMC_NAND_GET_FLAG(hnand
->Instance
, hnand
->Init
.NandBank
, FMC_FLAG_FEMPT
))
268 /* NAND interrupt callback*/
269 HAL_NAND_ITCallback(hnand
);
271 /* Clear NAND interrupt FIFO empty pending bit */
272 __FMC_NAND_CLEAR_FLAG(hnand
->Instance
, FMC_FLAG_FEMPT
);
278 * @brief NAND interrupt feature callback
279 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
280 * the configuration information for NAND module.
283 __weak
void HAL_NAND_ITCallback(NAND_HandleTypeDef
*hnand
)
285 /* Prevent unused argument(s) compilation warning */
288 /* NOTE : This function Should not be modified, when the callback is needed,
289 the HAL_NAND_ITCallback could be implemented in the user file
297 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
298 * @brief Input Output and memory control functions
301 ==============================================================================
302 ##### NAND Input and Output functions #####
303 ==============================================================================
305 This section provides functions allowing to use and control the NAND
313 * @brief Read the NAND memory electronic signature
314 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
315 * the configuration information for NAND module.
316 * @param pNAND_ID: NAND ID structure
319 HAL_StatusTypeDef
HAL_NAND_Read_ID(NAND_HandleTypeDef
*hnand
, NAND_IDTypeDef
*pNAND_ID
)
321 __IO
uint32_t data
= 0;
322 __IO
uint32_t data1
= 0;
323 uint32_t deviceAddress
= 0;
328 /* Check the NAND controller state */
329 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
334 /* Identify the device address */
335 deviceAddress
= NAND_DEVICE
;
337 /* Update the NAND controller state */
338 hnand
->State
= HAL_NAND_STATE_BUSY
;
340 /* Send Read ID command sequence */
341 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_READID
;
343 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
346 /* Read the electronic signature from NAND flash */
347 if (hnand
->Init
.MemoryDataWidth
== FMC_NAND_PCC_MEM_BUS_WIDTH_8
)
349 data
= *(__IO
uint32_t *)deviceAddress
;
351 /* Return the data read */
352 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
353 pNAND_ID
->Device_Id
= ADDR_2ND_CYCLE(data
);
354 pNAND_ID
->Third_Id
= ADDR_3RD_CYCLE(data
);
355 pNAND_ID
->Fourth_Id
= ADDR_4TH_CYCLE(data
);
359 data
= *(__IO
uint32_t *)deviceAddress
;
360 data1
= *((__IO
uint32_t *)deviceAddress
+ 4);
362 /* Return the data read */
363 pNAND_ID
->Maker_Id
= ADDR_1ST_CYCLE(data
);
364 pNAND_ID
->Device_Id
= ADDR_3RD_CYCLE(data
);
365 pNAND_ID
->Third_Id
= ADDR_1ST_CYCLE(data1
);
366 pNAND_ID
->Fourth_Id
= ADDR_3RD_CYCLE(data1
);
369 /* Update the NAND controller state */
370 hnand
->State
= HAL_NAND_STATE_READY
;
372 /* Process unlocked */
379 * @brief NAND memory reset
380 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
381 * the configuration information for NAND module.
384 HAL_StatusTypeDef
HAL_NAND_Reset(NAND_HandleTypeDef
*hnand
)
386 uint32_t deviceAddress
= 0;
391 /* Check the NAND controller state */
392 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
397 /* Identify the device address */
398 deviceAddress
= NAND_DEVICE
;
400 /* Update the NAND controller state */
401 hnand
->State
= HAL_NAND_STATE_BUSY
;
403 /* Send NAND reset command */
404 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = 0xFF;
406 /* Update the NAND controller state */
407 hnand
->State
= HAL_NAND_STATE_READY
;
409 /* Process unlocked */
417 * @brief Configure the device: Enter the physical parameters of the device
418 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
419 * the configuration information for NAND module.
420 * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
423 HAL_StatusTypeDef
HAL_NAND_ConfigDevice(NAND_HandleTypeDef
*hnand
, NAND_DeviceConfigTypeDef
*pDeviceConfig
)
425 hnand
->Config
.PageSize
= pDeviceConfig
->PageSize
;
426 hnand
->Config
.SpareAreaSize
= pDeviceConfig
->SpareAreaSize
;
427 hnand
->Config
.BlockSize
= pDeviceConfig
->BlockSize
;
428 hnand
->Config
.BlockNbr
= pDeviceConfig
->BlockNbr
;
429 hnand
->Config
.PlaneSize
= pDeviceConfig
->PlaneSize
;
430 hnand
->Config
.PlaneNbr
= pDeviceConfig
->PlaneNbr
;
431 hnand
->Config
.ExtraCommandEnable
= pDeviceConfig
->ExtraCommandEnable
;
438 * @brief Read Page(s) from NAND memory block (8-bits addressing)
439 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
440 * the configuration information for NAND module.
441 * @param pAddress : pointer to NAND address structure
442 * @param pBuffer : pointer to destination read buffer
443 * @param NumPageToRead : number of pages to read from block
446 HAL_StatusTypeDef
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToRead
)
448 __IO
uint32_t index
= 0;
449 uint32_t tickstart
= 0U;
450 uint32_t deviceAddress
= 0, size
= 0, numPagesRead
= 0, nandAddress
= 0;
455 /* Check the NAND controller state */
456 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
461 /* Identify the device address */
462 deviceAddress
= NAND_DEVICE
;
464 /* Update the NAND controller state */
465 hnand
->State
= HAL_NAND_STATE_BUSY
;
467 /* NAND raw address calculation */
468 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
470 /* Page(s) read loop */
471 while((NumPageToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
473 /* update the buffer size */
474 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
476 /* Send read page command sequence */
477 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
480 /* Cards with page size <= 512 bytes */
481 if((hnand
->Config
.PageSize
) <= 512)
483 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
485 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
487 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
489 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
492 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
494 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
496 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
498 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
500 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
504 else /* (hnand->Config.PageSize) > 512 */
506 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
508 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
510 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
512 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
514 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
517 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
519 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
521 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
523 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
525 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
527 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
532 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
536 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
539 tickstart
= HAL_GetTick();
541 /* Read status until NAND is ready */
542 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
544 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
550 /* Go back to read mode */
551 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
555 /* Get Data into Buffer */
556 for(; index
< size
; index
++)
558 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
561 /* Increment read pages number */
564 /* Decrement pages to read */
567 /* Increment the NAND address */
568 nandAddress
= (uint32_t)(nandAddress
+ 1);
571 /* Update the NAND controller state */
572 hnand
->State
= HAL_NAND_STATE_READY
;
574 /* Process unlocked */
582 * @brief Read Page(s) from NAND memory block (16-bits addressing)
583 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
584 * the configuration information for NAND module.
585 * @param pAddress : pointer to NAND address structure
586 * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
587 * @param NumPageToRead : number of pages to read from block
590 HAL_StatusTypeDef
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToRead
)
592 __IO
uint32_t index
= 0;
593 uint32_t tickstart
= 0;
594 uint32_t deviceAddress
= 0, size
= 0, numPagesRead
= 0, nandAddress
= 0;
599 /* Check the NAND controller state */
600 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
605 /* Identify the device address */
606 deviceAddress
= NAND_DEVICE
;
608 /* Update the NAND controller state */
609 hnand
->State
= HAL_NAND_STATE_BUSY
;
611 /* NAND raw address calculation */
612 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
614 /* Page(s) read loop */
615 while((NumPageToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
617 /* update the buffer size */
618 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesRead
);
620 /* Send read page command sequence */
621 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
624 /* Cards with page size <= 512 bytes */
625 if((hnand
->Config
.PageSize
) <= 512)
627 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
629 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
631 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
633 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
636 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
638 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
640 *(__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
);
644 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
648 else /* (hnand->Config.PageSize) > 512 */
650 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
652 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
654 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
656 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
658 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
661 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
663 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
665 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
667 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
669 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
671 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
676 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
679 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
682 tickstart
= HAL_GetTick();
684 /* Read status until NAND is ready */
685 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
687 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
693 /* Go back to read mode */
694 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
698 /* Get Data into Buffer */
699 for(; index
< size
; index
++)
701 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceAddress
;
704 /* Increment read pages number */
707 /* Decrement pages to read */
710 /* Increment the NAND address */
711 nandAddress
= (uint32_t)(nandAddress
+ 1);
714 /* Update the NAND controller state */
715 hnand
->State
= HAL_NAND_STATE_READY
;
717 /* Process unlocked */
724 * @brief Write Page(s) to NAND memory block (8-bits addressing)
725 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
726 * the configuration information for NAND module.
727 * @param pAddress : pointer to NAND address structure
728 * @param pBuffer : pointer to source buffer to write
729 * @param NumPageToWrite : number of pages to write to block
732 HAL_StatusTypeDef
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumPageToWrite
)
734 __IO
uint32_t index
= 0;
735 uint32_t tickstart
= 0;
736 uint32_t deviceAddress
= 0, size
= 0, numPagesWritten
= 0, nandAddress
= 0;
741 /* Check the NAND controller state */
742 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
747 /* Identify the device address */
748 deviceAddress
= NAND_DEVICE
;
750 /* Update the NAND controller state */
751 hnand
->State
= HAL_NAND_STATE_BUSY
;
753 /* NAND raw address calculation */
754 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
756 /* Page(s) write loop */
757 while((NumPageToWrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
759 /* update the buffer size */
760 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
762 /* Send write page command sequence */
763 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
765 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
768 /* Cards with page size <= 512 bytes */
769 if((hnand
->Config
.PageSize
) <= 512)
771 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
773 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
775 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
777 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
780 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
782 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
784 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
786 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
788 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
792 else /* (hnand->Config.PageSize) > 512 */
794 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
796 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
798 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
800 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
802 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
805 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
807 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
809 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
811 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
813 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
815 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
820 /* Write data to memory */
821 for(; index
< size
; index
++)
823 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
827 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
830 /* Read status until NAND is ready */
831 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
834 tickstart
= HAL_GetTick();
836 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
842 /* Increment written pages number */
845 /* Decrement pages to write */
848 /* Increment the NAND address */
849 nandAddress
= (uint32_t)(nandAddress
+ 1);
852 /* Update the NAND controller state */
853 hnand
->State
= HAL_NAND_STATE_READY
;
855 /* Process unlocked */
862 * @brief Write Page(s) to NAND memory block (16-bits addressing)
863 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
864 * the configuration information for NAND module.
865 * @param pAddress : pointer to NAND address structure
866 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
867 * @param NumPageToWrite : number of pages to write to block
870 HAL_StatusTypeDef
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumPageToWrite
)
872 __IO
uint32_t index
= 0;
873 uint32_t tickstart
= 0;
874 uint32_t deviceAddress
= 0, size
= 0, numPagesWritten
= 0, nandAddress
= 0;
879 /* Check the NAND controller state */
880 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
885 /* Identify the device address */
886 deviceAddress
= NAND_DEVICE
;
888 /* Update the NAND controller state */
889 hnand
->State
= HAL_NAND_STATE_BUSY
;
891 /* NAND raw address calculation */
892 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
894 /* Page(s) write loop */
895 while((NumPageToWrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
897 /* update the buffer size */
898 size
= (hnand
->Config
.PageSize
) + ((hnand
->Config
.PageSize
) * numPagesWritten
);
900 /* Send write page command sequence */
901 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
903 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
906 /* Cards with page size <= 512 bytes */
907 if((hnand
->Config
.PageSize
) <= 512)
909 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
911 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
913 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
915 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
918 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
920 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
922 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
924 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
926 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
930 else /* (hnand->Config.PageSize) > 512 */
932 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
934 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
936 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
938 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
940 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
943 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
945 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
947 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
949 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
951 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
953 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
958 /* Write data to memory */
959 for(; index
< size
; index
++)
961 *(__IO
uint16_t *)deviceAddress
= *(uint16_t *)pBuffer
++;
965 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
968 /* Read status until NAND is ready */
969 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
972 tickstart
= HAL_GetTick();
974 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
980 /* Increment written pages number */
983 /* Decrement pages to write */
986 /* Increment the NAND address */
987 nandAddress
= (uint32_t)(nandAddress
+ 1);
990 /* Update the NAND controller state */
991 hnand
->State
= HAL_NAND_STATE_READY
;
993 /* Process unlocked */
1000 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
1001 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1002 * the configuration information for NAND module.
1003 * @param pAddress : pointer to NAND address structure
1004 * @param pBuffer: pointer to source buffer to write
1005 * @param NumSpareAreaToRead: Number of spare area to read
1006 * @retval HAL status
1008 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1010 __IO
uint32_t index
= 0;
1011 uint32_t tickstart
= 0U;
1012 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaRead
= 0, nandAddress
= 0, columnAddress
= 0;
1014 /* Process Locked */
1017 /* Check the NAND controller state */
1018 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1023 /* Identify the device address */
1024 deviceAddress
= NAND_DEVICE
;
1026 /* Update the NAND controller state */
1027 hnand
->State
= HAL_NAND_STATE_BUSY
;
1029 /* NAND raw address calculation */
1030 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1032 /* Column in page address */
1033 columnAddress
= COLUMN_ADDRESS(hnand
);
1035 /* Spare area(s) read loop */
1036 while((NumSpareAreaToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1038 /* update the buffer size */
1039 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1041 /* Cards with page size <= 512 bytes */
1042 if((hnand
->Config
.PageSize
) <= 512)
1044 /* Send read spare area command sequence */
1045 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1048 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1050 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1052 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1054 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1057 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1059 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1061 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1063 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1065 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1069 else /* (hnand->Config.PageSize) > 512 */
1071 /* Send read spare area command sequence */
1072 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1075 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1077 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1079 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1081 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1083 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1086 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1088 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1090 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1092 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1094 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1096 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1101 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1104 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1107 tickstart
= HAL_GetTick();
1109 /* Read status until NAND is ready */
1110 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1112 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1118 /* Go back to read mode */
1119 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
1123 /* Get Data into Buffer */
1124 for(; index
< size
; index
++)
1126 *(uint8_t *)pBuffer
++ = *(uint8_t *)deviceAddress
;
1129 /* Increment read spare areas number */
1132 /* Decrement spare areas to read */
1133 NumSpareAreaToRead
--;
1135 /* Increment the NAND address */
1136 nandAddress
= (uint32_t)(nandAddress
+ 1);
1139 /* Update the NAND controller state */
1140 hnand
->State
= HAL_NAND_STATE_READY
;
1142 /* Process unlocked */
1143 __HAL_UNLOCK(hnand
);
1149 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1150 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1151 * the configuration information for NAND module.
1152 * @param pAddress : pointer to NAND address structure
1153 * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
1154 * @param NumSpareAreaToRead: Number of spare area to read
1155 * @retval HAL status
1157 HAL_StatusTypeDef
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaToRead
)
1159 __IO
uint32_t index
= 0;
1160 uint32_t tickstart
= 0U;
1161 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaRead
= 0, nandAddress
= 0, columnAddress
= 0;
1163 /* Process Locked */
1166 /* Check the NAND controller state */
1167 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1172 /* Identify the device address */
1173 deviceAddress
= NAND_DEVICE
;
1175 /* Update the NAND controller state */
1176 hnand
->State
= HAL_NAND_STATE_BUSY
;
1178 /* NAND raw address calculation */
1179 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1181 /* Column in page address */
1182 columnAddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2);
1184 /* Spare area(s) read loop */
1185 while((NumSpareAreaToRead
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1187 /* update the buffer size */
1188 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaRead
);
1190 /* Cards with page size <= 512 bytes */
1191 if((hnand
->Config
.PageSize
) <= 512)
1193 /* Send read spare area command sequence */
1194 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1197 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1199 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1201 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1203 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1206 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1208 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1210 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1212 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1214 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1218 else /* (hnand->Config.PageSize) > 512 */
1220 /* Send read spare area command sequence */
1221 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1224 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1226 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1228 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1230 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1232 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1235 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1237 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1239 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1241 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1243 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1245 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1250 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_TRUE1
;
1253 if(hnand
->Config
.ExtraCommandEnable
== ENABLE
)
1256 tickstart
= HAL_GetTick();
1258 /* Read status until NAND is ready */
1259 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1261 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1267 /* Go back to read mode */
1268 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = ((uint8_t)0x00U
);
1272 /* Get Data into Buffer */
1273 for(; index
< size
; index
++)
1275 *(uint16_t *)pBuffer
++ = *(uint16_t *)deviceAddress
;
1278 /* Increment read spare areas number */
1281 /* Decrement spare areas to read */
1282 NumSpareAreaToRead
--;
1284 /* Increment the NAND address */
1285 nandAddress
= (uint32_t)(nandAddress
+ 1);
1288 /* Update the NAND controller state */
1289 hnand
->State
= HAL_NAND_STATE_READY
;
1291 /* Process unlocked */
1292 __HAL_UNLOCK(hnand
);
1298 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1299 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1300 * the configuration information for NAND module.
1301 * @param pAddress : pointer to NAND address structure
1302 * @param pBuffer : pointer to source buffer to write
1303 * @param NumSpareAreaTowrite : number of spare areas to write to block
1304 * @retval HAL status
1306 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint8_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1308 __IO
uint32_t index
= 0;
1309 uint32_t tickstart
= 0;
1310 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaWritten
= 0, nandAddress
= 0, columnAddress
=0;
1312 /* Process Locked */
1315 /* Check the NAND controller state */
1316 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1321 /* Identify the device address */
1322 deviceAddress
= NAND_DEVICE
;
1324 /* Update the FMC_NAND controller state */
1325 hnand
->State
= HAL_NAND_STATE_BUSY
;
1327 /* Page address calculation */
1328 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1330 /* Column in page address */
1331 columnAddress
= COLUMN_ADDRESS(hnand
);
1333 /* Spare area(s) write loop */
1334 while((NumSpareAreaTowrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1336 /* update the buffer size */
1337 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1339 /* Cards with page size <= 512 bytes */
1340 if((hnand
->Config
.PageSize
) <= 512)
1342 /* Send write Spare area command sequence */
1343 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1345 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1348 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1350 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1352 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1354 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1357 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1359 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1361 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1363 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1365 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1369 else /* (hnand->Config.PageSize) > 512 */
1371 /* Send write Spare area command sequence */
1372 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1374 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1377 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1379 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1381 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1383 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1385 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1388 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1390 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1392 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1394 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1396 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1398 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1403 /* Write data to memory */
1404 for(; index
< size
; index
++)
1406 *(__IO
uint8_t *)deviceAddress
= *(uint8_t *)pBuffer
++;
1410 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1413 /* Read status until NAND is ready */
1414 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1417 tickstart
= HAL_GetTick();
1419 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1425 /* Increment written spare areas number */
1426 numSpareAreaWritten
++;
1428 /* Decrement spare areas to write */
1429 NumSpareAreaTowrite
--;
1431 /* Increment the NAND address */
1432 nandAddress
= (uint32_t)(nandAddress
+ 1);
1435 /* Update the NAND controller state */
1436 hnand
->State
= HAL_NAND_STATE_READY
;
1438 /* Process unlocked */
1439 __HAL_UNLOCK(hnand
);
1445 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1446 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1447 * the configuration information for NAND module.
1448 * @param pAddress : pointer to NAND address structure
1449 * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
1450 * @param NumSpareAreaTowrite : number of spare areas to write to block
1451 * @retval HAL status
1453 HAL_StatusTypeDef
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
, uint16_t *pBuffer
, uint32_t NumSpareAreaTowrite
)
1455 __IO
uint32_t index
= 0;
1456 uint32_t tickstart
= 0;
1457 uint32_t deviceAddress
= 0, size
= 0, numSpareAreaWritten
= 0, nandAddress
= 0, columnAddress
= 0;
1459 /* Process Locked */
1462 /* Check the NAND controller state */
1463 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1468 /* Identify the device address */
1469 deviceAddress
= NAND_DEVICE
;
1471 /* Update the FMC_NAND controller state */
1472 hnand
->State
= HAL_NAND_STATE_BUSY
;
1474 /* NAND raw address calculation */
1475 nandAddress
= ARRAY_ADDRESS(pAddress
, hnand
);
1477 /* Column in page address */
1478 columnAddress
= (uint32_t)(COLUMN_ADDRESS(hnand
) * 2);
1480 /* Spare area(s) write loop */
1481 while((NumSpareAreaTowrite
!= 0) && (nandAddress
< ((hnand
->Config
.BlockSize
) * (hnand
->Config
.BlockNbr
))))
1483 /* update the buffer size */
1484 size
= (hnand
->Config
.SpareAreaSize
) + ((hnand
->Config
.SpareAreaSize
) * numSpareAreaWritten
);
1486 /* Cards with page size <= 512 bytes */
1487 if((hnand
->Config
.PageSize
) <= 512)
1489 /* Send write Spare area command sequence */
1490 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_C
;
1492 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1495 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1497 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1499 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1501 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1504 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1506 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = 0x00;
1508 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1510 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1512 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1516 else /* (hnand->Config.PageSize) > 512 */
1518 /* Send write Spare area command sequence */
1519 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_AREA_A
;
1521 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE0
;
1524 if (((hnand
->Config
.BlockSize
)*(hnand
->Config
.BlockNbr
)) <= 65535)
1526 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1528 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1530 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1532 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1535 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1537 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_1ST_CYCLE(columnAddress
);
1539 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = COLUMN_2ND_CYCLE(columnAddress
);
1541 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(nandAddress
);
1543 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(nandAddress
);
1545 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(nandAddress
);
1550 /* Write data to memory */
1551 for(; index
< size
; index
++)
1553 *(__IO
uint16_t *)deviceAddress
= *(uint16_t *)pBuffer
++;
1557 *(__IO
uint8_t *)((uint32_t)(deviceAddress
| CMD_AREA
)) = NAND_CMD_WRITE_TRUE1
;
1560 /* Read status until NAND is ready */
1561 while(HAL_NAND_Read_Status(hnand
) != NAND_READY
)
1564 tickstart
= HAL_GetTick();
1566 if((HAL_GetTick() - tickstart
) > NAND_WRITE_TIMEOUT
)
1572 /* Increment written spare areas number */
1573 numSpareAreaWritten
++;
1575 /* Decrement spare areas to write */
1576 NumSpareAreaTowrite
--;
1578 /* Increment the NAND address */
1579 nandAddress
= (uint32_t)(nandAddress
+ 1);
1582 /* Update the NAND controller state */
1583 hnand
->State
= HAL_NAND_STATE_READY
;
1585 /* Process unlocked */
1586 __HAL_UNLOCK(hnand
);
1592 * @brief NAND memory Block erase
1593 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1594 * the configuration information for NAND module.
1595 * @param pAddress : pointer to NAND address structure
1596 * @retval HAL status
1598 HAL_StatusTypeDef
HAL_NAND_Erase_Block(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1600 uint32_t DeviceAddress
= 0;
1602 /* Process Locked */
1605 /* Check the NAND controller state */
1606 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1611 /* Identify the device address */
1612 DeviceAddress
= NAND_DEVICE
;
1614 /* Update the NAND controller state */
1615 hnand
->State
= HAL_NAND_STATE_BUSY
;
1617 /* Send Erase block command sequence */
1618 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_ERASE0
;
1620 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1622 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1624 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| ADDR_AREA
)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress
, hnand
));
1627 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_ERASE1
;
1630 /* Update the NAND controller state */
1631 hnand
->State
= HAL_NAND_STATE_READY
;
1633 /* Process unlocked */
1634 __HAL_UNLOCK(hnand
);
1640 * @brief Increment the NAND memory address
1641 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1642 * the configuration information for NAND module.
1643 * @param pAddress: pointer to NAND address structure
1644 * @retval The new status of the increment address operation. It can be:
1645 * - NAND_VALID_ADDRESS: When the new address is valid address
1646 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1648 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef
*hnand
, NAND_AddressTypeDef
*pAddress
)
1650 uint32_t status
= NAND_VALID_ADDRESS
;
1652 /* Increment page address */
1655 /* Check NAND address is valid */
1656 if(pAddress
->Page
== hnand
->Config
.BlockSize
)
1661 if(pAddress
->Block
== hnand
->Config
.PlaneSize
)
1663 pAddress
->Block
= 0;
1666 if(pAddress
->Plane
== (hnand
->Config
.PlaneNbr
))
1668 status
= NAND_INVALID_ADDRESS
;
1679 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1680 * @brief management functions
1683 ==============================================================================
1684 ##### NAND Control functions #####
1685 ==============================================================================
1687 This subsection provides a set of functions allowing to control dynamically
1696 * @brief Enables dynamically NAND ECC feature.
1697 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1698 * the configuration information for NAND module.
1699 * @retval HAL status
1701 HAL_StatusTypeDef
HAL_NAND_ECC_Enable(NAND_HandleTypeDef
*hnand
)
1703 /* Check the NAND controller state */
1704 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1709 /* Update the NAND state */
1710 hnand
->State
= HAL_NAND_STATE_BUSY
;
1712 /* Enable ECC feature */
1713 FMC_NAND_ECC_Enable(hnand
->Instance
, hnand
->Init
.NandBank
);
1715 /* Update the NAND state */
1716 hnand
->State
= HAL_NAND_STATE_READY
;
1722 * @brief Disables dynamically FMC_NAND ECC feature.
1723 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1724 * the configuration information for NAND module.
1725 * @retval HAL status
1727 HAL_StatusTypeDef
HAL_NAND_ECC_Disable(NAND_HandleTypeDef
*hnand
)
1729 /* Check the NAND controller state */
1730 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1735 /* Update the NAND state */
1736 hnand
->State
= HAL_NAND_STATE_BUSY
;
1738 /* Disable ECC feature */
1739 FMC_NAND_ECC_Disable(hnand
->Instance
, hnand
->Init
.NandBank
);
1741 /* Update the NAND state */
1742 hnand
->State
= HAL_NAND_STATE_READY
;
1748 * @brief Disables dynamically NAND ECC feature.
1749 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1750 * the configuration information for NAND module.
1751 * @param ECCval: pointer to ECC value
1752 * @param Timeout: maximum timeout to wait
1753 * @retval HAL status
1755 HAL_StatusTypeDef
HAL_NAND_GetECC(NAND_HandleTypeDef
*hnand
, uint32_t *ECCval
, uint32_t Timeout
)
1757 HAL_StatusTypeDef status
= HAL_OK
;
1759 /* Check the NAND controller state */
1760 if(hnand
->State
== HAL_NAND_STATE_BUSY
)
1765 /* Update the NAND state */
1766 hnand
->State
= HAL_NAND_STATE_BUSY
;
1768 /* Get NAND ECC value */
1769 status
= FMC_NAND_GetECC(hnand
->Instance
, ECCval
, hnand
->Init
.NandBank
, Timeout
);
1771 /* Update the NAND state */
1772 hnand
->State
= HAL_NAND_STATE_READY
;
1782 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1783 * @brief Peripheral State functions
1786 ==============================================================================
1787 ##### NAND State functions #####
1788 ==============================================================================
1790 This subsection permits to get in run-time the status of the NAND controller
1798 * @brief return the NAND state
1799 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1800 * the configuration information for NAND module.
1803 HAL_NAND_StateTypeDef
HAL_NAND_GetState(NAND_HandleTypeDef
*hnand
)
1805 return hnand
->State
;
1809 * @brief NAND memory read status
1810 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1811 * the configuration information for NAND module.
1812 * @retval NAND status
1814 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef
*hnand
)
1817 uint32_t DeviceAddress
= 0;
1819 /* Identify the device address */
1820 DeviceAddress
= NAND_DEVICE
;
1822 /* Send Read status operation command */
1823 *(__IO
uint8_t *)((uint32_t)(DeviceAddress
| CMD_AREA
)) = NAND_CMD_STATUS
;
1825 /* Read status register data */
1826 data
= *(__IO
uint8_t *)DeviceAddress
;
1828 /* Return the status */
1829 if((data
& NAND_ERROR
) == NAND_ERROR
)
1833 else if((data
& NAND_READY
) == NAND_READY
)
1849 #endif /* HAL_NAND_MODULE_ENABLED */
1859 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/