2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_nand.c
\r
4 * @author MCD Application Team
\r
6 * @date 24-March-2015
\r
7 * @brief NAND HAL module driver.
\r
8 * This file provides a generic firmware to drive NAND memories mounted
\r
9 * as external device.
\r
12 ==============================================================================
\r
13 ##### How to use this driver #####
\r
14 ==============================================================================
\r
16 This driver is a generic layered driver which contains a set of APIs used to
\r
17 control NAND flash memories. It uses the FMC/FSMC layer functions to interface
\r
18 with NAND devices. This driver is used as follows:
\r
20 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
\r
21 with control and timing parameters for both common and attribute spaces.
\r
23 (+) Read NAND flash memory maker and device IDs using the function
\r
24 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
\r
25 structure declared by the function caller.
\r
27 (+) Access NAND flash memory by read/write operations using the functions
\r
28 HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
\r
29 to read/write page(s)/spare area(s). These functions use specific device
\r
30 information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
\r
31 structure. The read/write address information is contained by the Nand_Address_Typedef
\r
32 structure passed as parameter.
\r
34 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
\r
36 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
\r
37 The erase block address information is contained in the Nand_Address_Typedef
\r
38 structure passed as parameter.
\r
40 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
\r
42 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
\r
43 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
\r
44 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
\r
46 (+) You can monitor the NAND device HAL state by calling the function
\r
47 HAL_NAND_GetState()
\r
50 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
\r
51 If a NAND flash device contains different operations and/or implementations,
\r
52 it should be implemented separately.
\r
55 ******************************************************************************
\r
58 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
60 * Redistribution and use in source and binary forms, with or without modification,
\r
61 * are permitted provided that the following conditions are met:
\r
62 * 1. Redistributions of source code must retain the above copyright notice,
\r
63 * this list of conditions and the following disclaimer.
\r
64 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
65 * this list of conditions and the following disclaimer in the documentation
\r
66 * and/or other materials provided with the distribution.
\r
67 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
68 * may be used to endorse or promote products derived from this software
\r
69 * without specific prior written permission.
\r
71 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
72 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
73 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
74 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
75 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
76 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
78 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
79 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
80 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
82 ******************************************************************************
\r
85 /* Includes ------------------------------------------------------------------*/
\r
86 #include "stm32f7xx_hal.h"
\r
88 /** @addtogroup STM32F7xx_HAL_Driver
\r
93 #ifdef HAL_NAND_MODULE_ENABLED
\r
95 #if defined(STM32F756xx) || defined(STM32F746xx)
\r
97 /** @defgroup NAND NAND
\r
98 * @brief NAND HAL module driver
\r
102 /* Private typedef -----------------------------------------------------------*/
\r
103 /* Private Constants ------------------------------------------------------------*/
\r
104 /* Private macro -------------------------------------------------------------*/
\r
105 /* Private variables ---------------------------------------------------------*/
\r
106 /* Private function prototypes -----------------------------------------------*/
\r
107 /* Exported functions ---------------------------------------------------------*/
\r
109 /** @defgroup NAND_Exported_Functions NAND Exported Functions
\r
113 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
\r
114 * @brief Initialization and Configuration functions
\r
117 ==============================================================================
\r
118 ##### NAND Initialization and de-initialization functions #####
\r
119 ==============================================================================
\r
121 This section provides functions allowing to initialize/de-initialize
\r
129 * @brief Perform NAND memory Initialization sequence
\r
130 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
131 * the configuration information for NAND module.
\r
132 * @param ComSpace_Timing: pointer to Common space timing structure
\r
133 * @param AttSpace_Timing: pointer to Attribute space timing structure
\r
134 * @retval HAL status
\r
136 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
\r
138 /* Check the NAND handle state */
\r
144 if(hnand->State == HAL_NAND_STATE_RESET)
\r
146 /* Initialize the low level hardware (MSP) */
\r
147 HAL_NAND_MspInit(hnand);
\r
150 /* Initialize NAND control Interface */
\r
151 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
\r
153 /* Initialize NAND common space timing Interface */
\r
154 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
\r
156 /* Initialize NAND attribute space timing Interface */
\r
157 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
\r
159 /* Enable the NAND device */
\r
160 __FMC_NAND_ENABLE(hnand->Instance);
\r
162 /* Update the NAND controller state */
\r
163 hnand->State = HAL_NAND_STATE_READY;
\r
169 * @brief Perform NAND memory De-Initialization sequence
\r
170 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
171 * the configuration information for NAND module.
\r
172 * @retval HAL status
\r
174 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
\r
176 /* Initialize the low level hardware (MSP) */
\r
177 HAL_NAND_MspDeInit(hnand);
\r
179 /* Configure the NAND registers with their reset values */
\r
180 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
\r
182 /* Reset the NAND controller state */
\r
183 hnand->State = HAL_NAND_STATE_RESET;
\r
186 __HAL_UNLOCK(hnand);
\r
192 * @brief NAND MSP Init
\r
193 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
194 * the configuration information for NAND module.
\r
197 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
\r
199 /* NOTE : This function Should not be modified, when the callback is needed,
\r
200 the HAL_NAND_MspInit could be implemented in the user file
\r
205 * @brief NAND MSP DeInit
\r
206 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
207 * the configuration information for NAND module.
\r
210 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
\r
212 /* NOTE : This function Should not be modified, when the callback is needed,
\r
213 the HAL_NAND_MspDeInit could be implemented in the user file
\r
219 * @brief This function handles NAND device interrupt request.
\r
220 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
221 * the configuration information for NAND module.
\r
222 * @retval HAL status
\r
224 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
\r
226 /* Check NAND interrupt Rising edge flag */
\r
227 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
\r
229 /* NAND interrupt callback*/
\r
230 HAL_NAND_ITCallback(hnand);
\r
232 /* Clear NAND interrupt Rising edge pending bit */
\r
233 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
\r
236 /* Check NAND interrupt Level flag */
\r
237 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
\r
239 /* NAND interrupt callback*/
\r
240 HAL_NAND_ITCallback(hnand);
\r
242 /* Clear NAND interrupt Level pending bit */
\r
243 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
\r
246 /* Check NAND interrupt Falling edge flag */
\r
247 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
\r
249 /* NAND interrupt callback*/
\r
250 HAL_NAND_ITCallback(hnand);
\r
252 /* Clear NAND interrupt Falling edge pending bit */
\r
253 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
\r
256 /* Check NAND interrupt FIFO empty flag */
\r
257 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
\r
259 /* NAND interrupt callback*/
\r
260 HAL_NAND_ITCallback(hnand);
\r
262 /* Clear NAND interrupt FIFO empty pending bit */
\r
263 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
\r
269 * @brief NAND interrupt feature callback
\r
270 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
271 * the configuration information for NAND module.
\r
274 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
\r
276 /* NOTE : This function Should not be modified, when the callback is needed,
\r
277 the HAL_NAND_ITCallback could be implemented in the user file
\r
285 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
\r
286 * @brief Input Output and memory control functions
\r
289 ==============================================================================
\r
290 ##### NAND Input and Output functions #####
\r
291 ==============================================================================
\r
293 This section provides functions allowing to use and control the NAND
\r
301 * @brief Read the NAND memory electronic signature
\r
302 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
303 * the configuration information for NAND module.
\r
304 * @param pNAND_ID: NAND ID structure
\r
305 * @retval HAL status
\r
307 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
\r
309 __IO uint32_t data = 0;
\r
310 uint32_t deviceAddress = 0;
\r
312 /* Process Locked */
\r
313 __HAL_LOCK(hnand);
\r
315 /* Check the NAND controller state */
\r
316 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
321 /* Identify the device address */
\r
322 deviceAddress = NAND_DEVICE;
\r
324 /* Update the NAND controller state */
\r
325 hnand->State = HAL_NAND_STATE_BUSY;
\r
327 /* Send Read ID command sequence */
\r
328 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
\r
329 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
\r
331 /* Read the electronic signature from NAND flash */
\r
332 data = *(__IO uint32_t *)deviceAddress;
\r
334 /* Return the data read */
\r
335 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
\r
336 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
\r
337 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
\r
338 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
\r
340 /* Update the NAND controller state */
\r
341 hnand->State = HAL_NAND_STATE_READY;
\r
343 /* Process unlocked */
\r
344 __HAL_UNLOCK(hnand);
\r
350 * @brief NAND memory reset
\r
351 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
352 * the configuration information for NAND module.
\r
353 * @retval HAL status
\r
355 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
\r
357 uint32_t deviceAddress = 0;
\r
359 /* Process Locked */
\r
362 /* Check the NAND controller state */
\r
363 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
368 /* Identify the device address */
\r
369 deviceAddress = NAND_DEVICE;
\r
371 /* Update the NAND controller state */
\r
372 hnand->State = HAL_NAND_STATE_BUSY;
\r
374 /* Send NAND reset command */
\r
375 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
\r
378 /* Update the NAND controller state */
\r
379 hnand->State = HAL_NAND_STATE_READY;
\r
381 /* Process unlocked */
\r
382 __HAL_UNLOCK(hnand);
\r
389 * @brief Read Page(s) from NAND memory block
\r
390 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
391 * the configuration information for NAND module.
\r
392 * @param pAddress : pointer to NAND address structure
\r
393 * @param pBuffer : pointer to destination read buffer
\r
394 * @param NumPageToRead : number of pages to read from block
\r
395 * @retval HAL status
\r
397 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
\r
399 __IO uint32_t index = 0;
\r
400 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
\r
402 /* Process Locked */
\r
403 __HAL_LOCK(hnand);
\r
405 /* Check the NAND controller state */
\r
406 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
411 /* Identify the device address */
\r
412 deviceAddress = NAND_DEVICE;
\r
414 /* Update the NAND controller state */
\r
415 hnand->State = HAL_NAND_STATE_BUSY;
\r
417 /* NAND raw address calculation */
\r
418 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
\r
420 /* Page(s) read loop */
\r
421 while((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
\r
423 /* update the buffer size */
\r
424 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
\r
426 /* Send read page command sequence */
\r
427 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
\r
429 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
\r
430 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
\r
431 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
\r
432 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
\r
434 /* for 512 and 1 GB devices, 4th cycle is required */
\r
435 if(hnand->Info.BlockNbr >= 1024)
\r
437 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
\r
440 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
\r
442 /* Get Data into Buffer */
\r
443 for(index = 0; index < size; index++)
\r
445 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
\r
448 /* Increment read pages number */
\r
451 /* Decrement pages to read */
\r
454 /* Increment the NAND address */
\r
455 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
\r
459 /* Update the NAND controller state */
\r
460 hnand->State = HAL_NAND_STATE_READY;
\r
462 /* Process unlocked */
\r
463 __HAL_UNLOCK(hnand);
\r
470 * @brief Write Page(s) to NAND memory block
\r
471 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
472 * the configuration information for NAND module.
\r
473 * @param pAddress : pointer to NAND address structure
\r
474 * @param pBuffer : pointer to source buffer to write
\r
475 * @param NumPageToWrite : number of pages to write to block
\r
476 * @retval HAL status
\r
478 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
\r
480 __IO uint32_t index = 0;
\r
481 uint32_t tickstart = 0;
\r
482 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
\r
484 /* Process Locked */
\r
485 __HAL_LOCK(hnand);
\r
487 /* Check the NAND controller state */
\r
488 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
493 /* Identify the device address */
\r
494 deviceAddress = NAND_DEVICE;
\r
496 /* Update the NAND controller state */
\r
497 hnand->State = HAL_NAND_STATE_BUSY;
\r
499 /* NAND raw address calculation */
\r
500 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
\r
502 /* Page(s) write loop */
\r
503 while((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
\r
505 /* update the buffer size */
\r
506 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
\r
508 /* Send write page command sequence */
\r
509 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
\r
510 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
\r
512 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
\r
513 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
\r
514 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
\r
515 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
\r
518 /* for 512 and 1 GB devices, 4th cycle is required */
\r
519 if(hnand->Info.BlockNbr >= 1024)
\r
521 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
\r
525 /* Write data to memory */
\r
526 for(index = 0; index < size; index++)
\r
528 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
\r
532 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
\r
534 /* Read status until NAND is ready */
\r
535 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
\r
538 tickstart = HAL_GetTick();
\r
540 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
\r
542 return HAL_TIMEOUT;
\r
546 /* Increment written pages number */
\r
549 /* Decrement pages to write */
\r
552 /* Increment the NAND address */
\r
553 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
\r
556 /* Update the NAND controller state */
\r
557 hnand->State = HAL_NAND_STATE_READY;
\r
559 /* Process unlocked */
\r
560 __HAL_UNLOCK(hnand);
\r
566 * @brief Read Spare area(s) from NAND memory
\r
567 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
568 * the configuration information for NAND module.
\r
569 * @param pAddress : pointer to NAND address structure
\r
570 * @param pBuffer: pointer to source buffer to write
\r
571 * @param NumSpareAreaToRead: Number of spare area to read
\r
572 * @retval HAL status
\r
574 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
\r
576 __IO uint32_t index = 0;
\r
577 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
\r
579 /* Process Locked */
\r
580 __HAL_LOCK(hnand);
\r
582 /* Check the NAND controller state */
\r
583 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
588 /* Identify the device address */
\r
589 deviceAddress = NAND_DEVICE;
\r
591 /* Update the NAND controller state */
\r
592 hnand->State = HAL_NAND_STATE_BUSY;
\r
594 /* NAND raw address calculation */
\r
595 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
\r
597 /* Spare area(s) read loop */
\r
598 while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
\r
601 /* update the buffer size */
\r
602 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
\r
604 /* Send read spare area command sequence */
\r
605 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
\r
607 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
\r
608 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
\r
609 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
\r
610 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
\r
612 /* for 512 and 1 GB devices, 4th cycle is required */
\r
613 if(hnand->Info.BlockNbr >= 1024)
\r
615 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
\r
618 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
\r
620 /* Get Data into Buffer */
\r
621 for(index = 0; index < size; index++)
\r
623 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
\r
626 /* Increment read spare areas number */
\r
627 numSpareAreaRead++;
\r
629 /* Decrement spare areas to read */
\r
630 NumSpareAreaToRead--;
\r
632 /* Increment the NAND address */
\r
633 nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
\r
636 /* Update the NAND controller state */
\r
637 hnand->State = HAL_NAND_STATE_READY;
\r
639 /* Process unlocked */
\r
640 __HAL_UNLOCK(hnand);
\r
646 * @brief Write Spare area(s) to NAND memory
\r
647 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
648 * the configuration information for NAND module.
\r
649 * @param pAddress : pointer to NAND address structure
\r
650 * @param pBuffer : pointer to source buffer to write
\r
651 * @param NumSpareAreaTowrite : number of spare areas to write to block
\r
652 * @retval HAL status
\r
654 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
\r
656 __IO uint32_t index = 0;
\r
657 uint32_t tickstart = 0;
\r
658 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
\r
660 /* Process Locked */
\r
661 __HAL_LOCK(hnand);
\r
663 /* Check the NAND controller state */
\r
664 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
669 /* Identify the device address */
\r
670 deviceAddress = NAND_DEVICE;
\r
672 /* Update the FMC_NAND controller state */
\r
673 hnand->State = HAL_NAND_STATE_BUSY;
\r
675 /* NAND raw address calculation */
\r
676 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
\r
678 /* Spare area(s) write loop */
\r
679 while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
\r
681 /* update the buffer size */
\r
682 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
\r
684 /* Send write Spare area command sequence */
\r
685 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
\r
686 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
\r
688 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
\r
689 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
\r
690 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
\r
691 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
\r
693 /* for 512 and 1 GB devices, 4th cycle is required */
\r
694 if(hnand->Info.BlockNbr >= 1024)
\r
696 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
\r
700 /* Write data to memory */
\r
701 for(index = 0; index < size; index++)
\r
703 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
\r
707 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
\r
710 /* Read status until NAND is ready */
\r
711 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
\r
714 tickstart = HAL_GetTick();
\r
716 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
\r
718 return HAL_TIMEOUT;
\r
722 /* Increment written spare areas number */
\r
723 numSpareAreaWritten++;
\r
725 /* Decrement spare areas to write */
\r
726 NumSpareAreaTowrite--;
\r
728 /* Increment the NAND address */
\r
729 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));
\r
732 /* Update the NAND controller state */
\r
733 hnand->State = HAL_NAND_STATE_READY;
\r
735 /* Process unlocked */
\r
736 __HAL_UNLOCK(hnand);
\r
742 * @brief NAND memory Block erase
\r
743 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
744 * the configuration information for NAND module.
\r
745 * @param pAddress : pointer to NAND address structure
\r
746 * @retval HAL status
\r
748 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
\r
750 uint32_t DeviceAddress = 0;
\r
752 /* Process Locked */
\r
755 /* Check the NAND controller state */
\r
756 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
761 /* Identify the device address */
\r
762 DeviceAddress = NAND_DEVICE;
\r
764 /* Update the NAND controller state */
\r
765 hnand->State = HAL_NAND_STATE_BUSY;
\r
767 /* Send Erase block command sequence */
\r
768 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
\r
770 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
\r
771 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
\r
772 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
\r
775 /* for 512 and 1 GB devices, 4th cycle is required */
\r
776 if(hnand->Info.BlockNbr >= 1024)
\r
778 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
\r
782 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
\r
785 /* Update the NAND controller state */
\r
786 hnand->State = HAL_NAND_STATE_READY;
\r
788 /* Process unlocked */
\r
789 __HAL_UNLOCK(hnand);
\r
795 * @brief NAND memory read status
\r
796 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
797 * the configuration information for NAND module.
\r
798 * @retval NAND status
\r
800 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
\r
803 uint32_t DeviceAddress = 0;
\r
805 /* Identify the device address */
\r
806 DeviceAddress = NAND_DEVICE;
\r
808 /* Send Read status operation command */
\r
809 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
\r
811 /* Read status register data */
\r
812 data = *(__IO uint8_t *)DeviceAddress;
\r
814 /* Return the status */
\r
815 if((data & NAND_ERROR) == NAND_ERROR)
\r
819 else if((data & NAND_READY) == NAND_READY)
\r
828 * @brief Increment the NAND memory address
\r
829 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
830 * the configuration information for NAND module.
\r
831 * @param pAddress: pointer to NAND address structure
\r
832 * @retval The new status of the increment address operation. It can be:
\r
833 * - NAND_VALID_ADDRESS: When the new address is valid address
\r
834 * - NAND_INVALID_ADDRESS: When the new address is invalid address
\r
836 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
\r
838 uint32_t status = NAND_VALID_ADDRESS;
\r
840 /* Increment page address */
\r
843 /* Check NAND address is valid */
\r
844 if(pAddress->Page == hnand->Info.BlockSize)
\r
846 pAddress->Page = 0;
\r
849 if(pAddress->Block == hnand->Info.ZoneSize)
\r
851 pAddress->Block = 0;
\r
854 if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
\r
856 status = NAND_INVALID_ADDRESS;
\r
867 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
\r
868 * @brief management functions
\r
871 ==============================================================================
\r
872 ##### NAND Control functions #####
\r
873 ==============================================================================
\r
875 This subsection provides a set of functions allowing to control dynamically
\r
876 the NAND interface.
\r
884 * @brief Enables dynamically NAND ECC feature.
\r
885 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
886 * the configuration information for NAND module.
\r
887 * @retval HAL status
\r
889 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
\r
891 /* Check the NAND controller state */
\r
892 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
897 /* Update the NAND state */
\r
898 hnand->State = HAL_NAND_STATE_BUSY;
\r
900 /* Enable ECC feature */
\r
901 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
\r
903 /* Update the NAND state */
\r
904 hnand->State = HAL_NAND_STATE_READY;
\r
910 * @brief Disables dynamically FMC_NAND ECC feature.
\r
911 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
912 * the configuration information for NAND module.
\r
913 * @retval HAL status
\r
915 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
\r
917 /* Check the NAND controller state */
\r
918 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
923 /* Update the NAND state */
\r
924 hnand->State = HAL_NAND_STATE_BUSY;
\r
926 /* Disable ECC feature */
\r
927 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
\r
929 /* Update the NAND state */
\r
930 hnand->State = HAL_NAND_STATE_READY;
\r
936 * @brief Disables dynamically NAND ECC feature.
\r
937 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
938 * the configuration information for NAND module.
\r
939 * @param ECCval: pointer to ECC value
\r
940 * @param Timeout: maximum timeout to wait
\r
941 * @retval HAL status
\r
943 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
\r
945 HAL_StatusTypeDef status = HAL_OK;
\r
947 /* Check the NAND controller state */
\r
948 if(hnand->State == HAL_NAND_STATE_BUSY)
\r
953 /* Update the NAND state */
\r
954 hnand->State = HAL_NAND_STATE_BUSY;
\r
956 /* Get NAND ECC value */
\r
957 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
\r
959 /* Update the NAND state */
\r
960 hnand->State = HAL_NAND_STATE_READY;
\r
970 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
\r
971 * @brief Peripheral State functions
\r
974 ==============================================================================
\r
975 ##### NAND State functions #####
\r
976 ==============================================================================
\r
978 This subsection permits to get in run-time the status of the NAND controller
\r
986 * @brief return the NAND state
\r
987 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
\r
988 * the configuration information for NAND module.
\r
989 * @retval HAL state
\r
991 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
\r
993 return hnand->State;
\r
1003 #endif /* STM32F756xx || STM32F746xx */
\r
1004 #endif /* HAL_NAND_MODULE_ENABLED */
\r
1014 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r