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