1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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     *** Callback registration ***
56     =============================================
57     [..]
58       The compilation define  USE_HAL_NAND_REGISTER_CALLBACKS when set to 1
59       allows the user to configure dynamically the driver callbacks.
60 
61       Use Functions @ref HAL_NAND_RegisterCallback() to register a user callback,
62       it allows to register following callbacks:
63         (+) MspInitCallback    : NAND MspInit.
64         (+) MspDeInitCallback  : NAND MspDeInit.
65       This function takes as parameters the HAL peripheral handle, the Callback ID
66       and a pointer to the user callback function.
67 
68       Use function @ref HAL_NAND_UnRegisterCallback() to reset a callback to the default
69       weak (surcharged) function. It allows to reset following callbacks:
70         (+) MspInitCallback    : NAND MspInit.
71         (+) MspDeInitCallback  : NAND MspDeInit.
72       This function) takes as parameters the HAL peripheral handle and the Callback ID.
73 
74       By default, after the @ref HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET
75       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
76       Exception done for MspInit and MspDeInit callbacks that are respectively
77       reset to the legacy weak (surcharged) functions in the @ref HAL_NAND_Init
78       and @ref  HAL_NAND_DeInit only when these callbacks are null (not registered beforehand).
79       If not, MspInit or MspDeInit are not null, the @ref HAL_NAND_Init and @ref HAL_NAND_DeInit
80       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
81 
82       Callbacks can be registered/unregistered in READY state only.
83       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
84       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
85       during the Init/DeInit.
86       In that case first register the MspInit/MspDeInit user callbacks
87       using @ref HAL_NAND_RegisterCallback before calling @ref HAL_NAND_DeInit
88       or @ref HAL_NAND_Init function.
89 
90       When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or
91       not defined, the callback registering feature is not available
92       and weak (surcharged) callbacks are used.
93 
94   @endverbatim
95   ******************************************************************************
96   * @attention
97   *
98   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
99   * All rights reserved.</center></h2>
100   *
101   * This software component is licensed by ST under BSD 3-Clause license,
102   * the "License"; You may not use this file except in compliance with the
103   * License. You may obtain a copy of the License at:
104   *                       opensource.org/licenses/BSD-3-Clause
105   *
106   ******************************************************************************
107   */
108 
109 /* Includes ------------------------------------------------------------------*/
110 #include "stm32l5xx_hal.h"
111 
112 
113 /** @addtogroup STM32L5xx_HAL_Driver
114   * @{
115   */
116 
117 #ifdef HAL_NAND_MODULE_ENABLED
118 
119 /** @defgroup NAND NAND
120   * @brief NAND HAL module driver
121   * @{
122   */
123 
124 /* Private typedef -----------------------------------------------------------*/
125 /* Private Constants ------------------------------------------------------------*/
126 /* Private macro -------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /* Private function prototypes -----------------------------------------------*/
129 /* Exported functions ---------------------------------------------------------*/
130 
131 /** @defgroup NAND_Exported_Functions NAND Exported Functions
132   * @{
133   */
134 
135 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
136   * @brief    Initialization and Configuration functions
137   *
138   @verbatim
139   ==============================================================================
140             ##### NAND Initialization and de-initialization functions #####
141   ==============================================================================
142   [..]
143     This section provides functions allowing to initialize/de-initialize
144     the NAND memory
145 
146 @endverbatim
147   * @{
148   */
149 
150 /**
151   * @brief  Perform NAND memory Initialization sequence
152   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
153   *                the configuration information for NAND module.
154   * @param  ComSpace_Timing pointer to Common space timing structure
155   * @param  AttSpace_Timing pointer to Attribute space timing structure
156   * @retval HAL status
157   */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)158 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
159                                  FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
160 {
161   /* Check the NAND handle state */
162   if (hnand == NULL)
163   {
164     return HAL_ERROR;
165   }
166 
167   if (hnand->State == HAL_NAND_STATE_RESET)
168   {
169     /* Allocate lock resource and initialize it */
170     hnand->Lock = HAL_UNLOCKED;
171 
172 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
173     if (hnand->MspInitCallback == NULL)
174     {
175       hnand->MspInitCallback = HAL_NAND_MspInit;
176     }
177     hnand->ItCallback = HAL_NAND_ITCallback;
178 
179     /* Init the low level hardware */
180     hnand->MspInitCallback(hnand);
181 #else
182     /* Initialize the low level hardware (MSP) */
183     HAL_NAND_MspInit(hnand);
184 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
185   }
186 
187   /* Initialize NAND control Interface */
188   (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init));
189 
190   /* Initialize NAND common space timing Interface */
191   (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
192 
193   /* Initialize NAND attribute space timing Interface */
194   (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
195 
196   /* Enable the NAND device */
197   __FMC_NAND_ENABLE(hnand->Instance);
198 
199   /* Update the NAND controller state */
200   hnand->State = HAL_NAND_STATE_READY;
201 
202   return HAL_OK;
203 }
204 
205 /**
206   * @brief  Perform NAND memory De-Initialization sequence
207   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
208   *                the configuration information for NAND module.
209   * @retval HAL status
210   */
HAL_NAND_DeInit(NAND_HandleTypeDef * hnand)211 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
212 {
213 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
214   if (hnand->MspDeInitCallback == NULL)
215   {
216     hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
217   }
218 
219   /* DeInit the low level hardware */
220   hnand->MspDeInitCallback(hnand);
221 #else
222   /* Initialize the low level hardware (MSP) */
223   HAL_NAND_MspDeInit(hnand);
224 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
225 
226   /* Configure the NAND registers with their reset values */
227   (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
228 
229   /* Reset the NAND controller state */
230   hnand->State = HAL_NAND_STATE_RESET;
231 
232   /* Release Lock */
233   __HAL_UNLOCK(hnand);
234 
235   return HAL_OK;
236 }
237 
238 /**
239   * @brief  NAND MSP Init
240   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
241   *                the configuration information for NAND module.
242   * @retval None
243   */
HAL_NAND_MspInit(NAND_HandleTypeDef * hnand)244 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
245 {
246   /* Prevent unused argument(s) compilation warning */
247   UNUSED(hnand);
248 
249   /* NOTE : This function Should not be modified, when the callback is needed,
250             the HAL_NAND_MspInit could be implemented in the user file
251    */
252 }
253 
254 /**
255   * @brief  NAND MSP DeInit
256   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
257   *                the configuration information for NAND module.
258   * @retval None
259   */
HAL_NAND_MspDeInit(NAND_HandleTypeDef * hnand)260 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
261 {
262   /* Prevent unused argument(s) compilation warning */
263   UNUSED(hnand);
264 
265   /* NOTE : This function Should not be modified, when the callback is needed,
266             the HAL_NAND_MspDeInit could be implemented in the user file
267    */
268 }
269 
270 
271 /**
272   * @brief  This function handles NAND device interrupt request.
273   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
274   *                the configuration information for NAND module.
275   * @retval HAL status
276   */
HAL_NAND_IRQHandler(NAND_HandleTypeDef * hnand)277 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
278 {
279   /* Check NAND interrupt Rising edge flag */
280   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
281   {
282     /* NAND interrupt callback*/
283 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
284     hnand->ItCallback(hnand);
285 #else
286     HAL_NAND_ITCallback(hnand);
287 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
288 
289     /* Clear NAND interrupt Rising edge pending bit */
290     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
291   }
292 
293   /* Check NAND interrupt Level flag */
294   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
295   {
296     /* NAND interrupt callback*/
297 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
298     hnand->ItCallback(hnand);
299 #else
300     HAL_NAND_ITCallback(hnand);
301 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
302 
303     /* Clear NAND interrupt Level pending bit */
304     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
305   }
306 
307   /* Check NAND interrupt Falling edge flag */
308   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
309   {
310     /* NAND interrupt callback*/
311 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
312     hnand->ItCallback(hnand);
313 #else
314     HAL_NAND_ITCallback(hnand);
315 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
316 
317     /* Clear NAND interrupt Falling edge pending bit */
318     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
319   }
320 
321   /* Check NAND interrupt FIFO empty flag */
322   if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
323   {
324     /* NAND interrupt callback*/
325 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
326     hnand->ItCallback(hnand);
327 #else
328     HAL_NAND_ITCallback(hnand);
329 #endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
330 
331     /* Clear NAND interrupt FIFO empty pending bit */
332     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
333   }
334 
335 }
336 
337 /**
338   * @brief  NAND interrupt feature callback
339   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
340   *                the configuration information for NAND module.
341   * @retval None
342   */
HAL_NAND_ITCallback(NAND_HandleTypeDef * hnand)343 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
344 {
345   /* Prevent unused argument(s) compilation warning */
346   UNUSED(hnand);
347 
348   /* NOTE : This function Should not be modified, when the callback is needed,
349             the HAL_NAND_ITCallback could be implemented in the user file
350    */
351 }
352 
353 /**
354   * @}
355   */
356 
357 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
358   * @brief    Input Output and memory control functions
359   *
360   @verbatim
361   ==============================================================================
362                     ##### NAND Input and Output functions #####
363   ==============================================================================
364   [..]
365     This section provides functions allowing to use and control the NAND
366     memory
367 
368 @endverbatim
369   * @{
370   */
371 
372 /**
373   * @brief  Read the NAND memory electronic signature
374   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
375   *                the configuration information for NAND module.
376   * @param  pNAND_ID NAND ID structure
377   * @retval HAL status
378   */
HAL_NAND_Read_ID(NAND_HandleTypeDef * hnand,NAND_IDTypeDef * pNAND_ID)379 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
380 {
381   __IO uint32_t data = 0;
382   __IO uint32_t data1 = 0;
383   uint32_t deviceaddress;
384 
385   /* Check the NAND controller state */
386   if (hnand->State == HAL_NAND_STATE_BUSY)
387   {
388     return HAL_BUSY;
389   }
390   else if (hnand->State == HAL_NAND_STATE_READY)
391   {
392     /* Process Locked */
393     __HAL_LOCK(hnand);
394 
395     /* Update the NAND controller state */
396     hnand->State = HAL_NAND_STATE_BUSY;
397 
398     /* Identify the device address */
399     deviceaddress = NAND_DEVICE;
400 
401     /* Send Read ID command sequence */
402     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_READID;
403     __DSB();
404     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
405     __DSB();
406 
407     /* Read the electronic signature from NAND flash */
408     if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
409     {
410       data = *(__IO uint32_t *)deviceaddress;
411 
412       /* Return the data read */
413       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
414       pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
415       pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
416       pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
417     }
418     else
419     {
420       data = *(__IO uint32_t *)deviceaddress;
421       data1 = *((__IO uint32_t *)deviceaddress + 4);
422 
423       /* Return the data read */
424       pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
425       pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
426       pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
427       pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
428     }
429 
430     /* Update the NAND controller state */
431     hnand->State = HAL_NAND_STATE_READY;
432 
433     /* Process unlocked */
434     __HAL_UNLOCK(hnand);
435   }
436   else
437   {
438     return HAL_ERROR;
439   }
440 
441   return HAL_OK;
442 }
443 
444 /**
445   * @brief  NAND memory reset
446   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
447   *                the configuration information for NAND module.
448   * @retval HAL status
449   */
HAL_NAND_Reset(NAND_HandleTypeDef * hnand)450 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
451 {
452   uint32_t deviceaddress;
453 
454   /* Check the NAND controller state */
455   if (hnand->State == HAL_NAND_STATE_BUSY)
456   {
457     return HAL_BUSY;
458   }
459   else if (hnand->State == HAL_NAND_STATE_READY)
460   {
461     /* Process Locked */
462     __HAL_LOCK(hnand);
463 
464     /* Update the NAND controller state */
465     hnand->State = HAL_NAND_STATE_BUSY;
466 
467     /* Identify the device address */
468     deviceaddress = NAND_DEVICE;
469 
470     /* Send NAND reset command */
471     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
472 
473     /* Update the NAND controller state */
474     hnand->State = HAL_NAND_STATE_READY;
475 
476     /* Process unlocked */
477     __HAL_UNLOCK(hnand);
478   }
479   else
480   {
481     return HAL_ERROR;
482   }
483 
484   return HAL_OK;
485 
486 }
487 
488 /**
489   * @brief  Configure the device: Enter the physical parameters of the device
490   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
491   *                the configuration information for NAND module.
492   * @param  pDeviceConfig  pointer to NAND_DeviceConfigTypeDef structure
493   * @retval HAL status
494   */
HAL_NAND_ConfigDevice(NAND_HandleTypeDef * hnand,NAND_DeviceConfigTypeDef * pDeviceConfig)495 HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
496 {
497   hnand->Config.PageSize           = pDeviceConfig->PageSize;
498   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
499   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
500   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
501   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
502   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
503   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
504 
505   return HAL_OK;
506 }
507 
508 /**
509   * @brief  Read Page(s) from NAND memory block (8-bits addressing)
510   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
511   *                the configuration information for NAND module.
512   * @param  pAddress  pointer to NAND address structure
513   * @param  pBuffer  pointer to destination read buffer
514   * @param  NumPageToRead  number of pages to read from block
515   * @retval HAL status
516   */
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToRead)517 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
518                                         uint32_t NumPageToRead)
519 {
520   uint32_t index;
521   uint32_t tickstart;
522   uint32_t deviceaddress;
523   uint32_t numpagesread = 0U;
524   uint32_t nandaddress;
525   uint32_t nbpages = NumPageToRead;
526   uint8_t *buff = pBuffer;
527 
528   /* Check the NAND controller state */
529   if (hnand->State == HAL_NAND_STATE_BUSY)
530   {
531     return HAL_BUSY;
532   }
533   else if (hnand->State == HAL_NAND_STATE_READY)
534   {
535     /* Process Locked */
536     __HAL_LOCK(hnand);
537 
538     /* Update the NAND controller state */
539     hnand->State = HAL_NAND_STATE_BUSY;
540 
541     /* Identify the device address */
542     deviceaddress = NAND_DEVICE;
543 
544     /* NAND raw address calculation */
545     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
546 
547     /* Page(s) read loop */
548     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
549     {
550       /* Send read page command sequence */
551       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
552       __DSB();
553 
554       /* Cards with page size <= 512 bytes */
555       if ((hnand->Config.PageSize) <= 512U)
556       {
557         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
558         {
559           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
560           __DSB();
561           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
562           __DSB();
563           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
564           __DSB();
565         }
566         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
567         {
568           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
569           __DSB();
570           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
571           __DSB();
572           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
573           __DSB();
574           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
575           __DSB();
576         }
577       }
578       else /* (hnand->Config.PageSize) > 512 */
579       {
580         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
581         {
582           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
583           __DSB();
584           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
585           __DSB();
586           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
587           __DSB();
588           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
589           __DSB();
590         }
591         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
592         {
593           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
594           __DSB();
595           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
596           __DSB();
597           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
598           __DSB();
599           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
600           __DSB();
601           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
602           __DSB();
603         }
604       }
605 
606       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
607       __DSB();
608 
609 
610       if (hnand->Config.ExtraCommandEnable == ENABLE)
611       {
612         /* Get tick */
613         tickstart = HAL_GetTick();
614 
615         /* Read status until NAND is ready */
616         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
617         {
618           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
619           {
620             /* Update the NAND controller state */
621             hnand->State = HAL_NAND_STATE_ERROR;
622 
623             /* Process unlocked */
624             __HAL_UNLOCK(hnand);
625 
626             return HAL_TIMEOUT;
627           }
628         }
629 
630         /* Go back to read mode */
631         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
632         __DSB();
633       }
634 
635       /* Get Data into Buffer */
636       for (index = 0U; index < hnand->Config.PageSize; index++)
637       {
638         *buff = *(uint8_t *)deviceaddress;
639         buff++;
640       }
641 
642       /* Increment read pages number */
643       numpagesread++;
644 
645       /* Decrement pages to read */
646       nbpages--;
647 
648       /* Increment the NAND address */
649       nandaddress = (uint32_t)(nandaddress + 1U);
650     }
651 
652     /* Update the NAND controller state */
653     hnand->State = HAL_NAND_STATE_READY;
654 
655     /* Process unlocked */
656     __HAL_UNLOCK(hnand);
657   }
658   else
659   {
660     return HAL_ERROR;
661   }
662 
663   return HAL_OK;
664 }
665 
666 /**
667   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
668   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
669   *                the configuration information for NAND module.
670   * @param  pAddress  pointer to NAND address structure
671   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
672   * @param  NumPageToRead  number of pages to read from block
673   * @retval HAL status
674   */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)675 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
676                                          uint32_t NumPageToRead)
677 {
678   uint32_t index;
679   uint32_t tickstart;
680   uint32_t deviceaddress;
681   uint32_t numpagesread = 0U;
682   uint32_t nandaddress;
683   uint32_t nbpages = NumPageToRead;
684   uint16_t *buff = pBuffer;
685 
686   /* Check the NAND controller state */
687   if (hnand->State == HAL_NAND_STATE_BUSY)
688   {
689     return HAL_BUSY;
690   }
691   else if (hnand->State == HAL_NAND_STATE_READY)
692   {
693     /* Process Locked */
694     __HAL_LOCK(hnand);
695 
696     /* Update the NAND controller state */
697     hnand->State = HAL_NAND_STATE_BUSY;
698 
699     /* Identify the device address */
700     deviceaddress = NAND_DEVICE;
701 
702     /* NAND raw address calculation */
703     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
704 
705     /* Page(s) read loop */
706     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
707     {
708       /* Send read page command sequence */
709       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
710       __DSB();
711 
712       /* Cards with page size <= 512 bytes */
713       if ((hnand->Config.PageSize) <= 512U)
714       {
715         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
716         {
717           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
718           __DSB();
719           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
720           __DSB();
721           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
722           __DSB();
723         }
724         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
725         {
726           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
727           __DSB();
728           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
729           __DSB();
730           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
731           __DSB();
732           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
733           __DSB();
734         }
735       }
736       else /* (hnand->Config.PageSize) > 512 */
737       {
738         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
739         {
740           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
741           __DSB();
742           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
743           __DSB();
744           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
745           __DSB();
746           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
747           __DSB();
748         }
749         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
750         {
751           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
752           __DSB();
753           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
754           __DSB();
755           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
756           __DSB();
757           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
758           __DSB();
759           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
760           __DSB();
761         }
762       }
763 
764       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
765       __DSB();
766 
767       if (hnand->Config.ExtraCommandEnable == ENABLE)
768       {
769         /* Get tick */
770         tickstart = HAL_GetTick();
771 
772         /* Read status until NAND is ready */
773         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
774         {
775           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
776           {
777             /* Update the NAND controller state */
778             hnand->State = HAL_NAND_STATE_ERROR;
779 
780             /* Process unlocked */
781             __HAL_UNLOCK(hnand);
782 
783             return HAL_TIMEOUT;
784           }
785         }
786 
787         /* Go back to read mode */
788         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
789         __DSB();
790       }
791 
792       /* Calculate PageSize */
793       if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
794       {
795         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
796       }
797       else
798       {
799         /* Do nothing */
800         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
801       }
802 
803       /* Get Data into Buffer */
804       for (index = 0U; index < hnand->Config.PageSize; index++)
805       {
806         *buff = *(uint16_t *)deviceaddress;
807         buff++;
808       }
809 
810       /* Increment read pages number */
811       numpagesread++;
812 
813       /* Decrement pages to read */
814       nbpages--;
815 
816       /* Increment the NAND address */
817       nandaddress = (uint32_t)(nandaddress + 1U);
818     }
819 
820     /* Update the NAND controller state */
821     hnand->State = HAL_NAND_STATE_READY;
822 
823     /* Process unlocked */
824     __HAL_UNLOCK(hnand);
825   }
826   else
827   {
828     return HAL_ERROR;
829   }
830 
831   return HAL_OK;
832 }
833 
834 /**
835   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
836   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
837   *                the configuration information for NAND module.
838   * @param  pAddress  pointer to NAND address structure
839   * @param  pBuffer  pointer to source buffer to write
840   * @param  NumPageToWrite   number of pages to write to block
841   * @retval HAL status
842   */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)843 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
844                                          uint32_t NumPageToWrite)
845 {
846   uint32_t index;
847   uint32_t tickstart;
848   uint32_t deviceaddress;
849   uint32_t numpageswritten = 0U;
850   uint32_t nandaddress;
851   uint32_t nbpages = NumPageToWrite;
852   uint8_t *buff = pBuffer;
853 
854   /* Check the NAND controller state */
855   if (hnand->State == HAL_NAND_STATE_BUSY)
856   {
857     return HAL_BUSY;
858   }
859   else if (hnand->State == HAL_NAND_STATE_READY)
860   {
861     /* Process Locked */
862     __HAL_LOCK(hnand);
863 
864     /* Update the NAND controller state */
865     hnand->State = HAL_NAND_STATE_BUSY;
866 
867     /* Identify the device address */
868     deviceaddress = NAND_DEVICE;
869 
870     /* NAND raw address calculation */
871     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
872 
873     /* Page(s) write loop */
874     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
875     {
876       /* Send write page command sequence */
877       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
878       __DSB();
879       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
880       __DSB();
881 
882       /* Cards with page size <= 512 bytes */
883       if ((hnand->Config.PageSize) <= 512U)
884       {
885         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
886         {
887           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
888           __DSB();
889           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
890           __DSB();
891           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
892           __DSB();
893         }
894         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
895         {
896           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
897           __DSB();
898           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
899           __DSB();
900           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
901           __DSB();
902           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
903           __DSB();
904         }
905       }
906       else /* (hnand->Config.PageSize) > 512 */
907       {
908         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
909         {
910           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
911           __DSB();
912           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
913           __DSB();
914           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
915           __DSB();
916           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
917           __DSB();
918         }
919         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
920         {
921           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
922           __DSB();
923           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
924           __DSB();
925           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
926           __DSB();
927           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
928           __DSB();
929           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
930           __DSB();
931         }
932       }
933 
934       /* Write data to memory */
935       for (index = 0U; index < hnand->Config.PageSize; index++)
936       {
937         *(__IO uint8_t *)deviceaddress = *buff;
938         buff++;
939         __DSB();
940       }
941 
942       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
943       __DSB();
944 
945       /* Get tick */
946       tickstart = HAL_GetTick();
947 
948       /* Read status until NAND is ready */
949       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
950       {
951         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
952         {
953           /* Update the NAND controller state */
954           hnand->State = HAL_NAND_STATE_ERROR;
955 
956           /* Process unlocked */
957           __HAL_UNLOCK(hnand);
958 
959           return HAL_TIMEOUT;
960         }
961       }
962 
963       /* Increment written pages number */
964       numpageswritten++;
965 
966       /* Decrement pages to write */
967       nbpages--;
968 
969       /* Increment the NAND address */
970       nandaddress = (uint32_t)(nandaddress + 1U);
971     }
972 
973     /* Update the NAND controller state */
974     hnand->State = HAL_NAND_STATE_READY;
975 
976     /* Process unlocked */
977     __HAL_UNLOCK(hnand);
978   }
979   else
980   {
981     return HAL_ERROR;
982   }
983 
984   return HAL_OK;
985 }
986 
987 /**
988   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
989   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
990   *                the configuration information for NAND module.
991   * @param  pAddress  pointer to NAND address structure
992   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
993   * @param  NumPageToWrite   number of pages to write to block
994   * @retval HAL status
995   */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)996 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
997                                           uint32_t NumPageToWrite)
998 {
999   uint32_t index;
1000   uint32_t tickstart;
1001   uint32_t deviceaddress;
1002   uint32_t numpageswritten = 0U;
1003   uint32_t nandaddress;
1004   uint32_t nbpages = NumPageToWrite;
1005   uint16_t *buff = pBuffer;
1006 
1007   /* Check the NAND controller state */
1008   if (hnand->State == HAL_NAND_STATE_BUSY)
1009   {
1010     return HAL_BUSY;
1011   }
1012   else if (hnand->State == HAL_NAND_STATE_READY)
1013   {
1014     /* Process Locked */
1015     __HAL_LOCK(hnand);
1016 
1017     /* Update the NAND controller state */
1018     hnand->State = HAL_NAND_STATE_BUSY;
1019 
1020     /* Identify the device address */
1021     deviceaddress = NAND_DEVICE;
1022 
1023     /* NAND raw address calculation */
1024     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1025 
1026     /* Page(s) write loop */
1027     while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1028     {
1029       /* Send write page command sequence */
1030       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1031       __DSB();
1032       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1033       __DSB();
1034 
1035       /* Cards with page size <= 512 bytes */
1036       if ((hnand->Config.PageSize) <= 512U)
1037       {
1038         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1039         {
1040           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1041           __DSB();
1042           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1043           __DSB();
1044           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1045           __DSB();
1046         }
1047         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1048         {
1049           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1050           __DSB();
1051           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1052           __DSB();
1053           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1054           __DSB();
1055           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1056           __DSB();
1057         }
1058       }
1059       else /* (hnand->Config.PageSize) > 512 */
1060       {
1061         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1062         {
1063           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1064           __DSB();
1065           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1066           __DSB();
1067           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1068           __DSB();
1069           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1070           __DSB();
1071         }
1072         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1073         {
1074           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1075           __DSB();
1076           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1077           __DSB();
1078           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1079           __DSB();
1080           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1081           __DSB();
1082           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1083           __DSB();
1084         }
1085       }
1086 
1087       /* Calculate PageSize */
1088       if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
1089       {
1090         hnand->Config.PageSize = hnand->Config.PageSize / 2U;
1091       }
1092       else
1093       {
1094         /* Do nothing */
1095         /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
1096       }
1097 
1098       /* Write data to memory */
1099       for (index = 0U; index < hnand->Config.PageSize; index++)
1100       {
1101         *(__IO uint16_t *)deviceaddress = *buff;
1102         buff++;
1103         __DSB();
1104       }
1105 
1106       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1107       __DSB();
1108 
1109       /* Get tick */
1110       tickstart = HAL_GetTick();
1111 
1112       /* Read status until NAND is ready */
1113       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1114       {
1115         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1116         {
1117           /* Update the NAND controller state */
1118           hnand->State = HAL_NAND_STATE_ERROR;
1119 
1120           /* Process unlocked */
1121           __HAL_UNLOCK(hnand);
1122 
1123           return HAL_TIMEOUT;
1124         }
1125       }
1126 
1127       /* Increment written pages number */
1128       numpageswritten++;
1129 
1130       /* Decrement pages to write */
1131       nbpages--;
1132 
1133       /* Increment the NAND address */
1134       nandaddress = (uint32_t)(nandaddress + 1U);
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   else
1144   {
1145     return HAL_ERROR;
1146   }
1147 
1148   return HAL_OK;
1149 }
1150 
1151 /**
1152   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
1153   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1154   *                the configuration information for NAND module.
1155   * @param  pAddress  pointer to NAND address structure
1156   * @param  pBuffer pointer to source buffer to write
1157   * @param  NumSpareAreaToRead Number of spare area to read
1158   * @retval HAL status
1159   */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1160 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
1161                                              uint32_t NumSpareAreaToRead)
1162 {
1163   uint32_t index;
1164   uint32_t tickstart;
1165   uint32_t deviceaddress;
1166   uint32_t numsparearearead = 0U;
1167   uint32_t nandaddress;
1168   uint32_t columnaddress;
1169   uint32_t nbspare = NumSpareAreaToRead;
1170   uint8_t *buff = pBuffer;
1171 
1172   /* Check the NAND controller state */
1173   if (hnand->State == HAL_NAND_STATE_BUSY)
1174   {
1175     return HAL_BUSY;
1176   }
1177   else if (hnand->State == HAL_NAND_STATE_READY)
1178   {
1179     /* Process Locked */
1180     __HAL_LOCK(hnand);
1181 
1182     /* Update the NAND controller state */
1183     hnand->State = HAL_NAND_STATE_BUSY;
1184 
1185     /* Identify the device address */
1186     deviceaddress = NAND_DEVICE;
1187 
1188     /* NAND raw address calculation */
1189     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1190 
1191     /* Column in page address */
1192     columnaddress = COLUMN_ADDRESS(hnand);
1193 
1194     /* Spare area(s) read loop */
1195     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1196     {
1197       /* Cards with page size <= 512 bytes */
1198       if ((hnand->Config.PageSize) <= 512U)
1199       {
1200         /* Send read spare area command sequence */
1201         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1202         __DSB();
1203 
1204         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1205         {
1206           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
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         }
1213         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1214         {
1215           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1216           __DSB();
1217           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1218           __DSB();
1219           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1220           __DSB();
1221           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1222           __DSB();
1223         }
1224       }
1225       else /* (hnand->Config.PageSize) > 512 */
1226       {
1227         /* Send read spare area command sequence */
1228         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1229         __DSB();
1230 
1231         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1232         {
1233           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1234           __DSB();
1235           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1236           __DSB();
1237           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1238           __DSB();
1239           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1240           __DSB();
1241         }
1242         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1243         {
1244           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1245           __DSB();
1246           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1247           __DSB();
1248           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1249           __DSB();
1250           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1251           __DSB();
1252           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1253           __DSB();
1254         }
1255       }
1256 
1257       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1258       __DSB();
1259 
1260       if (hnand->Config.ExtraCommandEnable == ENABLE)
1261       {
1262         /* Get tick */
1263         tickstart = HAL_GetTick();
1264 
1265         /* Read status until NAND is ready */
1266         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1267         {
1268           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1269           {
1270             /* Update the NAND controller state */
1271             hnand->State = HAL_NAND_STATE_ERROR;
1272 
1273             /* Process unlocked */
1274             __HAL_UNLOCK(hnand);
1275 
1276             return HAL_TIMEOUT;
1277           }
1278         }
1279 
1280         /* Go back to read mode */
1281         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1282         __DSB();
1283       }
1284 
1285       /* Get Data into Buffer */
1286       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1287       {
1288         *buff = *(uint8_t *)deviceaddress;
1289         buff++;
1290       }
1291 
1292       /* Increment read spare areas number */
1293       numsparearearead++;
1294 
1295       /* Decrement spare areas to read */
1296       nbspare--;
1297 
1298       /* Increment the NAND address */
1299       nandaddress = (uint32_t)(nandaddress + 1U);
1300     }
1301 
1302     /* Update the NAND controller state */
1303     hnand->State = HAL_NAND_STATE_READY;
1304 
1305     /* Process unlocked */
1306     __HAL_UNLOCK(hnand);
1307   }
1308   else
1309   {
1310     return HAL_ERROR;
1311   }
1312 
1313   return HAL_OK;
1314 }
1315 
1316 /**
1317   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
1318   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1319   *                the configuration information for NAND module.
1320   * @param  pAddress  pointer to NAND address structure
1321   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1322   * @param  NumSpareAreaToRead Number of spare area to read
1323   * @retval HAL status
1324   */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1325 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1326                                               uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1327 {
1328   uint32_t index;
1329   uint32_t tickstart;
1330   uint32_t deviceaddress;
1331   uint32_t numsparearearead = 0U;
1332   uint32_t nandaddress;
1333   uint32_t columnaddress;
1334   uint32_t nbspare = NumSpareAreaToRead;
1335   uint16_t *buff = pBuffer;
1336 
1337   /* Check the NAND controller state */
1338   if (hnand->State == HAL_NAND_STATE_BUSY)
1339   {
1340     return HAL_BUSY;
1341   }
1342   else if (hnand->State == HAL_NAND_STATE_READY)
1343   {
1344     /* Process Locked */
1345     __HAL_LOCK(hnand);
1346 
1347     /* Update the NAND controller state */
1348     hnand->State = HAL_NAND_STATE_BUSY;
1349 
1350     /* Identify the device address */
1351     deviceaddress = NAND_DEVICE;
1352 
1353     /* NAND raw address calculation */
1354     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1355 
1356     /* Column in page address */
1357     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1358 
1359     /* Spare area(s) read loop */
1360     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1361     {
1362       /* Cards with page size <= 512 bytes */
1363       if ((hnand->Config.PageSize) <= 512U)
1364       {
1365         /* Send read spare area command sequence */
1366         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1367         __DSB();
1368 
1369         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1370         {
1371           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1372           __DSB();
1373           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1374           __DSB();
1375           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1376           __DSB();
1377         }
1378         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1379         {
1380           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1381           __DSB();
1382           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1383           __DSB();
1384           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1385           __DSB();
1386           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1387           __DSB();
1388         }
1389       }
1390       else /* (hnand->Config.PageSize) > 512 */
1391       {
1392         /* Send read spare area command sequence */
1393         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1394         __DSB();
1395 
1396         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1397         {
1398           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1399           __DSB();
1400           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1401           __DSB();
1402           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1403           __DSB();
1404           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1405           __DSB();
1406         }
1407         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1408         {
1409           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1410           __DSB();
1411           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1412           __DSB();
1413           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1414           __DSB();
1415           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1416           __DSB();
1417           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1418           __DSB();
1419         }
1420       }
1421 
1422       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1423       __DSB();
1424 
1425       if (hnand->Config.ExtraCommandEnable == ENABLE)
1426       {
1427         /* Get tick */
1428         tickstart = HAL_GetTick();
1429 
1430         /* Read status until NAND is ready */
1431         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1432         {
1433           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1434           {
1435             /* Update the NAND controller state */
1436             hnand->State = HAL_NAND_STATE_ERROR;
1437 
1438             /* Process unlocked */
1439             __HAL_UNLOCK(hnand);
1440 
1441             return HAL_TIMEOUT;
1442           }
1443         }
1444 
1445         /* Go back to read mode */
1446         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1447         __DSB();
1448       }
1449 
1450       /* Get Data into Buffer */
1451       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1452       {
1453         *buff = *(uint16_t *)deviceaddress;
1454         buff++;
1455       }
1456 
1457       /* Increment read spare areas number */
1458       numsparearearead++;
1459 
1460       /* Decrement spare areas to read */
1461       nbspare--;
1462 
1463       /* Increment the NAND address */
1464       nandaddress = (uint32_t)(nandaddress + 1U);
1465     }
1466 
1467     /* Update the NAND controller state */
1468     hnand->State = HAL_NAND_STATE_READY;
1469 
1470     /* Process unlocked */
1471     __HAL_UNLOCK(hnand);
1472   }
1473   else
1474   {
1475     return HAL_ERROR;
1476   }
1477 
1478   return HAL_OK;
1479 }
1480 
1481 /**
1482   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
1483   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1484   *                the configuration information for NAND module.
1485   * @param  pAddress  pointer to NAND address structure
1486   * @param  pBuffer  pointer to source buffer to write
1487   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1488   * @retval HAL status
1489   */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1490 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1491                                               uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1492 {
1493   uint32_t index;
1494   uint32_t tickstart;
1495   uint32_t deviceaddress;
1496   uint32_t numspareareawritten = 0U;
1497   uint32_t nandaddress;
1498   uint32_t columnaddress;
1499   uint32_t nbspare = NumSpareAreaTowrite;
1500   uint8_t *buff = pBuffer;
1501 
1502   /* Check the NAND controller state */
1503   if (hnand->State == HAL_NAND_STATE_BUSY)
1504   {
1505     return HAL_BUSY;
1506   }
1507   else if (hnand->State == HAL_NAND_STATE_READY)
1508   {
1509     /* Process Locked */
1510     __HAL_LOCK(hnand);
1511 
1512     /* Update the NAND controller state */
1513     hnand->State = HAL_NAND_STATE_BUSY;
1514 
1515     /* Identify the device address */
1516     deviceaddress = NAND_DEVICE;
1517 
1518     /* Page address calculation */
1519     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1520 
1521     /* Column in page address */
1522     columnaddress = COLUMN_ADDRESS(hnand);
1523 
1524     /* Spare area(s) write loop */
1525     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1526     {
1527       /* Cards with page size <= 512 bytes */
1528       if ((hnand->Config.PageSize) <= 512U)
1529       {
1530         /* Send write Spare area command sequence */
1531         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1532         __DSB();
1533         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1534         __DSB();
1535 
1536         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1537         {
1538           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1539           __DSB();
1540           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1541           __DSB();
1542           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1543           __DSB();
1544         }
1545         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1546         {
1547           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1548           __DSB();
1549           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1550           __DSB();
1551           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1552           __DSB();
1553           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1554           __DSB();
1555         }
1556       }
1557       else /* (hnand->Config.PageSize) > 512 */
1558       {
1559         /* Send write Spare area command sequence */
1560         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1561         __DSB();
1562         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1563         __DSB();
1564 
1565         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1566         {
1567           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1568           __DSB();
1569           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1570           __DSB();
1571           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1572           __DSB();
1573           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1574           __DSB();
1575         }
1576         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1577         {
1578           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1579           __DSB();
1580           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1581           __DSB();
1582           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1583           __DSB();
1584           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1585           __DSB();
1586           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1587           __DSB();
1588         }
1589       }
1590 
1591       /* Write data to memory */
1592       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1593       {
1594         *(__IO uint8_t *)deviceaddress = *buff;
1595         buff++;
1596         __DSB();
1597       }
1598 
1599       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1600       __DSB();
1601 
1602       /* Get tick */
1603       tickstart = HAL_GetTick();
1604 
1605       /* Read status until NAND is ready */
1606       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1607       {
1608         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1609         {
1610           /* Update the NAND controller state */
1611           hnand->State = HAL_NAND_STATE_ERROR;
1612 
1613           /* Process unlocked */
1614           __HAL_UNLOCK(hnand);
1615 
1616           return HAL_TIMEOUT;
1617         }
1618       }
1619 
1620       /* Increment written spare areas number */
1621       numspareareawritten++;
1622 
1623       /* Decrement spare areas to write */
1624       nbspare--;
1625 
1626       /* Increment the NAND address */
1627       nandaddress = (uint32_t)(nandaddress + 1U);
1628     }
1629 
1630     /* Update the NAND controller state */
1631     hnand->State = HAL_NAND_STATE_READY;
1632 
1633     /* Process unlocked */
1634     __HAL_UNLOCK(hnand);
1635   }
1636   else
1637   {
1638     return HAL_ERROR;
1639   }
1640 
1641   return HAL_OK;
1642 }
1643 
1644 /**
1645   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
1646   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1647   *                the configuration information for NAND module.
1648   * @param  pAddress  pointer to NAND address structure
1649   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
1650   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1651   * @retval HAL status
1652   */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1653 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1654                                                uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1655 {
1656   uint32_t index;
1657   uint32_t tickstart;
1658   uint32_t deviceaddress;
1659   uint32_t numspareareawritten = 0U;
1660   uint32_t nandaddress;
1661   uint32_t columnaddress;
1662   uint32_t nbspare = NumSpareAreaTowrite;
1663   uint16_t *buff = pBuffer;
1664 
1665   /* Check the NAND controller state */
1666   if (hnand->State == HAL_NAND_STATE_BUSY)
1667   {
1668     return HAL_BUSY;
1669   }
1670   else if (hnand->State == HAL_NAND_STATE_READY)
1671   {
1672     /* Process Locked */
1673     __HAL_LOCK(hnand);
1674 
1675     /* Update the NAND controller state */
1676     hnand->State = HAL_NAND_STATE_BUSY;
1677 
1678     /* Identify the device address */
1679     deviceaddress = NAND_DEVICE;
1680 
1681     /* NAND raw address calculation */
1682     nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1683 
1684     /* Column in page address */
1685     columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1686 
1687     /* Spare area(s) write loop */
1688     while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1689     {
1690       /* Cards with page size <= 512 bytes */
1691       if ((hnand->Config.PageSize) <= 512U)
1692       {
1693         /* Send write Spare area command sequence */
1694         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1695         __DSB();
1696         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1697         __DSB();
1698 
1699         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1700         {
1701           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1702           __DSB();
1703           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1704           __DSB();
1705           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1706           __DSB();
1707         }
1708         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1709         {
1710           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1711           __DSB();
1712           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1713           __DSB();
1714           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1715           __DSB();
1716           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1717           __DSB();
1718         }
1719       }
1720       else /* (hnand->Config.PageSize) > 512 */
1721       {
1722         /* Send write Spare area command sequence */
1723         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1724         __DSB();
1725         *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1726         __DSB();
1727 
1728         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1729         {
1730           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1731           __DSB();
1732           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1733           __DSB();
1734           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1735           __DSB();
1736           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1737           __DSB();
1738         }
1739         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1740         {
1741           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1742           __DSB();
1743           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1744           __DSB();
1745           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1746           __DSB();
1747           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1748           __DSB();
1749           *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1750           __DSB();
1751         }
1752       }
1753 
1754       /* Write data to memory */
1755       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1756       {
1757         *(__IO uint16_t *)deviceaddress = *buff;
1758         buff++;
1759         __DSB();
1760       }
1761 
1762       *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1763       __DSB();
1764 
1765       /* Get tick */
1766       tickstart = HAL_GetTick();
1767 
1768       /* Read status until NAND is ready */
1769       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1770       {
1771         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1772         {
1773           /* Update the NAND controller state */
1774           hnand->State = HAL_NAND_STATE_ERROR;
1775 
1776           /* Process unlocked */
1777           __HAL_UNLOCK(hnand);
1778 
1779           return HAL_TIMEOUT;
1780         }
1781       }
1782 
1783       /* Increment written spare areas number */
1784       numspareareawritten++;
1785 
1786       /* Decrement spare areas to write */
1787       nbspare--;
1788 
1789       /* Increment the NAND address */
1790       nandaddress = (uint32_t)(nandaddress + 1U);
1791     }
1792 
1793     /* Update the NAND controller state */
1794     hnand->State = HAL_NAND_STATE_READY;
1795 
1796     /* Process unlocked */
1797     __HAL_UNLOCK(hnand);
1798   }
1799   else
1800   {
1801     return HAL_ERROR;
1802   }
1803 
1804   return HAL_OK;
1805 }
1806 
1807 /**
1808   * @brief  NAND memory Block erase
1809   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1810   *                the configuration information for NAND module.
1811   * @param  pAddress  pointer to NAND address structure
1812   * @retval HAL status
1813   */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1814 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1815 {
1816   uint32_t deviceaddress;
1817 
1818   /* Check the NAND controller state */
1819   if (hnand->State == HAL_NAND_STATE_BUSY)
1820   {
1821     return HAL_BUSY;
1822   }
1823   else if (hnand->State == HAL_NAND_STATE_READY)
1824   {
1825     /* Process Locked */
1826     __HAL_LOCK(hnand);
1827 
1828     /* Update the NAND controller state */
1829     hnand->State = HAL_NAND_STATE_BUSY;
1830 
1831     /* Identify the device address */
1832     deviceaddress = NAND_DEVICE;
1833 
1834     /* Send Erase block command sequence */
1835     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
1836     __DSB();
1837     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1838     __DSB();
1839     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1840     __DSB();
1841     *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1842     __DSB();
1843 
1844     *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
1845     __DSB();
1846 
1847     /* Update the NAND controller state */
1848     hnand->State = HAL_NAND_STATE_READY;
1849 
1850     /* Process unlocked */
1851     __HAL_UNLOCK(hnand);
1852   }
1853   else
1854   {
1855     return HAL_ERROR;
1856   }
1857 
1858   return HAL_OK;
1859 }
1860 
1861 /**
1862   * @brief  Increment the NAND memory address
1863   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1864   *                the configuration information for NAND module.
1865   * @param pAddress pointer to NAND address structure
1866   * @retval The new status of the increment address operation. It can be:
1867   *           - NAND_VALID_ADDRESS: When the new address is valid address
1868   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
1869   */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1870 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1871 {
1872   uint32_t status = NAND_VALID_ADDRESS;
1873 
1874   /* Increment page address */
1875   pAddress->Page++;
1876 
1877   /* Check NAND address is valid */
1878   if (pAddress->Page == hnand->Config.BlockSize)
1879   {
1880     pAddress->Page = 0;
1881     pAddress->Block++;
1882 
1883     if (pAddress->Block == hnand->Config.PlaneSize)
1884     {
1885       pAddress->Block = 0;
1886       pAddress->Plane++;
1887 
1888       if (pAddress->Plane == (hnand->Config.PlaneNbr))
1889       {
1890         status = NAND_INVALID_ADDRESS;
1891       }
1892     }
1893   }
1894 
1895   return (status);
1896 }
1897 
1898 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1899 /**
1900   * @brief  Register a User NAND Callback
1901   *         To be used instead of the weak (surcharged) predefined callback
1902   * @param hnand : NAND handle
1903   * @param CallbackId : ID of the callback to be registered
1904   *        This parameter can be one of the following values:
1905   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1906   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1907   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1908   * @param pCallback : pointer to the Callback function
1909   * @retval status
1910   */
HAL_NAND_RegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId,pNAND_CallbackTypeDef pCallback)1911 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
1912                                             pNAND_CallbackTypeDef pCallback)
1913 {
1914   HAL_StatusTypeDef status = HAL_OK;
1915 
1916   if (pCallback == NULL)
1917   {
1918     return HAL_ERROR;
1919   }
1920 
1921   /* Process locked */
1922   __HAL_LOCK(hnand);
1923 
1924   if (hnand->State == HAL_NAND_STATE_READY)
1925   {
1926     switch (CallbackId)
1927     {
1928       case HAL_NAND_MSP_INIT_CB_ID :
1929         hnand->MspInitCallback = pCallback;
1930         break;
1931       case HAL_NAND_MSP_DEINIT_CB_ID :
1932         hnand->MspDeInitCallback = pCallback;
1933         break;
1934       case HAL_NAND_IT_CB_ID :
1935         hnand->ItCallback = pCallback;
1936         break;
1937       default :
1938         /* update return status */
1939         status =  HAL_ERROR;
1940         break;
1941     }
1942   }
1943   else if (hnand->State == HAL_NAND_STATE_RESET)
1944   {
1945     switch (CallbackId)
1946     {
1947       case HAL_NAND_MSP_INIT_CB_ID :
1948         hnand->MspInitCallback = pCallback;
1949         break;
1950       case HAL_NAND_MSP_DEINIT_CB_ID :
1951         hnand->MspDeInitCallback = pCallback;
1952         break;
1953       default :
1954         /* update return status */
1955         status =  HAL_ERROR;
1956         break;
1957     }
1958   }
1959   else
1960   {
1961     /* update return status */
1962     status =  HAL_ERROR;
1963   }
1964 
1965   /* Release Lock */
1966   __HAL_UNLOCK(hnand);
1967   return status;
1968 }
1969 
1970 /**
1971   * @brief  Unregister a User NAND Callback
1972   *         NAND Callback is redirected to the weak (surcharged) predefined callback
1973   * @param hnand : NAND handle
1974   * @param CallbackId : ID of the callback to be unregistered
1975   *        This parameter can be one of the following values:
1976   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1977   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1978   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1979   * @retval status
1980   */
HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId)1981 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1982 {
1983   HAL_StatusTypeDef status = HAL_OK;
1984 
1985   /* Process locked */
1986   __HAL_LOCK(hnand);
1987 
1988   if (hnand->State == HAL_NAND_STATE_READY)
1989   {
1990     switch (CallbackId)
1991     {
1992       case HAL_NAND_MSP_INIT_CB_ID :
1993         hnand->MspInitCallback = HAL_NAND_MspInit;
1994         break;
1995       case HAL_NAND_MSP_DEINIT_CB_ID :
1996         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1997         break;
1998       case HAL_NAND_IT_CB_ID :
1999         hnand->ItCallback = HAL_NAND_ITCallback;
2000         break;
2001       default :
2002         /* update return status */
2003         status =  HAL_ERROR;
2004         break;
2005     }
2006   }
2007   else if (hnand->State == HAL_NAND_STATE_RESET)
2008   {
2009     switch (CallbackId)
2010     {
2011       case HAL_NAND_MSP_INIT_CB_ID :
2012         hnand->MspInitCallback = HAL_NAND_MspInit;
2013         break;
2014       case HAL_NAND_MSP_DEINIT_CB_ID :
2015         hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
2016         break;
2017       default :
2018         /* update return status */
2019         status =  HAL_ERROR;
2020         break;
2021     }
2022   }
2023   else
2024   {
2025     /* update return status */
2026     status =  HAL_ERROR;
2027   }
2028 
2029   /* Release Lock */
2030   __HAL_UNLOCK(hnand);
2031   return status;
2032 }
2033 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
2034 
2035 /**
2036   * @}
2037   */
2038 
2039 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
2040   *  @brief   management functions
2041   *
2042 @verbatim
2043   ==============================================================================
2044                          ##### NAND Control functions #####
2045   ==============================================================================
2046   [..]
2047     This subsection provides a set of functions allowing to control dynamically
2048     the NAND interface.
2049 
2050 @endverbatim
2051   * @{
2052   */
2053 
2054 
2055 /**
2056   * @brief  Enables dynamically NAND ECC feature.
2057   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2058   *                the configuration information for NAND module.
2059   * @retval HAL status
2060   */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)2061 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2062 {
2063   /* Check the NAND controller state */
2064   if (hnand->State == HAL_NAND_STATE_BUSY)
2065   {
2066     return HAL_BUSY;
2067   }
2068   else if (hnand->State == HAL_NAND_STATE_READY)
2069   {
2070     /* Update the NAND state */
2071     hnand->State = HAL_NAND_STATE_BUSY;
2072 
2073     /* Enable ECC feature */
2074     (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2075 
2076     /* Update the NAND state */
2077     hnand->State = HAL_NAND_STATE_READY;
2078   }
2079   else
2080   {
2081     return HAL_ERROR;
2082   }
2083 
2084   return HAL_OK;
2085 }
2086 
2087 /**
2088   * @brief  Disables dynamically FMC_NAND ECC feature.
2089   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2090   *                the configuration information for NAND module.
2091   * @retval HAL status
2092   */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)2093 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2094 {
2095   /* Check the NAND controller state */
2096   if (hnand->State == HAL_NAND_STATE_BUSY)
2097   {
2098     return HAL_BUSY;
2099   }
2100   else if (hnand->State == HAL_NAND_STATE_READY)
2101   {
2102     /* Update the NAND state */
2103     hnand->State = HAL_NAND_STATE_BUSY;
2104 
2105     /* Disable ECC feature */
2106     (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2107 
2108     /* Update the NAND state */
2109     hnand->State = HAL_NAND_STATE_READY;
2110   }
2111   else
2112   {
2113     return HAL_ERROR;
2114   }
2115 
2116   return HAL_OK;
2117 }
2118 
2119 /**
2120   * @brief  Disables dynamically NAND ECC feature.
2121   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2122   *                the configuration information for NAND module.
2123   * @param  ECCval pointer to ECC value
2124   * @param  Timeout maximum timeout to wait
2125   * @retval HAL status
2126   */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)2127 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2128 {
2129   HAL_StatusTypeDef status;
2130 
2131   /* Check the NAND controller state */
2132   if (hnand->State == HAL_NAND_STATE_BUSY)
2133   {
2134     return HAL_BUSY;
2135   }
2136   else if (hnand->State == HAL_NAND_STATE_READY)
2137   {
2138     /* Update the NAND state */
2139     hnand->State = HAL_NAND_STATE_BUSY;
2140 
2141     /* Get NAND ECC value */
2142     status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2143 
2144     /* Update the NAND state */
2145     hnand->State = HAL_NAND_STATE_READY;
2146   }
2147   else
2148   {
2149     return HAL_ERROR;
2150   }
2151 
2152   return status;
2153 }
2154 
2155 /**
2156   * @}
2157   */
2158 
2159 
2160 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2161   *  @brief   Peripheral State functions
2162   *
2163 @verbatim
2164   ==============================================================================
2165                          ##### NAND State functions #####
2166   ==============================================================================
2167   [..]
2168     This subsection permits to get in run-time the status of the NAND controller
2169     and the data flow.
2170 
2171 @endverbatim
2172   * @{
2173   */
2174 
2175 /**
2176   * @brief  return the NAND state
2177   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2178   *                the configuration information for NAND module.
2179   * @retval HAL state
2180   */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)2181 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2182 {
2183   return hnand->State;
2184 }
2185 
2186 /**
2187   * @brief  NAND memory read status
2188   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2189   *                the configuration information for NAND module.
2190   * @retval NAND status
2191   */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)2192 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2193 {
2194   uint32_t data;
2195   uint32_t deviceaddress;
2196   UNUSED(hnand);
2197 
2198   /* Identify the device address */
2199   deviceaddress = NAND_DEVICE;
2200 
2201   /* Send Read status operation command */
2202   *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
2203 
2204   /* Read status register data */
2205   data = *(__IO uint8_t *)deviceaddress;
2206 
2207   /* Return the status */
2208   if ((data & NAND_ERROR) == NAND_ERROR)
2209   {
2210     return NAND_ERROR;
2211   }
2212   else if ((data & NAND_READY) == NAND_READY)
2213   {
2214     return NAND_READY;
2215   }
2216   else
2217   {
2218     return NAND_BUSY;
2219   }
2220 }
2221 
2222 /**
2223   * @}
2224   */
2225 
2226 /**
2227   * @}
2228   */
2229 
2230 /**
2231   * @}
2232   */
2233 
2234 #endif /* HAL_NAND_MODULE_ENABLED  */
2235 
2236 /**
2237   * @}
2238   */
2239 
2240 
2241 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2242