source: rtems/c/src/lib/libbsp/arm/stm32f7x/hal/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_nand.c @ c20847a5

5
Last change on this file since c20847a5 was c20847a5, checked in by Isaac Gutekunst <isaac.gutekunst@…>, on 09/16/15 at 13:16:02

Add STM32F7 HAL Files

These files originated as:

+ STC32CubeF7 V1.1.0 from http://www.st.com/web/en/catalog/tools/PF261909

  • Property mode set to 100644
File size: 31.2 KB
Line 
1/**
2  ******************************************************************************
3  * @file    stm32f7xx_hal_nand.c
4  * @author  MCD Application Team
5  * @version V1.0.1
6  * @date    25-June-2015
7  * @brief   NAND HAL module driver.
8  *          This file provides a generic firmware to drive NAND memories mounted
9  *          as external device.
10  *
11  @verbatim
12  ==============================================================================
13                         ##### How to use this driver #####
14  ==============================================================================
15    [..]
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:
19
20      (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
21          with control and timing parameters for both common and attribute spaces.
22
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.
26
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.
33
34      (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
35
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.
39
40      (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
41
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.
45
46      (+) You can monitor the NAND device HAL state by calling the function
47          HAL_NAND_GetState()
48
49    [..]
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.
53
54  @endverbatim
55  ******************************************************************************
56  * @attention
57  *
58  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
59  *
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.
70  *
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.
81  *
82  ******************************************************************************
83  */
84
85/* Includes ------------------------------------------------------------------*/
86#include "stm32f7xx_hal.h"
87
88/** @addtogroup STM32F7xx_HAL_Driver
89  * @{
90  */
91
92
93#ifdef HAL_NAND_MODULE_ENABLED
94
95/** @defgroup NAND NAND
96  * @brief NAND HAL module driver
97  * @{
98  */
99
100/* Private typedef -----------------------------------------------------------*/
101/* Private Constants ------------------------------------------------------------*/
102/* Private macro -------------------------------------------------------------*/
103/* Private variables ---------------------------------------------------------*/
104/* Private function prototypes -----------------------------------------------*/
105/* Exported functions ---------------------------------------------------------*/
106
107/** @defgroup NAND_Exported_Functions NAND Exported Functions
108  * @{
109  */
110
111/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
112  * @brief    Initialization and Configuration functions
113  *
114  @verbatim
115  ==============================================================================
116            ##### NAND Initialization and de-initialization functions #####
117  ==============================================================================
118  [..]
119    This section provides functions allowing to initialize/de-initialize
120    the NAND memory
121
122@endverbatim
123  * @{
124  */
125
126/**
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
132  * @retval HAL status
133  */
134HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
135{
136  /* Check the NAND handle state */
137  if(hnand == NULL)
138  {
139     return HAL_ERROR;
140  }
141
142  if(hnand->State == HAL_NAND_STATE_RESET)
143  {
144    /* Allocate lock resource and initialize it */
145    hnand->Lock = HAL_UNLOCKED;
146    /* Initialize the low level hardware (MSP) */
147    HAL_NAND_MspInit(hnand);
148  }
149
150  /* Initialize NAND control Interface */
151  FMC_NAND_Init(hnand->Instance, &(hnand->Init));
152
153  /* Initialize NAND common space timing Interface */
154  FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
155
156  /* Initialize NAND attribute space timing Interface */
157  FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
158
159  /* Enable the NAND device */
160  __FMC_NAND_ENABLE(hnand->Instance);
161
162  /* Update the NAND controller state */
163  hnand->State = HAL_NAND_STATE_READY;
164
165  return HAL_OK;
166}
167
168/**
169  * @brief  Perform NAND memory De-Initialization sequence
170  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
171  *                the configuration information for NAND module.
172  * @retval HAL status
173  */
174HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
175{
176  /* Initialize the low level hardware (MSP) */
177  HAL_NAND_MspDeInit(hnand);
178
179  /* Configure the NAND registers with their reset values */
180  FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
181
182  /* Reset the NAND controller state */
183  hnand->State = HAL_NAND_STATE_RESET;
184
185  /* Release Lock */
186  __HAL_UNLOCK(hnand);
187
188  return HAL_OK;
189}
190
191/**
192  * @brief  NAND MSP Init
193  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
194  *                the configuration information for NAND module.
195  * @retval None
196  */
197__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
198{
199  /* NOTE : This function Should not be modified, when the callback is needed,
200            the HAL_NAND_MspInit could be implemented in the user file
201   */
202}
203
204/**
205  * @brief  NAND MSP DeInit
206  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
207  *                the configuration information for NAND module.
208  * @retval None
209  */
210__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
211{
212  /* NOTE : This function Should not be modified, when the callback is needed,
213            the HAL_NAND_MspDeInit could be implemented in the user file
214   */
215}
216
217
218/**
219  * @brief  This function handles NAND device interrupt request.
220  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
221  *                the configuration information for NAND module.
222  * @retval HAL status
223*/
224void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
225{
226  /* Check NAND interrupt Rising edge flag */
227  if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
228  {
229    /* NAND interrupt callback*/
230    HAL_NAND_ITCallback(hnand);
231
232    /* Clear NAND interrupt Rising edge pending bit */
233    __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
234  }
235
236  /* Check NAND interrupt Level flag */
237  if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
238  {
239    /* NAND interrupt callback*/
240    HAL_NAND_ITCallback(hnand);
241
242    /* Clear NAND interrupt Level pending bit */
243    __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
244  }
245
246  /* Check NAND interrupt Falling edge flag */
247  if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
248  {
249    /* NAND interrupt callback*/
250    HAL_NAND_ITCallback(hnand);
251
252    /* Clear NAND interrupt Falling edge pending bit */
253    __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
254  }
255
256  /* Check NAND interrupt FIFO empty flag */
257  if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
258  {
259    /* NAND interrupt callback*/
260    HAL_NAND_ITCallback(hnand);
261
262    /* Clear NAND interrupt FIFO empty pending bit */
263    __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
264  }
265
266}
267
268/**
269  * @brief  NAND interrupt feature callback
270  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
271  *                the configuration information for NAND module.
272  * @retval None
273  */
274__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
275{
276  /* NOTE : This function Should not be modified, when the callback is needed,
277            the HAL_NAND_ITCallback could be implemented in the user file
278   */
279}
280
281/**
282  * @}
283  */
284
285/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
286  * @brief    Input Output and memory control functions
287  *
288  @verbatim
289  ==============================================================================
290                    ##### NAND Input and Output functions #####
291  ==============================================================================
292  [..]
293    This section provides functions allowing to use and control the NAND
294    memory
295
296@endverbatim
297  * @{
298  */
299
300/**
301  * @brief  Read the NAND memory electronic signature
302  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
303  *                the configuration information for NAND module.
304  * @param  pNAND_ID: NAND ID structure
305  * @retval HAL status
306  */
307HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
308{
309  __IO uint32_t data = 0;
310  uint32_t deviceAddress = 0;
311
312  /* Process Locked */
313  __HAL_LOCK(hnand);
314
315  /* Check the NAND controller state */
316  if(hnand->State == HAL_NAND_STATE_BUSY)
317  {
318     return HAL_BUSY;
319  }
320
321  /* Identify the device address */
322  deviceAddress = NAND_DEVICE;
323
324  /* Update the NAND controller state */
325  hnand->State = HAL_NAND_STATE_BUSY;
326
327  /* Send Read ID command sequence */
328  *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_READID;
329  *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
330
331  /* Read the electronic signature from NAND flash */
332  data = *(__IO uint32_t *)deviceAddress;
333
334  /* Return the data read */
335  pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
336  pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
337  pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
338  pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
339
340  /* Update the NAND controller state */
341  hnand->State = HAL_NAND_STATE_READY;
342
343  /* Process unlocked */
344  __HAL_UNLOCK(hnand);
345
346  return HAL_OK;
347}
348
349/**
350  * @brief  NAND memory reset
351  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
352  *                the configuration information for NAND module.
353  * @retval HAL status
354  */
355HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
356{
357  uint32_t deviceAddress = 0;
358
359  /* Process Locked */
360  __HAL_LOCK(hnand);
361
362  /* Check the NAND controller state */
363  if(hnand->State == HAL_NAND_STATE_BUSY)
364  {
365     return HAL_BUSY;
366  }
367
368  /* Identify the device address */
369  deviceAddress = NAND_DEVICE;
370
371  /* Update the NAND controller state */
372  hnand->State = HAL_NAND_STATE_BUSY;
373
374  /* Send NAND reset command */
375  *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
376
377
378  /* Update the NAND controller state */
379  hnand->State = HAL_NAND_STATE_READY;
380
381  /* Process unlocked */
382  __HAL_UNLOCK(hnand);
383
384  return HAL_OK;
385
386}
387
388/**
389  * @brief  Read Page(s) from NAND memory block
390  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
391  *                the configuration information for NAND module.
392  * @param  pAddress : pointer to NAND address structure
393  * @param  pBuffer : pointer to destination read buffer
394  * @param  NumPageToRead : number of pages to read from block
395  * @retval HAL status
396  */
397HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
398{
399  __IO uint32_t index  = 0;
400  uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
401
402  /* Process Locked */
403  __HAL_LOCK(hnand);
404
405  /* Check the NAND controller state */
406  if(hnand->State == HAL_NAND_STATE_BUSY)
407  {
408     return HAL_BUSY;
409  }
410
411  /* Identify the device address */
412  deviceAddress = NAND_DEVICE;
413
414  /* Update the NAND controller state */
415  hnand->State = HAL_NAND_STATE_BUSY;
416
417  /* NAND raw address calculation */
418  nandAddress = ARRAY_ADDRESS(pAddress, hnand);
419
420  /* Page(s) read loop */
421  while((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
422  {
423    /* update the buffer size */
424    size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
425
426    /* Send read page command sequence */
427    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
428
429    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
430    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
431    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
432    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
433
434    /* for 512 and 1 GB devices, 4th cycle is required */
435    if(hnand->Info.BlockNbr >= 1024)
436    {
437      *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
438    }
439
440    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
441
442    /* Get Data into Buffer */
443    for(index = 0; index < size; index++)
444    {
445      *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
446    }
447
448    /* Increment read pages number */
449    numPagesRead++;
450
451    /* Decrement pages to read */
452    NumPageToRead--;
453
454    /* Increment the NAND address */
455    nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
456
457  }
458
459  /* Update the NAND controller state */
460  hnand->State = HAL_NAND_STATE_READY;
461
462  /* Process unlocked */
463  __HAL_UNLOCK(hnand);
464
465  return HAL_OK;
466
467}
468
469/**
470  * @brief  Write Page(s) to NAND memory block
471  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
472  *                the configuration information for NAND module.
473  * @param  pAddress : pointer to NAND address structure
474  * @param  pBuffer : pointer to source buffer to write
475  * @param  NumPageToWrite  : number of pages to write to block
476  * @retval HAL status
477  */
478HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
479{
480  __IO uint32_t index = 0;
481  uint32_t tickstart = 0;
482  uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
483
484  /* Process Locked */
485  __HAL_LOCK(hnand);
486
487  /* Check the NAND controller state */
488  if(hnand->State == HAL_NAND_STATE_BUSY)
489  {
490     return HAL_BUSY;
491  }
492
493  /* Identify the device address */
494  deviceAddress = NAND_DEVICE;
495
496  /* Update the NAND controller state */
497  hnand->State = HAL_NAND_STATE_BUSY;
498
499  /* NAND raw address calculation */
500  nandAddress = ARRAY_ADDRESS(pAddress, hnand);
501
502  /* Page(s) write loop */
503  while((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
504  {
505    /* update the buffer size */
506    size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
507
508    /* Send write page command sequence */
509    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
510    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
511
512    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
513    *(__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);
515    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
516    __DSB();
517
518    /* for 512 and 1 GB devices, 4th cycle is required */
519    if(hnand->Info.BlockNbr >= 1024)
520    {
521      *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
522      __DSB();
523    }
524
525    /* Write data to memory */
526    for(index = 0; index < size; index++)
527    {
528      *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
529      __DSB();
530    }
531
532    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
533
534    /* Read status until NAND is ready */
535    while(HAL_NAND_Read_Status(hnand) != NAND_READY)
536    {
537      /* Get tick */
538      tickstart = HAL_GetTick();
539
540      if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
541      {
542        return HAL_TIMEOUT;
543      }
544    }
545
546    /* Increment written pages number */
547    numPagesWritten++;
548
549    /* Decrement pages to write */
550    NumPageToWrite--;
551
552    /* Increment the NAND address */
553    nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
554  }
555
556  /* Update the NAND controller state */
557  hnand->State = HAL_NAND_STATE_READY;
558
559  /* Process unlocked */
560  __HAL_UNLOCK(hnand);
561
562  return HAL_OK;
563}
564
565/**
566  * @brief  Read Spare area(s) from NAND memory
567  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
568  *                the configuration information for NAND module.
569  * @param  pAddress : pointer to NAND address structure
570  * @param  pBuffer: pointer to source buffer to write
571  * @param  NumSpareAreaToRead: Number of spare area to read
572  * @retval HAL status
573*/
574HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
575{
576  __IO uint32_t index = 0;
577  uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
578
579  /* Process Locked */
580  __HAL_LOCK(hnand);
581
582  /* Check the NAND controller state */
583  if(hnand->State == HAL_NAND_STATE_BUSY)
584  {
585     return HAL_BUSY;
586  }
587
588  /* Identify the device address */
589  deviceAddress = NAND_DEVICE;
590
591  /* Update the NAND controller state */
592  hnand->State = HAL_NAND_STATE_BUSY;
593
594  /* NAND raw address calculation */
595  nandAddress = ARRAY_ADDRESS(pAddress, hnand);
596
597  /* Spare area(s) read loop */
598  while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
599  {
600
601    /* update the buffer size */
602    size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
603
604    /* Send read spare area command sequence */
605    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
606
607    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
608    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
609    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
610    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
611
612    /* for 512 and 1 GB devices, 4th cycle is required */
613    if(hnand->Info.BlockNbr >= 1024)
614    {
615      *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
616    }
617
618    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
619
620    /* Get Data into Buffer */
621    for(index = 0; index < size; index++)
622    {
623      *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
624    }
625
626    /* Increment read spare areas number */
627    numSpareAreaRead++;
628
629    /* Decrement spare areas to read */
630    NumSpareAreaToRead--;
631
632    /* Increment the NAND address */
633    nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
634  }
635
636  /* Update the NAND controller state */
637  hnand->State = HAL_NAND_STATE_READY;
638
639  /* Process unlocked */
640  __HAL_UNLOCK(hnand);
641
642  return HAL_OK;
643}
644
645/**
646  * @brief  Write Spare area(s) to NAND memory
647  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
648  *                the configuration information for NAND module.
649  * @param  pAddress : pointer to NAND address structure
650  * @param  pBuffer : pointer to source buffer to write
651  * @param  NumSpareAreaTowrite  : number of spare areas to write to block
652  * @retval HAL status
653  */
654HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
655{
656  __IO uint32_t index = 0;
657  uint32_t tickstart = 0;
658  uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
659
660  /* Process Locked */
661  __HAL_LOCK(hnand);
662
663  /* Check the NAND controller state */
664  if(hnand->State == HAL_NAND_STATE_BUSY)
665  {
666     return HAL_BUSY;
667  }
668
669  /* Identify the device address */
670  deviceAddress = NAND_DEVICE;
671
672  /* Update the FMC_NAND controller state */
673  hnand->State = HAL_NAND_STATE_BUSY;
674
675  /* NAND raw address calculation */
676  nandAddress = ARRAY_ADDRESS(pAddress, hnand);
677
678  /* Spare area(s) write loop */
679  while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
680  {
681    /* update the buffer size */
682    size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
683
684    /* Send write Spare area command sequence */
685    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
686    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
687
688    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
689    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
690    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
691    *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
692    __DSB();
693    /* for 512 and 1 GB devices, 4th cycle is required */
694    if(hnand->Info.BlockNbr >= 1024)
695    {
696      *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
697      __DSB();
698    }
699
700    /* Write data to memory */
701    for(index = 0; index < size; index++)
702    {
703      *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
704      __DSB();
705    }
706
707    *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
708    __DSB();
709
710    /* Read status until NAND is ready */
711    while(HAL_NAND_Read_Status(hnand) != NAND_READY)
712    {
713      /* Get tick */
714      tickstart = HAL_GetTick();
715
716      if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
717      {
718        return HAL_TIMEOUT;
719      }
720    }
721
722    /* Increment written spare areas number */
723    numSpareAreaWritten++;
724
725    /* Decrement spare areas to write */
726    NumSpareAreaTowrite--;
727
728    /* Increment the NAND address */
729    nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));
730  }
731
732  /* Update the NAND controller state */
733  hnand->State = HAL_NAND_STATE_READY;
734
735  /* Process unlocked */
736  __HAL_UNLOCK(hnand);
737
738  return HAL_OK;
739}
740
741/**
742  * @brief  NAND memory Block erase
743  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
744  *                the configuration information for NAND module.
745  * @param  pAddress : pointer to NAND address structure
746  * @retval HAL status
747  */
748HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
749{
750  uint32_t DeviceAddress = 0;
751
752  /* Process Locked */
753  __HAL_LOCK(hnand);
754
755  /* Check the NAND controller state */
756  if(hnand->State == HAL_NAND_STATE_BUSY)
757  {
758     return HAL_BUSY;
759  }
760
761  /* Identify the device address */
762  DeviceAddress = NAND_DEVICE;
763
764  /* Update the NAND controller state */
765  hnand->State = HAL_NAND_STATE_BUSY;
766
767  /* Send Erase block command sequence */
768  *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
769
770  *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
771  *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
772  *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
773  __DSB();
774
775  /* for 512 and 1 GB devices, 4th cycle is required */
776  if(hnand->Info.BlockNbr >= 1024)
777  {
778    *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
779    __DSB();
780  }
781
782  *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
783  __DSB();
784
785  /* Update the NAND controller state */
786  hnand->State = HAL_NAND_STATE_READY;
787
788  /* Process unlocked */
789  __HAL_UNLOCK(hnand);
790
791  return HAL_OK;
792}
793
794/**
795  * @brief  NAND memory read status
796  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
797  *                the configuration information for NAND module.
798  * @retval NAND status
799  */
800uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
801{
802  uint32_t data = 0;
803  uint32_t DeviceAddress = 0;
804
805  /* Identify the device address */
806   DeviceAddress = NAND_DEVICE;
807
808  /* Send Read status operation command */
809  *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
810
811  /* Read status register data */
812  data = *(__IO uint8_t *)DeviceAddress;
813
814  /* Return the status */
815  if((data & NAND_ERROR) == NAND_ERROR)
816  {
817    return NAND_ERROR;
818  }
819  else if((data & NAND_READY) == NAND_READY)
820  {
821    return NAND_READY;
822  }
823
824  return NAND_BUSY;
825}
826
827/**
828  * @brief  Increment the NAND memory address
829  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
830  *                the configuration information for NAND module.
831  * @param pAddress: pointer to NAND address structure
832  * @retval The new status of the increment address operation. It can be:
833  *           - NAND_VALID_ADDRESS: When the new address is valid address
834  *           - NAND_INVALID_ADDRESS: When the new address is invalid address
835  */
836uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
837{
838  uint32_t status = NAND_VALID_ADDRESS;
839
840  /* Increment page address */
841  pAddress->Page++;
842
843  /* Check NAND address is valid */
844  if(pAddress->Page == hnand->Info.BlockSize)
845  {
846    pAddress->Page = 0;
847    pAddress->Block++;
848
849    if(pAddress->Block == hnand->Info.ZoneSize)
850    {
851      pAddress->Block = 0;
852      pAddress->Zone++;
853
854      if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
855      {
856        status = NAND_INVALID_ADDRESS;
857      }
858    }
859  }
860
861  return (status);
862}
863/**
864  * @}
865  */
866
867/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
868 *  @brief   management functions
869 *
870@verbatim
871  ==============================================================================
872                         ##### NAND Control functions #####
873  ==============================================================================
874  [..]
875    This subsection provides a set of functions allowing to control dynamically
876    the NAND interface.
877
878@endverbatim
879  * @{
880  */
881
882
883/**
884  * @brief  Enables dynamically NAND ECC feature.
885  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
886  *                the configuration information for NAND module.
887  * @retval HAL status
888  */
889HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
890{
891  /* Check the NAND controller state */
892  if(hnand->State == HAL_NAND_STATE_BUSY)
893  {
894     return HAL_BUSY;
895  }
896
897  /* Update the NAND state */
898  hnand->State = HAL_NAND_STATE_BUSY;
899
900  /* Enable ECC feature */
901  FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
902
903  /* Update the NAND state */
904  hnand->State = HAL_NAND_STATE_READY;
905
906  return HAL_OK;
907}
908
909/**
910  * @brief  Disables dynamically FMC_NAND ECC feature.
911  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
912  *                the configuration information for NAND module.
913  * @retval HAL status
914  */
915HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
916{
917  /* Check the NAND controller state */
918  if(hnand->State == HAL_NAND_STATE_BUSY)
919  {
920     return HAL_BUSY;
921  }
922
923  /* Update the NAND state */
924  hnand->State = HAL_NAND_STATE_BUSY;
925
926  /* Disable ECC feature */
927  FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
928
929  /* Update the NAND state */
930  hnand->State = HAL_NAND_STATE_READY;
931
932  return HAL_OK;
933}
934
935/**
936  * @brief  Disables dynamically NAND ECC feature.
937  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
938  *                the configuration information for NAND module.
939  * @param  ECCval: pointer to ECC value
940  * @param  Timeout: maximum timeout to wait
941  * @retval HAL status
942  */
943HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
944{
945  HAL_StatusTypeDef status = HAL_OK;
946
947  /* Check the NAND controller state */
948  if(hnand->State == HAL_NAND_STATE_BUSY)
949  {
950     return HAL_BUSY;
951  }
952
953  /* Update the NAND state */
954  hnand->State = HAL_NAND_STATE_BUSY;
955
956  /* Get NAND ECC value */
957  status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
958
959  /* Update the NAND state */
960  hnand->State = HAL_NAND_STATE_READY;
961
962  return status;
963}
964
965/**
966  * @}
967  */
968
969
970/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
971 *  @brief   Peripheral State functions
972 *
973@verbatim
974  ==============================================================================
975                         ##### NAND State functions #####
976  ==============================================================================
977  [..]
978    This subsection permits to get in run-time the status of the NAND controller
979    and the data flow.
980
981@endverbatim
982  * @{
983  */
984
985/**
986  * @brief  return the NAND state
987  * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
988  *                the configuration information for NAND module.
989  * @retval HAL state
990  */
991HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
992{
993  return hnand->State;
994}
995
996/**
997  * @}
998  */
999
1000/**
1001  * @}
1002  */
1003
1004#endif /* HAL_NAND_MODULE_ENABLED  */
1005
1006/**
1007  * @}
1008  */
1009
1010/**
1011  * @}
1012  */
1013
1014/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.