]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_nand.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_nand.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_nand.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    19-June-2014
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) 2014 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 "stm32f4xx_hal.h"
87
88 /** @addtogroup STM32F4xx_HAL_Driver
89   * @{
90   */
91
92 /** @defgroup NAND 
93   * @brief NAND driver modules
94   * @{
95   */
96 #ifdef HAL_NAND_MODULE_ENABLED
97
98 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
99
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /* Private macro -------------------------------------------------------------*/    
103 /* Private variables ---------------------------------------------------------*/
104 /* Private function prototypes -----------------------------------------------*/
105 /* Private functions ---------------------------------------------------------*/
106
107 /** @defgroup NAND_Private_Functions
108   * @{
109   */
110     
111 /** @defgroup NAND_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   */
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 == HAL_NULL)
138   {
139      return HAL_ERROR;
140   }
141
142   if(hnand->State == HAL_NAND_STATE_RESET)
143   {
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, hnand->Init.NandBank);
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   */
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   */
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   */
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 */
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   {
227     /* NAND interrupt callback*/
228     HAL_NAND_ITCallback(hnand);
229   
230     /* Clear NAND interrupt Rising edge pending bit */
231     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
232   }
233   
234   /* Check NAND interrupt Level flag */
235   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
236   {
237     /* NAND interrupt callback*/
238     HAL_NAND_ITCallback(hnand);
239   
240     /* Clear NAND interrupt Level pending bit */
241     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
242   }
243
244   /* Check NAND interrupt Falling edge flag */
245   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
246   {
247     /* NAND interrupt callback*/
248     HAL_NAND_ITCallback(hnand);
249   
250     /* Clear NAND interrupt Falling edge pending bit */
251     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
252   }
253   
254   /* Check NAND interrupt FIFO empty flag */
255   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
256   {
257     /* NAND interrupt callback*/
258     HAL_NAND_ITCallback(hnand);
259   
260     /* Clear NAND interrupt FIFO empty pending bit */
261     __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
262   }  
263
264 }
265
266 /**
267   * @brief  NAND interrupt feature callback
268   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
269   *                the configuration information for NAND module.
270   * @retval None
271   */
272 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
273 {
274   /* NOTE : This function Should not be modified, when the callback is needed,
275             the HAL_NAND_ITCallback could be implemented in the user file
276    */
277 }
278  
279 /**
280   * @}
281   */
282   
283 /** @defgroup NAND_Group2 Input and Output functions 
284   * @brief    Input Output and memory control functions 
285   *
286   @verbatim    
287   ==============================================================================
288                     ##### NAND Input and Output functions #####
289   ==============================================================================
290   [..]  
291     This section provides functions allowing to use and control the NAND 
292     memory
293   
294 @endverbatim
295   * @{
296   */
297
298 /**
299   * @brief  Read the NAND memory electronic signature
300   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
301   *                the configuration information for NAND module.
302   * @param  pNAND_ID: NAND ID structure
303   * @retval HAL status
304   */
305 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
306 {
307   __IO uint32_t data = 0;
308   uint32_t deviceAddress = 0;
309
310   /* Process Locked */
311   __HAL_LOCK(hnand);  
312   
313   /* Check the NAND controller state */
314   if(hnand->State == HAL_NAND_STATE_BUSY)
315   {
316      return HAL_BUSY;
317   }
318   
319   /* Identify the device address */
320   if(hnand->Init.NandBank == FMC_NAND_BANK2)
321   {
322     deviceAddress = NAND_DEVICE1;
323   }
324   else
325   {
326     deviceAddress = NAND_DEVICE2;
327   }
328   
329   /* Update the NAND controller state */ 
330   hnand->State = HAL_NAND_STATE_BUSY;
331   
332   /* Send Read ID command sequence */   
333   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_READID;
334   *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
335
336   /* Read the electronic signature from NAND flash */   
337   data = *(__IO uint32_t *)deviceAddress;
338   
339   /* Return the data read */
340   pNAND_ID->Maker_Id   = __ADDR_1st_CYCLE(data);
341   pNAND_ID->Device_Id  = __ADDR_2nd_CYCLE(data);
342   pNAND_ID->Third_Id   = __ADDR_3rd_CYCLE(data);
343   pNAND_ID->Fourth_Id  = __ADDR_4th_CYCLE(data);
344   
345   /* Update the NAND controller state */ 
346   hnand->State = HAL_NAND_STATE_READY;
347   
348   /* Process unlocked */
349   __HAL_UNLOCK(hnand);   
350    
351   return HAL_OK;
352 }
353
354 /**
355   * @brief  NAND memory reset
356   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
357   *                the configuration information for NAND module.
358   * @retval HAL status
359   */
360 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
361 {
362   uint32_t deviceAddress = 0;
363   
364   /* Process Locked */
365   __HAL_LOCK(hnand);
366     
367   /* Check the NAND controller state */
368   if(hnand->State == HAL_NAND_STATE_BUSY)
369   {
370      return HAL_BUSY;
371   }
372
373   /* Identify the device address */  
374   if(hnand->Init.NandBank == FMC_NAND_BANK2)
375   {
376     deviceAddress = NAND_DEVICE1;
377   }
378   else
379   {
380     deviceAddress = NAND_DEVICE2;
381   }  
382   
383   /* Update the NAND controller state */   
384   hnand->State = HAL_NAND_STATE_BUSY; 
385   
386   /* Send NAND reset command */  
387   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
388     
389   
390   /* Update the NAND controller state */   
391   hnand->State = HAL_NAND_STATE_READY;
392   
393   /* Process unlocked */
394   __HAL_UNLOCK(hnand);    
395   
396   return HAL_OK;
397   
398 }
399
400   
401 /**
402   * @brief  Read Page(s) from NAND memory block 
403   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
404   *                the configuration information for NAND module.
405   * @param  pAddress : pointer to NAND address structure
406   * @param  pBuffer : pointer to destination read buffer
407   * @param  NumPageToRead : number of pages to read from block 
408   * @retval HAL status
409   */
410 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
411 {   
412   __IO uint32_t index  = 0;
413   uint32_t deviceAddress = 0, numPagesRead = 0, nandAddress = 0, addressStatus = NAND_VALID_ADDRESS;
414   
415   /* Process Locked */
416   __HAL_LOCK(hnand); 
417   
418   /* Check the NAND controller state */
419   if(hnand->State == HAL_NAND_STATE_BUSY)
420   {
421      return HAL_BUSY;
422   }
423   
424   /* Identify the device address */
425   if(hnand->Init.NandBank == FMC_NAND_BANK2)
426   {
427     deviceAddress = NAND_DEVICE1;
428   }
429   else
430   {
431     deviceAddress = NAND_DEVICE2;
432   }
433
434   /* Update the NAND controller state */ 
435   hnand->State = HAL_NAND_STATE_BUSY;
436   
437   /* Page(s) read loop */
438   while((NumPageToRead != 0) && (addressStatus == NAND_VALID_ADDRESS))  
439   {        
440     /* NAND raw address calculation */
441     nandAddress = __ARRAY_ADDRESS(pAddress, hnand);
442     
443     /* Send read page command sequence */
444     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;  
445    
446     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 
447     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_1st_CYCLE(nandAddress); 
448     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(nandAddress); 
449     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(nandAddress);
450   
451     /* for 512 and 1 GB devices, 4th cycle is required */    
452     if(hnand->Info.BlockNbr > 1024)
453     {
454       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_4th_CYCLE(nandAddress);
455     }
456   
457     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
458       
459     /* Get Data into Buffer */    
460     for(index = 0 ; index < hnand->Info.PageSize; index++)
461     {
462       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
463     }
464     
465     /* Increment read pages number */
466     numPagesRead++;
467     
468     /* Decrement pages to read */
469     NumPageToRead--;
470     
471     /* Increment the NAND address */
472     HAL_NAND_Address_Inc(hnand, pAddress);
473     
474   }
475   
476   /* Update the NAND controller state */ 
477   hnand->State = HAL_NAND_STATE_READY;
478   
479   /* Process unlocked */
480   __HAL_UNLOCK(hnand);  
481     
482   return HAL_OK;
483
484 }
485
486 /**
487   * @brief  Write Page(s) to NAND memory block 
488   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
489   *                the configuration information for NAND module.
490   * @param  pAddress : pointer to NAND address structure
491   * @param  pBuffer : pointer to source buffer to write  
492   * @param  NumPageToWrite  : number of pages to write to block 
493   * @retval HAL status
494   */
495 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
496 {
497   __IO uint32_t index = 0;
498   uint32_t tickstart = 0;
499   uint32_t deviceAddress = 0 , numPagesWritten = 0, nandAddress = 0, addressStatus = NAND_VALID_ADDRESS;
500   
501   /* Process Locked */
502   __HAL_LOCK(hnand);  
503
504   /* Check the NAND controller state */
505   if(hnand->State == HAL_NAND_STATE_BUSY)
506   {
507      return HAL_BUSY;
508   }
509   
510   /* Identify the device address */
511   if(hnand->Init.NandBank == FMC_NAND_BANK2)
512   {
513     deviceAddress = NAND_DEVICE1;
514   }
515   else
516   {
517     deviceAddress = NAND_DEVICE2;
518   }
519   
520   /* Update the NAND controller state */ 
521   hnand->State = HAL_NAND_STATE_BUSY;
522   
523   /* Page(s) write loop */
524   while((NumPageToWrite != 0) && (addressStatus == NAND_VALID_ADDRESS))
525   {  
526     /* NAND raw address calculation */
527     nandAddress = __ARRAY_ADDRESS(pAddress, hnand);
528  
529     /* Send write page command sequence */
530     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
531     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
532
533     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;  
534     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_1st_CYCLE(nandAddress);  
535     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(nandAddress);  
536     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(nandAddress);
537   
538     /* for 512 and 1 GB devices, 4th cycle is required */     
539     if(hnand->Info.BlockNbr > 1024)
540     {
541       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_4th_CYCLE(nandAddress);
542     }
543   
544     /* Write data to memory */
545     for(index = 0 ; index < hnand->Info.PageSize; index++)
546     {
547       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
548     }
549    
550     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
551     
552     /* Read status until NAND is ready */
553     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
554     {
555       /* Get tick */
556       tickstart = HAL_GetTick();
557     
558       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
559       {
560         return HAL_TIMEOUT; 
561       } 
562     }    
563  
564     /* Increment written pages number */
565     numPagesWritten++;
566     
567     /* Decrement pages to write */
568     NumPageToWrite--;
569     
570     /* Increment the NAND address */
571     HAL_NAND_Address_Inc(hnand, pAddress);
572       
573   }
574   
575   /* Update the NAND controller state */ 
576   hnand->State = HAL_NAND_STATE_READY;
577   
578   /* Process unlocked */
579   __HAL_UNLOCK(hnand);      
580   
581   return HAL_OK;
582 }
583
584
585 /**
586   * @brief  Read Spare area(s) from NAND memory 
587   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
588   *                the configuration information for NAND module.
589   * @param  pAddress : pointer to NAND address structure
590   * @param  pBuffer: pointer to source buffer to write  
591   * @param  NumSpareAreaToRead: Number of spare area to read  
592   * @retval HAL status
593 */
594 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
595 {
596   __IO uint32_t index   = 0; 
597   uint32_t deviceAddress = 0, numSpareAreaRead = 0, nandAddress = 0, addressStatus = NAND_VALID_ADDRESS;
598   
599   /* Process Locked */
600   __HAL_LOCK(hnand);  
601   
602   /* Check the NAND controller state */
603   if(hnand->State == HAL_NAND_STATE_BUSY)
604   {
605      return HAL_BUSY;
606   }
607   
608   /* Identify the device address */
609   if(hnand->Init.NandBank == FMC_NAND_BANK2)
610   {
611     deviceAddress = NAND_DEVICE1;
612   }
613   else
614   {
615     deviceAddress = NAND_DEVICE2;
616   }
617   
618   /* Update the NAND controller state */
619   hnand->State = HAL_NAND_STATE_BUSY;    
620   
621   /* Spare area(s) read loop */ 
622   while((NumSpareAreaToRead != 0) && (addressStatus == NAND_VALID_ADDRESS))
623   { 
624     /* NAND raw address calculation */
625     nandAddress = __ARRAY_ADDRESS(pAddress, hnand);     
626
627     /* Send read spare area command sequence */     
628     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
629     
630     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 
631     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_1st_CYCLE(nandAddress);     
632     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(nandAddress);     
633     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(nandAddress);
634   
635     /* for 512 and 1 GB devices, 4th cycle is required */    
636     if(hnand->Info.BlockNbr > 1024)
637     {
638       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_4th_CYCLE(nandAddress);
639     } 
640
641     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;    
642     
643     /* Get Data into Buffer */
644     for(index = 0 ; index < hnand->Info.SpareAreaSize; index++)
645     {
646       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
647     }
648     
649     /* Increment read spare areas number */
650     numSpareAreaRead++;
651     
652     /* Decrement spare areas to read */
653     NumSpareAreaToRead--;
654     
655     /* Increment the NAND address */
656     HAL_NAND_Address_Inc(hnand, pAddress);
657   }
658   
659   /* Update the NAND controller state */
660   hnand->State = HAL_NAND_STATE_READY;
661   
662   /* Process unlocked */
663   __HAL_UNLOCK(hnand);     
664
665   return HAL_OK;  
666 }
667
668 /**
669   * @brief  Write Spare area(s) to NAND memory 
670   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
671   *                the configuration information for NAND module.
672   * @param  pAddress : pointer to NAND address structure
673   * @param  pBuffer : pointer to source buffer to write  
674   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
675   * @retval HAL status
676   */
677 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
678 {
679   __IO uint32_t index = 0;
680   uint32_t tickstart = 0;
681   uint32_t deviceAddress = 0, numSpareAreaWritten = 0, nandAddress = 0, addressStatus = NAND_VALID_ADDRESS;
682
683   /* Process Locked */
684   __HAL_LOCK(hnand); 
685   
686   /* Check the NAND controller state */
687   if(hnand->State == HAL_NAND_STATE_BUSY)
688   {
689      return HAL_BUSY;
690   }
691   
692   /* Identify the device address */
693   if(hnand->Init.NandBank == FMC_NAND_BANK2)
694   {
695     deviceAddress = NAND_DEVICE1;
696   }
697   else
698   {
699     deviceAddress = NAND_DEVICE2;
700   }
701   
702   /* Update the FMC_NAND controller state */
703   hnand->State = HAL_NAND_STATE_BUSY;  
704   
705   /* Spare area(s) write loop */
706   while((NumSpareAreaTowrite != 0) && (addressStatus == NAND_VALID_ADDRESS))
707   {  
708     /* NAND raw address calculation */
709     nandAddress = __ARRAY_ADDRESS(pAddress, hnand);
710     
711     /* Send write Spare area command sequence */
712     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
713     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
714
715     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;  
716     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_1st_CYCLE(nandAddress);  
717     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(nandAddress);  
718     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(nandAddress); 
719   
720     /* for 512 and 1 GB devices, 4th cycle is required */     
721     if(hnand->Info.BlockNbr >= 1024)
722     {
723       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = __ADDR_4th_CYCLE(nandAddress);
724     }
725   
726     /* Write data to memory */
727     for(index = 0 ; index < hnand->Info.SpareAreaSize; index++)
728     {
729       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
730     }
731    
732     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
733     
734    
735     /* Read status until NAND is ready */
736     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
737     {
738       /* Get tick */
739       tickstart = HAL_GetTick();
740     
741       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
742       {
743         return HAL_TIMEOUT; 
744       }   
745     }
746
747     /* Increment written spare areas number */
748     numSpareAreaWritten++;
749     
750     /* Decrement spare areas to write */
751     NumSpareAreaTowrite--;
752     
753     /* Increment the NAND address */
754     HAL_NAND_Address_Inc(hnand, pAddress); 
755       
756   }
757
758   /* Update the NAND controller state */
759   hnand->State = HAL_NAND_STATE_READY;
760
761   /* Process unlocked */
762   __HAL_UNLOCK(hnand);
763     
764   return HAL_OK;  
765 }
766
767 /**
768   * @brief  NAND memory Block erase 
769   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
770   *                the configuration information for NAND module.
771   * @param  pAddress : pointer to NAND address structure
772   * @retval HAL status
773   */
774 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
775 {
776   uint32_t DeviceAddress = 0;
777   
778   /* Process Locked */
779   __HAL_LOCK(hnand);
780   
781   /* Check the NAND controller state */
782   if(hnand->State == HAL_NAND_STATE_BUSY)
783   {
784      return HAL_BUSY;
785   }
786   
787   /* Identify the device address */
788   if(hnand->Init.NandBank == FMC_NAND_BANK2)
789   {
790     DeviceAddress = NAND_DEVICE1;
791   }
792   else
793   {
794     DeviceAddress = NAND_DEVICE2;
795   }
796   
797   /* Update the NAND controller state */
798   hnand->State = HAL_NAND_STATE_BUSY;  
799   
800   /* Send Erase block command sequence */
801   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
802
803   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = __ADDR_1st_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
804   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = __ADDR_2nd_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
805   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = __ADDR_3rd_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
806   
807   /* for 512 and 1 GB devices, 4th cycle is required */     
808   if(hnand->Info.BlockNbr >= 1024)
809   {
810     *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = __ADDR_4th_CYCLE(__ARRAY_ADDRESS(pAddress, hnand));
811   }  
812                 
813   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1; 
814   
815   /* Update the NAND controller state */
816   hnand->State = HAL_NAND_STATE_READY;
817   
818   /* Process unlocked */
819   __HAL_UNLOCK(hnand);    
820   
821   return HAL_OK;  
822 }
823
824
825 /**
826   * @brief  NAND memory read status 
827   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
828   *                the configuration information for NAND module.
829   * @retval NAND status
830   */
831 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
832 {
833   uint32_t data = 0;
834   uint32_t DeviceAddress = 0;
835   
836   /* Identify the device address */
837   if(hnand->Init.NandBank == FMC_NAND_BANK2)
838   {
839     DeviceAddress = NAND_DEVICE1;
840   }
841   else
842   {
843     DeviceAddress = NAND_DEVICE2;
844   } 
845
846   /* Send Read status operation command */
847   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
848   
849   /* Read status register data */
850   data = *(__IO uint8_t *)DeviceAddress;
851
852   /* Return the status */
853   if((data & NAND_ERROR) == NAND_ERROR)
854   {
855     return NAND_ERROR;
856   } 
857   else if((data & NAND_READY) == NAND_READY)
858   {
859     return NAND_READY;
860   }
861
862   return NAND_BUSY; 
863  
864 }
865
866 /**
867   * @brief  Increment the NAND memory address
868   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
869   *                the configuration information for NAND module.
870   * @param pAddress: pointer to NAND adress structure
871   * @retval The new status of the increment address operation. It can be:
872   *           - NAND_VALID_ADDRESS: When the new address is valid address
873   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
874   */
875 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
876 {
877   uint32_t status = NAND_VALID_ADDRESS;
878  
879   /* Increment page address */
880   pAddress->Page++;
881
882   /* Check NAND address is valid */
883   if(pAddress->Page == hnand->Info.BlockSize)
884   {
885     pAddress->Page = 0;
886     pAddress->Block++;
887     
888     if(pAddress->Block == hnand->Info.ZoneSize)
889     {
890       pAddress->Block = 0;
891       pAddress->Zone++;
892
893       if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
894       {
895         status = NAND_INVALID_ADDRESS;
896       }
897     }
898   } 
899   
900   return (status);
901 }
902
903
904 /**
905   * @}
906   */
907
908 /** @defgroup NAND_Group3 Control functions 
909  *  @brief   management functions 
910  *
911 @verbatim   
912   ==============================================================================
913                          ##### NAND Control functions #####
914   ==============================================================================  
915   [..]
916     This subsection provides a set of functions allowing to control dynamically
917     the NAND interface.
918
919 @endverbatim
920   * @{
921   */ 
922
923     
924 /**
925   * @brief  Enables dynamically NAND ECC feature.
926   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
927   *                the configuration information for NAND module.
928   * @retval HAL status
929   */    
930 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
931 {
932   /* Check the NAND controller state */
933   if(hnand->State == HAL_NAND_STATE_BUSY)
934   {
935      return HAL_BUSY;
936   }
937
938   /* Update the NAND state */
939   hnand->State = HAL_NAND_STATE_BUSY;
940    
941   /* Enable ECC feature */
942   FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
943   
944   /* Update the NAND state */
945   hnand->State = HAL_NAND_STATE_READY;
946   
947   return HAL_OK;  
948 }
949
950
951 /**
952   * @brief  Disables dynamically FMC_NAND ECC feature.
953   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
954   *                the configuration information for NAND module.
955   * @retval HAL status
956   */  
957 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)  
958 {
959   /* Check the NAND controller state */
960   if(hnand->State == HAL_NAND_STATE_BUSY)
961   {
962      return HAL_BUSY;
963   }
964
965   /* Update the NAND state */
966   hnand->State = HAL_NAND_STATE_BUSY;
967     
968   /* Disable ECC feature */
969   FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
970   
971   /* Update the NAND state */
972   hnand->State = HAL_NAND_STATE_READY;
973   
974   return HAL_OK;  
975 }
976
977 /**
978   * @brief  Disables dynamically NAND ECC feature.
979   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
980   *                the configuration information for NAND module.
981   * @param  ECCval: pointer to ECC value 
982   * @param  Timeout: maximum timeout to wait    
983   * @retval HAL status
984   */
985 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
986 {
987   HAL_StatusTypeDef status = HAL_OK;
988   
989   /* Check the NAND controller state */
990   if(hnand->State == HAL_NAND_STATE_BUSY)
991   {
992      return HAL_BUSY;
993   }
994   
995   /* Update the NAND state */
996   hnand->State = HAL_NAND_STATE_BUSY;  
997    
998   /* Get NAND ECC value */
999   status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1000   
1001   /* Update the NAND state */
1002   hnand->State = HAL_NAND_STATE_READY;
1003
1004   return status;  
1005 }
1006                       
1007 /**
1008   * @}
1009   */
1010   
1011     
1012 /** @defgroup NAND_Group4 State functions 
1013  *  @brief   Peripheral State functions 
1014  *
1015 @verbatim   
1016   ==============================================================================
1017                          ##### NAND State functions #####
1018   ==============================================================================  
1019   [..]
1020     This subsection permits to get in run-time the status of the NAND controller 
1021     and the data flow.
1022
1023 @endverbatim
1024   * @{
1025   */
1026   
1027 /**
1028   * @brief  return the NAND state
1029   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
1030   *                the configuration information for NAND module.
1031   * @retval HAL state
1032   */
1033 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1034 {
1035   return hnand->State;
1036 }
1037
1038 /**
1039   * @}
1040   */  
1041
1042 /**
1043   * @}
1044   */
1045 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
1046 #endif /* HAL_NAND_MODULE_ENABLED  */
1047
1048 /**
1049   * @}
1050   */
1051
1052 /**
1053   * @}
1054   */
1055
1056 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/