1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_nand.c
4   * @author  MCD Application Team
5   * @brief   NAND HAL module driver.
6   *          This file provides a generic firmware to drive NAND memories mounted
7   *          as external device.
8   *
9   @verbatim
10   ==============================================================================
11                          ##### How to use this driver #####
12   ==============================================================================
13     [..]
14       This driver is a generic layered driver which contains a set of APIs used to
15       control NAND flash memories. It uses the FMC layer functions to interface
16       with NAND devices. This driver is used as follows:
17 
18       (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
19           with control and timing parameters for both common and attribute spaces.
20 
21       (+) Read NAND flash memory maker and device IDs using the function
22           HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
23           structure declared by the function caller.
24 
25       (+) Access NAND flash memory by read/write operations using the functions
26           HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
27           HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
28           HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
29           HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
30           to read/write page(s)/spare area(s). These functions use specific device
31           information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
32           structure. The read/write address information is contained by the Nand_Address_Typedef
33           structure passed as parameter.
34 
35       (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
36 
37       (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
38           The erase block address information is contained in the Nand_Address_Typedef
39           structure passed as parameter.
40 
41       (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
42 
43       (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
44           HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
45           feature or the function HAL_NAND_GetECC() to get the ECC correction code.
46 
47       (+) You can monitor the NAND device HAL state by calling the function
48           HAL_NAND_GetState()
49 
50     [..]
51       (@) This driver is a set of generic APIs which handle standard NAND flash operations.
52           If a NAND flash device contains different operations and/or implementations,
53           it should be implemented separately.
54 
55   @endverbatim
56   ******************************************************************************
57   * @attention
58   *
59   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
60   *
61   * Redistribution and use in source and binary forms, with or without modification,
62   * are permitted provided that the following conditions are met:
63   *   1. Redistributions of source code must retain the above copyright notice,
64   *      this list of conditions and the following disclaimer.
65   *   2. Redistributions in binary form must reproduce the above copyright notice,
66   *      this list of conditions and the following disclaimer in the documentation
67   *      and/or other materials provided with the distribution.
68   *   3. Neither the name of STMicroelectronics nor the names of its contributors
69   *      may be used to endorse or promote products derived from this software
70   *      without specific prior written permission.
71   *
72   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
73   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
76   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
78   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
79   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
80   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
81   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82   *
83   ******************************************************************************
84   */
85 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32l4xx_hal.h"
88 
89 #if defined(FMC_BANK3)
90 
91 /** @addtogroup STM32L4xx_HAL_Driver
92   * @{
93   */
94 
95 #ifdef HAL_NAND_MODULE_ENABLED
96 
97 /** @defgroup NAND NAND
98   * @brief NAND HAL module driver
99   * @{
100   */
101 
102 /* Private typedef -----------------------------------------------------------*/
103 /* Private Constants ------------------------------------------------------------*/
104 /* Private macro -------------------------------------------------------------*/
105 /* Private variables ---------------------------------------------------------*/
106 /* Private function prototypes -----------------------------------------------*/
107 /* Exported functions ---------------------------------------------------------*/
108 
109 /** @defgroup NAND_Exported_Functions NAND Exported Functions
110   * @{
111   */
112 
113 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
114   * @brief    Initialization and Configuration functions
115   *
116   @verbatim
117   ==============================================================================
118             ##### NAND Initialization and de-initialization functions #####
119   ==============================================================================
120   [..]
121     This section provides functions allowing to initialize/de-initialize
122     the NAND memory
123 
124 @endverbatim
125   * @{
126   */
127 
128 /**
129   * @brief  Perform NAND memory Initialization sequence
130   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
131   *                the configuration information for NAND module.
132   * @param  ComSpace_Timing pointer to Common space timing structure
133   * @param  AttSpace_Timing pointer to Attribute space timing structure
134   * @retval HAL status
135   */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)136 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
137 {
138   /* Check the NAND handle state */
139   if(hnand == NULL)
140   {
141      return HAL_ERROR;
142   }
143 
144   if(hnand->State == HAL_NAND_STATE_RESET)
145   {
146     /* Allocate lock resource and initialize it */
147     hnand->Lock = HAL_UNLOCKED;
148     /* Initialize the low level hardware (MSP) */
149     HAL_NAND_MspInit(hnand);
150   }
151 
152   /* Initialize NAND control Interface */
153   FMC_NAND_Init(hnand->Instance, &(hnand->Init));
154 
155   /* Initialize NAND common space timing Interface */
156   FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
157 
158   /* Initialize NAND attribute space timing Interface */
159   FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
160 
161   /* Enable the NAND device */
162   __FMC_NAND_ENABLE(hnand->Instance);
163 
164   /* Update the NAND controller state */
165   hnand->State = HAL_NAND_STATE_READY;
166 
167   return HAL_OK;
168 }
169 
170 /**
171   * @brief  Perform NAND memory De-Initialization sequence
172   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
173   *                the configuration information for NAND module.
174   * @retval HAL status
175   */
HAL_NAND_DeInit(NAND_HandleTypeDef * hnand)176 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
177 {
178   /* Initialize the low level hardware (MSP) */
179   HAL_NAND_MspDeInit(hnand);
180 
181   /* Configure the NAND registers with their reset values */
182   FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
183 
184   /* Reset the NAND controller state */
185   hnand->State = HAL_NAND_STATE_RESET;
186 
187   /* Release Lock */
188   __HAL_UNLOCK(hnand);
189 
190   return HAL_OK;
191 }
192 
193 /**
194   * @brief  Initialize the NAND MSP
195   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
196   *                the configuration information for NAND module.
197   * @retval None
198   */
HAL_NAND_MspInit(NAND_HandleTypeDef * hnand)199 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
200 {
201   /* Prevent unused argument(s) compilation warning */
202   UNUSED(hnand);
203 
204   /* NOTE : This function should not be modified, when the callback is needed,
205             the HAL_NAND_MspInit could be implemented in the user file
206    */
207 }
208 
209 /**
210   * @brief  DeInitialize the NAND MSP
211   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
212   *                the configuration information for NAND module.
213   * @retval None
214   */
HAL_NAND_MspDeInit(NAND_HandleTypeDef * hnand)215 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
216 {
217   /* Prevent unused argument(s) compilation warning */
218   UNUSED(hnand);
219 
220   /* NOTE : This function should not be modified, when the callback is needed,
221             the HAL_NAND_MspDeInit could be implemented in the user file
222    */
223 }
224 
225 
226 /**
227   * @brief  This function handles NAND device interrupt request.
228   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
229   *                the configuration information for NAND module.
230   * @retval HAL status
231 */
HAL_NAND_IRQHandler(NAND_HandleTypeDef * hnand)232 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
233 {
234   /* Check NAND interrupt Rising edge flag */
235   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
236   {
237     /* NAND interrupt callback*/
238     HAL_NAND_ITCallback(hnand);
239 
240     /* Clear NAND interrupt Rising edge pending bit */
241     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
242   }
243 
244   /* Check NAND interrupt Level flag */
245   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
246   {
247     /* NAND interrupt callback*/
248     HAL_NAND_ITCallback(hnand);
249 
250     /* Clear NAND interrupt Level pending bit */
251     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
252   }
253 
254   /* Check NAND interrupt Falling edge flag */
255   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
256   {
257     /* NAND interrupt callback*/
258     HAL_NAND_ITCallback(hnand);
259 
260     /* Clear NAND interrupt Falling edge pending bit */
261     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
262   }
263 
264   /* Check NAND interrupt FIFO empty flag */
265   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
266   {
267     /* NAND interrupt callback*/
268     HAL_NAND_ITCallback(hnand);
269 
270     /* Clear NAND interrupt FIFO empty pending bit */
271     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
272   }
273 
274 }
275 
276 /**
277   * @brief  NAND interrupt feature callback
278   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
279   *                the configuration information for NAND module.
280   * @retval None
281   */
HAL_NAND_ITCallback(NAND_HandleTypeDef * hnand)282 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
283 {
284   /* Prevent unused argument(s) compilation warning */
285   UNUSED(hnand);
286 
287   /* NOTE : This function should not be modified, when the callback is needed,
288             the HAL_NAND_ITCallback could be implemented in the user file
289    */
290 }
291 
292 /**
293   * @}
294   */
295 
296 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
297   * @brief    Input Output and memory control functions
298   *
299   @verbatim
300   ==============================================================================
301                     ##### NAND Input and Output functions #####
302   ==============================================================================
303   [..]
304     This section provides functions allowing to use and control the NAND
305     memory
306 
307 @endverbatim
308   * @{
309   */
310 
311 /**
312   * @brief  Read the NAND memory electronic signature
313   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
314   *                the configuration information for NAND module.
315   * @param  pNAND_ID NAND ID structure
316   * @retval HAL status
317   */
HAL_NAND_Read_ID(NAND_HandleTypeDef * hnand,NAND_IDTypeDef * pNAND_ID)318 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
319 {
320   __IO uint32_t data = 0;
321   __IO uint32_t data1 = 0;
322   uint32_t deviceAddress = 0;
323 
324   /* Process Locked */
325   __HAL_LOCK(hnand);
326 
327   /* Check the NAND controller state */
328   if(hnand->State == HAL_NAND_STATE_BUSY)
329   {
330      return HAL_BUSY;
331   }
332 
333   /* Identify the device address */
334   deviceAddress = NAND_DEVICE;
335 
336   /* Update the NAND controller state */
337   hnand->State = HAL_NAND_STATE_BUSY;
338 
339   /* Send Read ID command sequence */
340   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_READID;
341   __DSB();
342   *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
343   __DSB();
344 
345   /* Read the electronic signature from NAND flash */
346   if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
347   {
348     data = *(__IO uint32_t *)deviceAddress;
349 
350     /* Return the data read */
351     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
352     pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
353     pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
354     pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
355   }
356   else
357   {
358     data = *(__IO uint32_t *)deviceAddress;
359     data1 = *((__IO uint32_t *)deviceAddress + 4);
360 
361     /* Return the data read */
362     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
363     pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
364     pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
365     pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
366   }
367 
368   /* Update the NAND controller state */
369   hnand->State = HAL_NAND_STATE_READY;
370 
371   /* Process unlocked */
372   __HAL_UNLOCK(hnand);
373 
374   return HAL_OK;
375 }
376 
377 /**
378   * @brief  NAND memory reset
379   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
380   *                the configuration information for NAND module.
381   * @retval HAL status
382   */
HAL_NAND_Reset(NAND_HandleTypeDef * hnand)383 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
384 {
385   uint32_t deviceAddress = 0;
386 
387   /* Process Locked */
388   __HAL_LOCK(hnand);
389 
390   /* Check the NAND controller state */
391   if(hnand->State == HAL_NAND_STATE_BUSY)
392   {
393      return HAL_BUSY;
394   }
395 
396   /* Identify the device address */
397   deviceAddress = NAND_DEVICE;
398 
399   /* Update the NAND controller state */
400   hnand->State = HAL_NAND_STATE_BUSY;
401 
402   /* Send NAND reset command */
403   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
404 
405   /* Update the NAND controller state */
406   hnand->State = HAL_NAND_STATE_READY;
407 
408   /* Process unlocked */
409   __HAL_UNLOCK(hnand);
410 
411   return HAL_OK;
412 
413 }
414 
415 /**
416   * @brief  Configure the device: Enter the physical parameters of the device
417   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
418   *                the configuration information for NAND module.
419   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
420   * @retval HAL status
421   */
HAL_NAND_ConfigDevice(NAND_HandleTypeDef * hnand,NAND_DeviceConfigTypeDef * pDeviceConfig)422 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
423 {
424   hnand->Config.PageSize           = pDeviceConfig->PageSize;
425   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
426   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
427   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
428   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
429   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
430   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
431 
432   return HAL_OK;
433 }
434 
435 
436 /**
437   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
438   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
439   *                the configuration information for NAND module.
440   * @param  pAddress  pointer to NAND address structure
441   * @param  pBuffer  pointer to destination read buffer
442   * @param  NumPageToRead  number of pages to read from block
443   * @retval HAL status
444   */
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToRead)445 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
446 {
447   __IO uint32_t index  = 0;
448   uint32_t tickstart = 0U;
449   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
450 
451   /* Process Locked */
452   __HAL_LOCK(hnand);
453 
454   /* Check the NAND controller state */
455   if(hnand->State == HAL_NAND_STATE_BUSY)
456   {
457      return HAL_BUSY;
458   }
459 
460   /* Identify the device address */
461   deviceAddress = NAND_DEVICE;
462 
463   /* Update the NAND controller state */
464   hnand->State = HAL_NAND_STATE_BUSY;
465 
466   /* NAND raw address calculation */
467   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
468 
469   /* Page(s) read loop */
470   while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
471   {
472     /* update the buffer size */
473     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
474 
475     /* Send read page command sequence */
476     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
477     __DSB();
478 
479     /* Cards with page size <= 512 bytes */
480     if ((hnand->Config.PageSize) <= 512)
481     {
482       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
483       {
484         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
485         __DSB();
486         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
487         __DSB();
488         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
489         __DSB();
490       }
491       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
492       {
493         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
494         __DSB();
495         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
496         __DSB();
497         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
498         __DSB();
499         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
500         __DSB();
501       }
502     }
503     else /* (hnand->Config.PageSize) > 512 */
504     {
505       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
506       {
507         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
508         __DSB();
509         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
510         __DSB();
511         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
512         __DSB();
513         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
514         __DSB();
515       }
516       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
517       {
518         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
519         __DSB();
520         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
521         __DSB();
522         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
523         __DSB();
524         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
525         __DSB();
526         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
527         __DSB();
528       }
529     }
530 
531     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
532     __DSB();
533 
534 
535     if (hnand->Config.ExtraCommandEnable == ENABLE)
536     {
537       /* Get tick */
538       tickstart = HAL_GetTick();
539 
540       /* Read status until NAND is ready */
541       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
542       {
543         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
544         {
545           return HAL_TIMEOUT;
546         }
547       }
548 
549       /* Go back to read mode */
550       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
551       __DSB();
552     }
553 
554     /* Get Data into Buffer */
555     for(; index < size; index++)
556     {
557       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
558     }
559 
560     /* Increment read pages number */
561     numPagesRead++;
562 
563     /* Decrement pages to read */
564     NumPageToRead--;
565 
566     /* Increment the NAND address */
567     nandAddress = (uint32_t)(nandAddress + 1);
568   }
569 
570   /* Update the NAND controller state */
571   hnand->State = HAL_NAND_STATE_READY;
572 
573   /* Process unlocked */
574   __HAL_UNLOCK(hnand);
575 
576   return HAL_OK;
577 }
578 
579 /**
580   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
581   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
582   *                the configuration information for NAND module.
583   * @param  pAddress  pointer to NAND address structure
584   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
585   * @param  NumPageToRead  number of pages to read from block
586   * @retval HAL status
587   */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)588 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
589 {
590   __IO uint32_t index  = 0;
591   uint32_t tickstart = 0;
592   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
593 
594   /* Process Locked */
595   __HAL_LOCK(hnand);
596 
597   /* Check the NAND controller state */
598   if (hnand->State == HAL_NAND_STATE_BUSY)
599   {
600     return HAL_BUSY;
601   }
602 
603   /* Identify the device address */
604   deviceAddress = NAND_DEVICE;
605 
606   /* Update the NAND controller state */
607   hnand->State = HAL_NAND_STATE_BUSY;
608 
609   /* NAND raw address calculation */
610   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
611 
612   /* Page(s) read loop */
613   while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
614   {
615     /* update the buffer size */
616     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
617 
618     /* Send read page command sequence */
619     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
620     __DSB();
621 
622     /* Cards with page size <= 512 bytes */
623     if ((hnand->Config.PageSize) <= 512)
624     {
625       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
626       {
627         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
628         __DSB();
629         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
630         __DSB();
631         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
632         __DSB();
633       }
634       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
635       {
636         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
637         __DSB();
638         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
639         __DSB();
640         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
641         __DSB();
642         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
643         __DSB();
644       }
645     }
646     else /* (hnand->Config.PageSize) > 512 */
647     {
648       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
649       {
650         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
651         __DSB();
652         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
653         __DSB();
654         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
655         __DSB();
656         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
657         __DSB();
658       }
659       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
660       {
661         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
662         __DSB();
663         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
664         __DSB();
665         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
666         __DSB();
667         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
668         __DSB();
669         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
670         __DSB();
671       }
672     }
673 
674     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
675     __DSB();
676 
677     if (hnand->Config.ExtraCommandEnable == ENABLE)
678     {
679       /* Get tick */
680       tickstart = HAL_GetTick();
681 
682       /* Read status until NAND is ready */
683       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
684       {
685         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
686         {
687           return HAL_TIMEOUT;
688         }
689       }
690 
691       /* Go back to read mode */
692       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
693       __DSB();
694     }
695 
696     /* Get Data into Buffer */
697     for (; index < size; index++)
698     {
699       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
700     }
701 
702     /* Increment read pages number */
703     numPagesRead++;
704 
705     /* Decrement pages to read */
706     NumPageToRead--;
707 
708     /* Increment the NAND address */
709     nandAddress = (uint32_t)(nandAddress + 1);
710   }
711 
712   /* Update the NAND controller state */
713   hnand->State = HAL_NAND_STATE_READY;
714 
715   /* Process unlocked */
716   __HAL_UNLOCK(hnand);
717 
718   return HAL_OK;
719 }
720 
721 /**
722   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
723   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
724   *                the configuration information for NAND module.
725   * @param  pAddress  pointer to NAND address structure
726   * @param  pBuffer  pointer to source buffer to write
727   * @param  NumPageToWrite   number of pages to write to block
728   * @retval HAL status
729   */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)730 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
731 {
732   __IO uint32_t index = 0;
733   uint32_t tickstart = 0;
734   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
735 
736   /* Process Locked */
737   __HAL_LOCK(hnand);
738 
739   /* Check the NAND controller state */
740   if(hnand->State == HAL_NAND_STATE_BUSY)
741   {
742      return HAL_BUSY;
743   }
744 
745   /* Identify the device address */
746   deviceAddress = NAND_DEVICE;
747 
748   /* Update the NAND controller state */
749   hnand->State = HAL_NAND_STATE_BUSY;
750 
751   /* NAND raw address calculation */
752   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
753 
754   /* Page(s) write loop */
755   while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
756   {
757     /* update the buffer size */
758     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
759 
760     /* Send write page command sequence */
761     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
762     __DSB();
763     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
764     __DSB();
765 
766     /* Cards with page size <= 512 bytes */
767     if ((hnand->Config.PageSize) <= 512)
768     {
769       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
770       {
771         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
772         __DSB();
773         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
774         __DSB();
775         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
776         __DSB();
777       }
778       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
779       {
780         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
781         __DSB();
782         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
783         __DSB();
784         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
785         __DSB();
786         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
787         __DSB();
788       }
789     }
790     else /* (hnand->Config.PageSize) > 512 */
791     {
792       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
793       {
794         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
795         __DSB();
796         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
797         __DSB();
798         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
799         __DSB();
800         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
801         __DSB();
802       }
803       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
804       {
805         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
806         __DSB();
807         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
808         __DSB();
809         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
810         __DSB();
811         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
812         __DSB();
813         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
814         __DSB();
815       }
816     }
817 
818     /* Write data to memory */
819     for (; index < size; index++)
820     {
821       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
822       __DSB();
823     }
824 
825     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
826     __DSB();
827 
828     /* Get tick */
829     tickstart = HAL_GetTick();
830 
831     /* Read status until NAND is ready */
832     while (HAL_NAND_Read_Status(hnand) != NAND_READY)
833     {
834       if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
835       {
836         return HAL_TIMEOUT;
837       }
838     }
839 
840     /* Increment written pages number */
841     numPagesWritten++;
842 
843     /* Decrement pages to write */
844     NumPageToWrite--;
845 
846     /* Increment the NAND address */
847     nandAddress = (uint32_t)(nandAddress + 1);
848   }
849 
850   /* Update the NAND controller state */
851   hnand->State = HAL_NAND_STATE_READY;
852 
853   /* Process unlocked */
854   __HAL_UNLOCK(hnand);
855 
856   return HAL_OK;
857 }
858 
859 /**
860   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
861   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
862   *                the configuration information for NAND module.
863   * @param  pAddress  pointer to NAND address structure
864   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
865   * @param  NumPageToWrite   number of pages to write to block
866   * @retval HAL status
867   */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)868 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
869 {
870   __IO uint32_t index = 0;
871   uint32_t tickstart = 0;
872   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
873 
874   /* Process Locked */
875   __HAL_LOCK(hnand);
876 
877   /* Check the NAND controller state */
878   if (hnand->State == HAL_NAND_STATE_BUSY)
879   {
880     return HAL_BUSY;
881   }
882 
883   /* Identify the device address */
884   deviceAddress = NAND_DEVICE;
885 
886   /* Update the NAND controller state */
887   hnand->State = HAL_NAND_STATE_BUSY;
888 
889   /* NAND raw address calculation */
890   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
891 
892   /* Page(s) write loop */
893   while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
894   {
895     /* update the buffer size */
896     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
897 
898     /* Send write page command sequence */
899     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
900     __DSB();
901     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
902     __DSB();
903 
904     /* Cards with page size <= 512 bytes */
905     if ((hnand->Config.PageSize) <= 512)
906     {
907       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
908       {
909         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
910         __DSB();
911         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
912         __DSB();
913         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
914         __DSB();
915       }
916       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
917       {
918         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
919         __DSB();
920         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
921         __DSB();
922         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
923         __DSB();
924         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
925         __DSB();
926       }
927     }
928     else /* (hnand->Config.PageSize) > 512 */
929     {
930       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
931       {
932         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
933         __DSB();
934         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
935         __DSB();
936         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
937         __DSB();
938         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
939         __DSB();
940       }
941       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
942       {
943         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
944         __DSB();
945         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
946         __DSB();
947         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
948         __DSB();
949         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
950         __DSB();
951         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
952         __DSB();
953       }
954     }
955 
956     /* Write data to memory */
957     for(; index < size; index++)
958     {
959       *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
960       __DSB();
961     }
962 
963     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
964     __DSB();
965 
966     /* Get tick */
967     tickstart = HAL_GetTick();
968 
969     /* Read status until NAND is ready */
970     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
971     {
972       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
973       {
974         return HAL_TIMEOUT;
975       }
976     }
977 
978     /* Increment written pages number */
979     numPagesWritten++;
980 
981     /* Decrement pages to write */
982     NumPageToWrite--;
983 
984     /* Increment the NAND address */
985     nandAddress = (uint32_t)(nandAddress + 1);
986   }
987 
988   /* Update the NAND controller state */
989   hnand->State = HAL_NAND_STATE_READY;
990 
991   /* Process unlocked */
992   __HAL_UNLOCK(hnand);
993 
994   return HAL_OK;
995 }
996 
997 /**
998   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
999   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1000   *                the configuration information for NAND module.
1001   * @param  pAddress  pointer to NAND address structure
1002   * @param  pBuffer pointer to source buffer to write
1003   * @param  NumSpareAreaToRead Number of spare area to read
1004   * @retval HAL status
1005 */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1006 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1007 {
1008   __IO uint32_t index   = 0;
1009   uint32_t tickstart = 0U;
1010   uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1011 
1012   /* Process Locked */
1013   __HAL_LOCK(hnand);
1014 
1015   /* Check the NAND controller state */
1016   if (hnand->State == HAL_NAND_STATE_BUSY)
1017   {
1018     return HAL_BUSY;
1019   }
1020 
1021   /* Identify the device address */
1022   deviceAddress = NAND_DEVICE;
1023 
1024   /* Update the NAND controller state */
1025   hnand->State = HAL_NAND_STATE_BUSY;
1026 
1027   /* NAND raw address calculation */
1028   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1029 
1030   /* Column in page address */
1031   columnAddress = COLUMN_ADDRESS(hnand);
1032 
1033   /* Spare area(s) read loop */
1034   while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1035   {
1036     /* update the buffer size */
1037     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1038 
1039     /* Cards with page size <= 512 bytes */
1040     if ((hnand->Config.PageSize) <= 512)
1041     {
1042       /* Send read spare area command sequence */
1043       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1044       __DSB();
1045 
1046       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1047       {
1048         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1049         __DSB();
1050         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1051         __DSB();
1052         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1053         __DSB();
1054       }
1055       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1056       {
1057         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1058         __DSB();
1059         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1060         __DSB();
1061         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1062         __DSB();
1063         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1064         __DSB();
1065       }
1066     }
1067     else /* (hnand->Config.PageSize) > 512 */
1068     {
1069       /* Send read spare area command sequence */
1070       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1071       __DSB();
1072 
1073       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1074       {
1075         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1076         __DSB();
1077         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1078         __DSB();
1079         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1080         __DSB();
1081         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1082         __DSB();
1083       }
1084       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1085       {
1086         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1087         __DSB();
1088         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1089         __DSB();
1090         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1091         __DSB();
1092         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1093         __DSB();
1094         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1095         __DSB();
1096       }
1097     }
1098 
1099     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1100     __DSB();
1101 
1102     if (hnand->Config.ExtraCommandEnable == ENABLE)
1103     {
1104       /* Get tick */
1105       tickstart = HAL_GetTick();
1106 
1107       /* Read status until NAND is ready */
1108       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1109       {
1110         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1111         {
1112           return HAL_TIMEOUT;
1113         }
1114       }
1115 
1116       /* Go back to read mode */
1117       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1118       __DSB();
1119     }
1120 
1121     /* Get Data into Buffer */
1122     for (; index < size; index++)
1123     {
1124       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
1125     }
1126 
1127     /* Increment read spare areas number */
1128     numSpareAreaRead++;
1129 
1130     /* Decrement spare areas to read */
1131     NumSpareAreaToRead--;
1132 
1133     /* Increment the NAND address */
1134     nandAddress = (uint32_t)(nandAddress + 1);
1135   }
1136 
1137   /* Update the NAND controller state */
1138   hnand->State = HAL_NAND_STATE_READY;
1139 
1140   /* Process unlocked */
1141   __HAL_UNLOCK(hnand);
1142 
1143   return HAL_OK;
1144 }
1145 
1146 /**
1147   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
1148   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1149   *                the configuration information for NAND module.
1150   * @param  pAddress  pointer to NAND address structure
1151   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1152   * @param  NumSpareAreaToRead Number of spare area to read
1153   * @retval HAL status
1154 */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1155 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1156 {
1157   __IO uint32_t index = 0;
1158   uint32_t tickstart = 0U;
1159   uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1160 
1161   /* Process Locked */
1162   __HAL_LOCK(hnand);
1163 
1164   /* Check the NAND controller state */
1165   if(hnand->State == HAL_NAND_STATE_BUSY)
1166   {
1167      return HAL_BUSY;
1168   }
1169 
1170   /* Identify the device address */
1171   deviceAddress = NAND_DEVICE;
1172 
1173   /* Update the NAND controller state */
1174   hnand->State = HAL_NAND_STATE_BUSY;
1175 
1176   /* NAND raw address calculation */
1177   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1178 
1179   /* Column in page address */
1180   columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1181 
1182   /* Spare area(s) read loop */
1183   while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1184   {
1185     /* update the buffer size */
1186     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1187 
1188     /* Cards with page size <= 512 bytes */
1189     if ((hnand->Config.PageSize) <= 512)
1190     {
1191       /* Send read spare area command sequence */
1192       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1193       __DSB();
1194 
1195       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1196       {
1197         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1198         __DSB();
1199         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1200         __DSB();
1201         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1202         __DSB();
1203       }
1204       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1205       {
1206         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1207         __DSB();
1208         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1209         __DSB();
1210         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1211         __DSB();
1212         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1213         __DSB();
1214       }
1215     }
1216     else /* (hnand->Config.PageSize) > 512 */
1217     {
1218       /* Send read spare area command sequence */
1219       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1220       __DSB();
1221 
1222       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1223       {
1224         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1225         __DSB();
1226         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1227         __DSB();
1228         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1229         __DSB();
1230         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1231         __DSB();
1232       }
1233       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1234       {
1235         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1236         __DSB();
1237         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1238         __DSB();
1239         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1240         __DSB();
1241         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1242         __DSB();
1243         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1244         __DSB();
1245       }
1246     }
1247 
1248     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1249     __DSB();
1250 
1251     if (hnand->Config.ExtraCommandEnable == ENABLE)
1252     {
1253       /* Get tick */
1254       tickstart = HAL_GetTick();
1255 
1256       /* Read status until NAND is ready */
1257       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1258       {
1259         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1260         {
1261           return HAL_TIMEOUT;
1262         }
1263       }
1264 
1265       /* Go back to read mode */
1266       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1267       __DSB();
1268     }
1269 
1270     /* Get Data into Buffer */
1271     for ( ;index < size; index++)
1272     {
1273       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
1274     }
1275 
1276     /* Increment read spare areas number */
1277     numSpareAreaRead++;
1278 
1279     /* Decrement spare areas to read */
1280     NumSpareAreaToRead--;
1281 
1282     /* Increment the NAND address */
1283     nandAddress = (uint32_t)(nandAddress + 1);
1284   }
1285 
1286   /* Update the NAND controller state */
1287   hnand->State = HAL_NAND_STATE_READY;
1288 
1289   /* Process unlocked */
1290   __HAL_UNLOCK(hnand);
1291 
1292   return HAL_OK;
1293 }
1294 
1295 /**
1296   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
1297   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1298   *                the configuration information for NAND module.
1299   * @param  pAddress  pointer to NAND address structure
1300   * @param  pBuffer  pointer to source buffer to write
1301   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1302   * @retval HAL status
1303   */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1304 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1305 {
1306   __IO uint32_t index = 0;
1307   uint32_t tickstart = 0;
1308   uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
1309 
1310   /* Process Locked */
1311   __HAL_LOCK(hnand);
1312 
1313   /* Check the NAND controller state */
1314   if(hnand->State == HAL_NAND_STATE_BUSY)
1315   {
1316      return HAL_BUSY;
1317   }
1318 
1319   /* Identify the device address */
1320   deviceAddress = NAND_DEVICE;
1321 
1322   /* Update the FMC_NAND controller state */
1323   hnand->State = HAL_NAND_STATE_BUSY;
1324 
1325   /* Page address calculation */
1326   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1327 
1328   /* Column in page address */
1329   columnAddress = COLUMN_ADDRESS(hnand);
1330 
1331   /* Spare area(s) write loop */
1332   while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1333   {
1334     /* update the buffer size */
1335     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1336 
1337     /* Cards with page size <= 512 bytes */
1338     if ((hnand->Config.PageSize) <= 512)
1339     {
1340       /* Send write Spare area command sequence */
1341       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1342       __DSB();
1343       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1344       __DSB();
1345 
1346       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1347       {
1348         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1349         __DSB();
1350         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1351         __DSB();
1352         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1353         __DSB();
1354       }
1355       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1356       {
1357         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1358         __DSB();
1359         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1360         __DSB();
1361         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1362         __DSB();
1363         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1364         __DSB();
1365       }
1366     }
1367     else /* (hnand->Config.PageSize) > 512 */
1368     {
1369       /* Send write Spare area command sequence */
1370       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1371       __DSB();
1372       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1373       __DSB();
1374 
1375       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1376       {
1377         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1378         __DSB();
1379         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1380         __DSB();
1381         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1382         __DSB();
1383         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1384         __DSB();
1385       }
1386       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1387       {
1388         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1389         __DSB();
1390         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1391         __DSB();
1392         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1393         __DSB();
1394         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1395         __DSB();
1396         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1397         __DSB();
1398       }
1399     }
1400 
1401     /* Write data to memory */
1402     for(; index < size; index++)
1403     {
1404       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
1405       __DSB();
1406     }
1407 
1408     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1409     __DSB();
1410 
1411     /* Get tick */
1412     tickstart = HAL_GetTick();
1413 
1414     /* Read status until NAND is ready */
1415     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1416     {
1417       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1418       {
1419         return HAL_TIMEOUT;
1420       }
1421     }
1422 
1423     /* Increment written spare areas number */
1424     numSpareAreaWritten++;
1425 
1426     /* Decrement spare areas to write */
1427     NumSpareAreaTowrite--;
1428 
1429     /* Increment the NAND address */
1430     nandAddress = (uint32_t)(nandAddress + 1);
1431   }
1432 
1433   /* Update the NAND controller state */
1434   hnand->State = HAL_NAND_STATE_READY;
1435 
1436   /* Process unlocked */
1437   __HAL_UNLOCK(hnand);
1438 
1439   return HAL_OK;
1440 }
1441 
1442 /**
1443   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
1444   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1445   *                the configuration information for NAND module.
1446   * @param  pAddress  pointer to NAND address structure
1447   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
1448   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1449   * @retval HAL status
1450   */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1451 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1452 {
1453   __IO uint32_t index = 0;
1454   uint32_t tickstart = 0;
1455   uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
1456 
1457   /* Process Locked */
1458   __HAL_LOCK(hnand);
1459 
1460   /* Check the NAND controller state */
1461   if (hnand->State == HAL_NAND_STATE_BUSY)
1462   {
1463     return HAL_BUSY;
1464   }
1465 
1466   /* Identify the device address */
1467   deviceAddress = NAND_DEVICE;
1468 
1469   /* Update the FMC_NAND controller state */
1470   hnand->State = HAL_NAND_STATE_BUSY;
1471 
1472   /* NAND raw address calculation */
1473   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1474 
1475   /* Column in page address */
1476   columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1477 
1478   /* Spare area(s) write loop */
1479   while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1480   {
1481     /* update the buffer size */
1482     size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1483 
1484     /* Cards with page size <= 512 bytes */
1485     if ((hnand->Config.PageSize) <= 512)
1486     {
1487       /* Send write Spare area command sequence */
1488       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1489       __DSB();
1490       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1491       __DSB();
1492 
1493       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1494       {
1495         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1496         __DSB();
1497         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1498         __DSB();
1499         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1500         __DSB();
1501       }
1502       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1503       {
1504         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1505         __DSB();
1506         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1507         __DSB();
1508         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1509         __DSB();
1510         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1511         __DSB();
1512       }
1513     }
1514     else /* (hnand->Config.PageSize) > 512 */
1515     {
1516       /* Send write Spare area command sequence */
1517       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1518       __DSB();
1519       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1520       __DSB();
1521 
1522       if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1523       {
1524         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1525         __DSB();
1526         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1527         __DSB();
1528         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1529         __DSB();
1530         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1531         __DSB();
1532       }
1533       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1534       {
1535         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1536         __DSB();
1537         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1538         __DSB();
1539         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1540         __DSB();
1541         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1542         __DSB();
1543         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1544         __DSB();
1545       }
1546     }
1547 
1548     /* Write data to memory */
1549     for (; index < size; index++)
1550     {
1551       *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
1552       __DSB();
1553     }
1554 
1555     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1556     __DSB();
1557 
1558     /* Get tick */
1559     tickstart = HAL_GetTick();
1560 
1561     /* Read status until NAND is ready */
1562     while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1563     {
1564       if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1565       {
1566         return HAL_TIMEOUT;
1567       }
1568     }
1569 
1570     /* Increment written spare areas number */
1571     numSpareAreaWritten++;
1572 
1573     /* Decrement spare areas to write */
1574     NumSpareAreaTowrite--;
1575 
1576     /* Increment the NAND address */
1577     nandAddress = (uint32_t)(nandAddress + 1);
1578   }
1579 
1580   /* Update the NAND controller state */
1581   hnand->State = HAL_NAND_STATE_READY;
1582 
1583   /* Process unlocked */
1584   __HAL_UNLOCK(hnand);
1585 
1586   return HAL_OK;
1587 }
1588 
1589 /**
1590   * @brief  NAND memory Block erase
1591   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1592   *                the configuration information for NAND module.
1593   * @param  pAddress  pointer to NAND address structure
1594   * @retval HAL status
1595   */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1596 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1597 {
1598   uint32_t DeviceAddress = 0;
1599 
1600   /* Process Locked */
1601   __HAL_LOCK(hnand);
1602 
1603   /* Check the NAND controller state */
1604   if(hnand->State == HAL_NAND_STATE_BUSY)
1605   {
1606      return HAL_BUSY;
1607   }
1608 
1609   /* Identify the device address */
1610   DeviceAddress = NAND_DEVICE;
1611 
1612   /* Update the NAND controller state */
1613   hnand->State = HAL_NAND_STATE_BUSY;
1614 
1615   /* Send Erase block command sequence */
1616   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
1617   __DSB();
1618   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1619   __DSB();
1620   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1621   __DSB();
1622   *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1623   __DSB();
1624 
1625   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1626   __DSB();
1627 
1628   /* Update the NAND controller state */
1629   hnand->State = HAL_NAND_STATE_READY;
1630 
1631   /* Process unlocked */
1632   __HAL_UNLOCK(hnand);
1633 
1634   return HAL_OK;
1635 }
1636 
1637 /**
1638   * @brief  Increment the NAND memory address
1639   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1640   *                the configuration information for NAND module.
1641   * @param pAddress pointer to NAND address structure
1642   * @retval The new status of the increment address operation. It can be:
1643   *           - NAND_VALID_ADDRESS: When the new address is valid address
1644   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
1645   */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1646 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1647 {
1648   uint32_t status = NAND_VALID_ADDRESS;
1649 
1650   /* Increment page address */
1651   pAddress->Page++;
1652 
1653   /* Check NAND address is valid */
1654   if (pAddress->Page == hnand->Config.BlockSize)
1655   {
1656     pAddress->Page = 0;
1657     pAddress->Block++;
1658 
1659     if (pAddress->Block == hnand->Config.PlaneSize)
1660     {
1661       pAddress->Block = 0;
1662       pAddress->Plane++;
1663 
1664       if (pAddress->Plane == (hnand->Config.PlaneNbr))
1665       {
1666         status = NAND_INVALID_ADDRESS;
1667       }
1668     }
1669   }
1670 
1671   return (status);
1672 }
1673 /**
1674   * @}
1675   */
1676 
1677 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1678  *  @brief   management functions
1679  *
1680 @verbatim
1681   ==============================================================================
1682                          ##### NAND Control functions #####
1683   ==============================================================================
1684   [..]
1685     This subsection provides a set of functions allowing to control dynamically
1686     the NAND interface.
1687 
1688 @endverbatim
1689   * @{
1690   */
1691 
1692 
1693 /**
1694   * @brief  Enable dynamically NAND ECC feature.
1695   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1696   *                the configuration information for NAND module.
1697   * @retval HAL status
1698   */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)1699 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
1700 {
1701   /* Check the NAND controller state */
1702   if(hnand->State == HAL_NAND_STATE_BUSY)
1703   {
1704      return HAL_BUSY;
1705   }
1706 
1707   /* Update the NAND state */
1708   hnand->State = HAL_NAND_STATE_BUSY;
1709 
1710   /* Enable ECC feature */
1711   FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1712 
1713   /* Update the NAND state */
1714   hnand->State = HAL_NAND_STATE_READY;
1715 
1716   return HAL_OK;
1717 }
1718 
1719 /**
1720   * @brief  Disable dynamically NAND ECC feature
1721   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1722   *                the configuration information for NAND module.
1723   * @retval HAL status
1724   */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)1725 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
1726 {
1727   /* Check the NAND controller state */
1728   if(hnand->State == HAL_NAND_STATE_BUSY)
1729   {
1730      return HAL_BUSY;
1731   }
1732 
1733   /* Update the NAND state */
1734   hnand->State = HAL_NAND_STATE_BUSY;
1735 
1736   /* Disable ECC feature */
1737   FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1738 
1739   /* Update the NAND state */
1740   hnand->State = HAL_NAND_STATE_READY;
1741 
1742   return HAL_OK;
1743 }
1744 
1745 /**
1746   * @brief  Get NAND ECC value
1747   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1748   *                the configuration information for NAND module.
1749   * @param  ECCval pointer to ECC value
1750   * @param  Timeout maximum timeout to wait
1751   * @retval HAL status
1752   */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)1753 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1754 {
1755   HAL_StatusTypeDef status = HAL_OK;
1756 
1757   /* Check the NAND controller state */
1758   if(hnand->State == HAL_NAND_STATE_BUSY)
1759   {
1760      return HAL_BUSY;
1761   }
1762 
1763   /* Update the NAND state */
1764   hnand->State = HAL_NAND_STATE_BUSY;
1765 
1766   /* Get NAND ECC value */
1767   status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1768 
1769   /* Update the NAND state */
1770   hnand->State = HAL_NAND_STATE_READY;
1771 
1772   return status;
1773 }
1774 
1775 /**
1776   * @}
1777   */
1778 
1779 
1780 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1781  *  @brief   Peripheral State functions
1782  *
1783 @verbatim
1784   ==============================================================================
1785                          ##### NAND State functions #####
1786   ==============================================================================
1787   [..]
1788     This subsection permits to get in run-time the status of the NAND controller
1789     and the data flow.
1790 
1791 @endverbatim
1792   * @{
1793   */
1794 
1795 /**
1796   * @brief  Return the NAND state
1797   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1798   *                the configuration information for NAND module.
1799   * @retval HAL state
1800   */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)1801 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1802 {
1803   /* Return NAND handle state */
1804   return hnand->State;
1805 }
1806 
1807 /**
1808   * @brief  NAND memory read status
1809   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1810   *                the configuration information for NAND module.
1811   * @retval NAND status
1812   */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)1813 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
1814 {
1815   uint32_t data = 0;
1816   uint32_t DeviceAddress = 0;
1817 
1818   /* Identify the device address */
1819   DeviceAddress = NAND_DEVICE;
1820 
1821   /* Send Read status operation command */
1822   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
1823 
1824   /* Read status register data */
1825   data = *(__IO uint8_t *)DeviceAddress;
1826 
1827   /* Return the status */
1828   if ((data & NAND_ERROR) == NAND_ERROR)
1829   {
1830     return NAND_ERROR;
1831   }
1832   else if ((data & NAND_READY) == NAND_READY)
1833   {
1834     return NAND_READY;
1835   }
1836 
1837   return NAND_BUSY;
1838 }
1839 
1840 /**
1841   * @}
1842   */
1843 
1844 /**
1845   * @}
1846   */
1847 
1848 /**
1849   * @}
1850   */
1851 
1852 #endif /* HAL_NAND_MODULE_ENABLED  */
1853 
1854 /**
1855   * @}
1856   */
1857 
1858 #endif /* FMC_BANK3 */
1859 
1860 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1861