]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F3/stm32f3xx_hal_nand.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F3 / stm32f3xx_hal_nand.c
1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_hal_nand.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    12-Sept-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 "stm32f3xx_hal.h"
87
88 /** @addtogroup STM32F3xx_HAL_Driver
89   * @{
90   */
91
92 /** @defgroup NAND NAND HAL module driver
93   * @brief NAND HAL module driver
94   * @{
95   */
96 #ifdef HAL_NAND_MODULE_ENABLED
97
98 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx)
99
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
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   */
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_Exported_Functions_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))  = 0x90;
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, size = 0, numPagesRead = 0, nandAddress = 0;
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   /* NAND raw address calculation */
438   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
439   
440   /* Page(s) read loop */  
441   while((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
442   {        
443     /* update the buffer size */
444     size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
445     
446     /* Send read page command sequence */
447     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;  
448    
449     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 
450     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress); 
451     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress); 
452     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
453   
454     /* for 512 and 1 GB devices, 4th cycle is required */    
455     if(hnand->Info.BlockNbr >= 1024)
456     {
457       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
458     }
459   
460     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = 0x30;
461       
462     /* Get Data into Buffer */    
463     for(; index < size; index++)
464     {
465       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
466     }
467     
468     /* Increment read pages number */
469     numPagesRead++;
470     
471     /* Decrement pages to read */
472     NumPageToRead--;
473     
474     /* Increment the NAND address */
475     nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
476     
477   }
478   
479   /* Update the NAND controller state */ 
480   hnand->State = HAL_NAND_STATE_READY;
481   
482   /* Process unlocked */
483   __HAL_UNLOCK(hnand);  
484     
485   return HAL_OK;
486
487 }
488
489 /**
490   * @brief  Write Page(s) to NAND memory block 
491   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
492   *                the configuration information for NAND module.
493   * @param  pAddress : pointer to NAND address structure
494   * @param  pBuffer : pointer to source buffer to write  
495   * @param  NumPageToWrite  : number of pages to write to block 
496   * @retval HAL status
497   */
498 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
499 {
500   __IO uint32_t index   = 0;
501   uint32_t timeout = 0;
502   uint32_t deviceAddress = 0, size = 0 , numPagesWritten = 0, nandAddress = 0;
503   
504   /* Process Locked */
505   __HAL_LOCK(hnand);  
506
507   /* Check the NAND controller state */
508   if(hnand->State == HAL_NAND_STATE_BUSY)
509   {
510      return HAL_BUSY;
511   }
512   
513   /* Identify the device address */
514   if(hnand->Init.NandBank == FMC_NAND_BANK2)
515   {
516     deviceAddress = NAND_DEVICE1;
517   }
518   else
519   {
520     deviceAddress = NAND_DEVICE2;
521   }
522   
523   /* Update the NAND controller state */ 
524   hnand->State = HAL_NAND_STATE_BUSY;
525   
526   /* NAND raw address calculation */
527   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
528   
529   /* Page(s) write loop */
530   while((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
531   {  
532     /* update the buffer size */
533     size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
534  
535     /* Send write page command sequence */
536     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
537     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x80;
538
539     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;  
540     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);  
541     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);  
542     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
543   
544     /* for 512 and 1 GB devices, 4th cycle is required */     
545     if(hnand->Info.BlockNbr >= 1024)
546     {
547       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
548     }
549   
550     /* Write data to memory */
551     for(; index < size; index++)
552     {
553       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
554     }
555    
556     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x10;
557     
558     /* Read status until NAND is ready */
559     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
560     {
561       /* Check for timeout value */
562       timeout = HAL_GetTick() + NAND_WRITE_TIMEOUT;
563     
564       if(HAL_GetTick() >= timeout)
565       {
566         return HAL_TIMEOUT; 
567       } 
568     }    
569  
570     /* Increment written pages number */
571     numPagesWritten++;
572     
573     /* Decrement pages to write */
574     NumPageToWrite--;
575     
576     /* Increment the NAND address */
577     nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
578       
579   }
580   
581   /* Update the NAND controller state */ 
582   hnand->State = HAL_NAND_STATE_READY;
583   
584   /* Process unlocked */
585   __HAL_UNLOCK(hnand);      
586   
587   return HAL_OK;
588 }
589
590
591 /**
592   * @brief  Read Spare area(s) from NAND memory 
593   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
594   *                the configuration information for NAND module.
595   * @param  pAddress : pointer to NAND address structure
596   * @param  pBuffer: pointer to source buffer to write  
597   * @param  NumSpareAreaToRead: Number of spare area to read  
598   * @retval HAL status
599 */
600 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
601 {
602   __IO uint32_t index   = 0; 
603   uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
604   
605   /* Process Locked */
606   __HAL_LOCK(hnand);  
607   
608   /* Check the NAND controller state */
609   if(hnand->State == HAL_NAND_STATE_BUSY)
610   {
611      return HAL_BUSY;
612   }
613   
614   /* Identify the device address */
615   if(hnand->Init.NandBank == FMC_NAND_BANK2)
616   {
617     deviceAddress = NAND_DEVICE1;
618   }
619   else
620   {
621     deviceAddress = NAND_DEVICE2;
622   }
623   
624   /* Update the NAND controller state */
625   hnand->State = HAL_NAND_STATE_BUSY; 
626   
627   /* NAND raw address calculation */
628   nandAddress = ARRAY_ADDRESS(pAddress, hnand);    
629   
630   /* Spare area(s) read loop */ 
631   while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
632   {     
633     
634     /* update the buffer size */
635     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
636     
637     /* Send read spare area command sequence */     
638     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
639
640     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; 
641     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);     
642     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);     
643     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
644   
645     /* for 512 and 1 GB devices, 4th cycle is required */    
646     if(hnand->Info.BlockNbr >= 1024)
647     {
648       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
649     } 
650
651     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x30;    
652     
653     /* Get Data into Buffer */
654     for ( ;index < size; index++)
655     {
656       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
657     }
658     
659     /* Increment read spare areas number */
660     numSpareAreaRead++;
661     
662     /* Decrement spare areas to read */
663     NumSpareAreaToRead--;
664     
665     /* Increment the NAND address */
666     nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
667   }
668   
669   /* Update the NAND controller state */
670   hnand->State = HAL_NAND_STATE_READY;
671   
672   /* Process unlocked */
673   __HAL_UNLOCK(hnand);     
674
675   return HAL_OK;  
676 }
677
678 /**
679   * @brief  Write Spare area(s) to NAND memory 
680   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
681   *                the configuration information for NAND module.
682   * @param  pAddress : pointer to NAND address structure
683   * @param  pBuffer : pointer to source buffer to write  
684   * @param  NumSpareAreaTowrite  : number of spare areas to write to block
685   * @retval HAL status
686   */
687 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
688 {
689   __IO uint32_t index = 0;
690   uint32_t timeout = 0;
691   uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
692
693   /* Process Locked */
694   __HAL_LOCK(hnand); 
695   
696   /* Check the NAND controller state */
697   if(hnand->State == HAL_NAND_STATE_BUSY)
698   {
699      return HAL_BUSY;
700   }
701   
702   /* Identify the device address */
703   if(hnand->Init.NandBank == FMC_NAND_BANK2)
704   {
705     deviceAddress = NAND_DEVICE1;
706   }
707   else
708   {
709     deviceAddress = NAND_DEVICE2;
710   }
711   
712   /* Update the FMC_NAND controller state */
713   hnand->State = HAL_NAND_STATE_BUSY;
714
715   /* NAND raw address calculation */
716   nandAddress = ARRAY_ADDRESS(pAddress, hnand);  
717   
718   /* Spare area(s) write loop */
719   while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
720   {  
721     /* update the buffer size */
722     size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
723
724     /* Send write Spare area command sequence */
725     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
726     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x80;
727
728     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;  
729     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);  
730     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);  
731     *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress); 
732   
733     /* for 512 and 1 GB devices, 4th cycle is required */     
734     if(hnand->Info.BlockNbr >= 1024)
735     {
736       *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
737     }
738   
739     /* Write data to memory */
740     for(; index < size; index++)
741     {
742       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
743     }
744    
745     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x10;
746     
747    
748     /* Read status until NAND is ready */
749     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
750     {
751       /* Check for timeout value */
752       timeout = HAL_GetTick() + NAND_WRITE_TIMEOUT;
753     
754       if(HAL_GetTick() >= timeout)
755       {
756         return HAL_TIMEOUT; 
757       } 
758     }
759
760     /* Increment written spare areas number */
761     numSpareAreaWritten++;
762     
763     /* Decrement spare areas to write */
764     NumSpareAreaTowrite--;
765     
766     /* Increment the NAND address */
767     nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));   
768       
769   }
770
771   /* Update the NAND controller state */
772   hnand->State = HAL_NAND_STATE_READY;
773
774   /* Process unlocked */
775   __HAL_UNLOCK(hnand);
776     
777   return HAL_OK;  
778 }
779
780 /**
781   * @brief  NAND memory Block erase 
782   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
783   *                the configuration information for NAND module.
784   * @param  pAddress : pointer to NAND address structure
785   * @retval HAL status
786   */
787 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
788 {
789   uint32_t DeviceAddress = 0;
790   
791   /* Process Locked */
792   __HAL_LOCK(hnand);
793   
794   /* Check the NAND controller state */
795   if(hnand->State == HAL_NAND_STATE_BUSY)
796   {
797      return HAL_BUSY;
798   }
799   
800   /* Identify the device address */
801   if(hnand->Init.NandBank == FMC_NAND_BANK2)
802   {
803     DeviceAddress = NAND_DEVICE1;
804   }
805   else
806   {
807     DeviceAddress = NAND_DEVICE2;
808   }
809   
810   /* Update the NAND controller state */
811   hnand->State = HAL_NAND_STATE_BUSY;  
812   
813   /* Send Erase block command sequence */
814   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0x60;
815
816   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
817   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
818   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
819   
820   /* for 512 and 1 GB devices, 4th cycle is required */     
821   if(hnand->Info.BlockNbr >= 1024)
822   {
823     *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
824   }  
825                 
826   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0xD0; 
827   
828   /* Update the NAND controller state */
829   hnand->State = HAL_NAND_STATE_READY;
830   
831   /* Process unlocked */
832   __HAL_UNLOCK(hnand);    
833   
834   return HAL_OK;  
835 }
836
837
838 /**
839   * @brief  NAND memory read status 
840   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
841   *                the configuration information for NAND module.
842   * @retval NAND status
843   */
844 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
845 {
846   uint32_t data = 0;
847   uint32_t DeviceAddress = 0;
848   
849   /* Identify the device address */
850   if(hnand->Init.NandBank == FMC_NAND_BANK2)
851   {
852     DeviceAddress = NAND_DEVICE1;
853   }
854   else
855   {
856     DeviceAddress = NAND_DEVICE2;
857   } 
858
859   /* Send Read status operation command */
860   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0x70;
861   
862   /* Read status register data */
863   data = *(__IO uint8_t *)DeviceAddress;
864
865   /* Return the status */
866   if((data & NAND_ERROR) == NAND_ERROR)
867   {
868     return NAND_ERROR;
869   } 
870   else if((data & NAND_READY) == NAND_READY)
871   {
872     return NAND_READY;
873   }
874
875   return NAND_BUSY; 
876  
877 }
878
879 /**
880   * @brief  Increment the NAND memory address
881   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
882   *                the configuration information for NAND module.
883   * @param pAddress: pointer to NAND adress structure
884   * @retval The new status of the increment address operation. It can be:
885   *           - NAND_VALID_ADDRESS: When the new address is valid address
886   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
887   */
888 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
889 {
890   uint32_t status = NAND_VALID_ADDRESS;
891  
892   /* Increment page address */
893   pAddress->Page++;
894
895   /* Check NAND address is valid */
896   if(pAddress->Page == hnand->Info.BlockSize)
897   {
898     pAddress->Page = 0;
899     pAddress->Block++;
900     
901     if(pAddress->Block == hnand->Info.ZoneSize)
902     {
903       pAddress->Block = 0;
904       pAddress->Zone++;
905
906       if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
907       {
908         status = NAND_INVALID_ADDRESS;
909       }
910     }
911   } 
912   
913   return (status);
914 }
915
916
917 /**
918   * @}
919   */
920
921 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions 
922  *  @brief   management functions 
923  *
924 @verbatim   
925   ==============================================================================
926                          ##### NAND Control functions #####
927   ==============================================================================  
928   [..]
929     This subsection provides a set of functions allowing to control dynamically
930     the NAND interface.
931
932 @endverbatim
933   * @{
934   */ 
935
936     
937 /**
938   * @brief  Enables dynamically NAND ECC feature.
939   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
940   *                the configuration information for NAND module.
941   * @retval HAL status
942   */    
943 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
944 {
945   /* Check the NAND controller state */
946   if(hnand->State == HAL_NAND_STATE_BUSY)
947   {
948      return HAL_BUSY;
949   }
950
951   /* Update the NAND state */
952   hnand->State = HAL_NAND_STATE_BUSY;
953    
954   /* Enable ECC feature */
955   FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
956   
957   /* Update the NAND state */
958   hnand->State = HAL_NAND_STATE_READY;
959   
960   return HAL_OK;  
961 }
962
963
964 /**
965   * @brief  Disables dynamically FMC_NAND ECC feature.
966   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
967   *                the configuration information for NAND module.
968   * @retval HAL status
969   */  
970 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)  
971 {
972   /* Check the NAND controller state */
973   if(hnand->State == HAL_NAND_STATE_BUSY)
974   {
975      return HAL_BUSY;
976   }
977
978   /* Update the NAND state */
979   hnand->State = HAL_NAND_STATE_BUSY;
980     
981   /* Disable ECC feature */
982   FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
983   
984   /* Update the NAND state */
985   hnand->State = HAL_NAND_STATE_READY;
986   
987   return HAL_OK;  
988 }
989
990 /**
991   * @brief  Disables dynamically NAND ECC feature.
992   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
993   *                the configuration information for NAND module.
994   * @param  ECCval: pointer to ECC value 
995   * @param  Timeout: maximum timeout to wait    
996   * @retval HAL status
997   */
998 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
999 {
1000   HAL_StatusTypeDef status = HAL_OK;
1001   
1002   /* Check the NAND controller state */
1003   if(hnand->State == HAL_NAND_STATE_BUSY)
1004   {
1005      return HAL_BUSY;
1006   }
1007   
1008   /* Update the NAND state */
1009   hnand->State = HAL_NAND_STATE_BUSY;  
1010    
1011   /* Get NAND ECC value */
1012   status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1013   
1014   /* Update the NAND state */
1015   hnand->State = HAL_NAND_STATE_READY;
1016
1017   return status;  
1018 }
1019                       
1020 /**
1021   * @}
1022   */
1023   
1024     
1025 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions 
1026  *  @brief   Peripheral State functions 
1027  *
1028 @verbatim   
1029   ==============================================================================
1030                          ##### NAND State functions #####
1031   ==============================================================================  
1032   [..]
1033     This subsection permits to get in run-time the status of the NAND controller 
1034     and the data flow.
1035
1036 @endverbatim
1037   * @{
1038   */
1039   
1040 /**
1041   * @brief  return the NAND state
1042   * @param  hnand: pointer to a NAND_HandleTypeDef structure that contains
1043   *                the configuration information for NAND module.
1044   * @retval HAL state
1045   */
1046 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1047 {
1048   return hnand->State;
1049 }
1050
1051 /**
1052   * @}
1053   */  
1054
1055 /**
1056   * @}
1057   */
1058 #endif /* STM32F302xE || STM32F303xE || STM32F398xx */
1059 #endif /* HAL_NAND_MODULE_ENABLED  */
1060
1061 /**
1062   * @}
1063   */
1064
1065 /**
1066   * @}
1067   */
1068
1069 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/