xref: /btstack/port/stm32-l451-miromico-sx1280/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_nand.c (revision 2fd737d36a1de5d778cacc671d4b4d8c4f3fed82)
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     *** 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) 2017 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 "stm32l4xx_hal.h"
111 
112 #if defined(FMC_BANK3)
113 
114 /** @addtogroup STM32L4xx_HAL_Driver
115   * @{
116   */
117 
118 #ifdef HAL_NAND_MODULE_ENABLED
119 
120 /** @defgroup NAND NAND
121   * @brief NAND HAL module driver
122   * @{
123   */
124 
125 /* Private typedef -----------------------------------------------------------*/
126 /* Private Constants ------------------------------------------------------------*/
127 /* Private macro -------------------------------------------------------------*/
128 /* Private variables ---------------------------------------------------------*/
129 /* Private function prototypes -----------------------------------------------*/
130 /* Exported functions ---------------------------------------------------------*/
131 
132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
133   * @{
134   */
135 
136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
137   * @brief    Initialization and Configuration functions
138   *
139   @verbatim
140   ==============================================================================
141             ##### NAND Initialization and de-initialization functions #####
142   ==============================================================================
143   [..]
144     This section provides functions allowing to initialize/de-initialize
145     the NAND memory
146 
147 @endverbatim
148   * @{
149   */
150 
151 /**
152   * @brief  Perform NAND memory Initialization sequence
153   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
154   *                the configuration information for NAND module.
155   * @param  ComSpace_Timing pointer to Common space timing structure
156   * @param  AttSpace_Timing pointer to Attribute space timing structure
157   * @retval HAL status
158   */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)159 HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, 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
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
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
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
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
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
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, uint32_t NumPageToRead)
518 {
519   uint32_t index;
520   uint32_t tickstart;
521   uint32_t deviceAddress, numPagesRead = 0U, nandAddress, nbpages = NumPageToRead;
522   uint8_t * buff = pBuffer;
523 
524   /* Check the NAND controller state */
525   if (hnand->State == HAL_NAND_STATE_BUSY)
526   {
527     return HAL_BUSY;
528   }
529   else if (hnand->State == HAL_NAND_STATE_READY)
530   {
531     /* Process Locked */
532     __HAL_LOCK(hnand);
533 
534     /* Update the NAND controller state */
535     hnand->State = HAL_NAND_STATE_BUSY;
536 
537     /* Identify the device address */
538     deviceAddress = NAND_DEVICE;
539 
540     /* NAND raw address calculation */
541     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
542 
543     /* Page(s) read loop */
544     while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
545     {
546       /* Send read page command sequence */
547       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
548       __DSB();
549 
550       /* Cards with page size <= 512 bytes */
551       if ((hnand->Config.PageSize) <= 512U)
552       {
553         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
554         {
555           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
556           __DSB();
557           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
558           __DSB();
559           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
560           __DSB();
561         }
562         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
563         {
564           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
565           __DSB();
566           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
567           __DSB();
568           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
569           __DSB();
570           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
571           __DSB();
572         }
573       }
574       else /* (hnand->Config.PageSize) > 512 */
575       {
576         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
577         {
578           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
579           __DSB();
580           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
581           __DSB();
582           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
583           __DSB();
584           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
585           __DSB();
586         }
587         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
588         {
589           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
590           __DSB();
591           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
592           __DSB();
593           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
594           __DSB();
595           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
596           __DSB();
597           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
598           __DSB();
599         }
600       }
601 
602       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
603       __DSB();
604 
605 
606       if (hnand->Config.ExtraCommandEnable == ENABLE)
607       {
608         /* Get tick */
609         tickstart = HAL_GetTick();
610 
611         /* Read status until NAND is ready */
612         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
613         {
614           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
615           {
616             /* Update the NAND controller state */
617             hnand->State = HAL_NAND_STATE_ERROR;
618 
619             /* Process unlocked */
620             __HAL_UNLOCK(hnand);
621 
622             return HAL_TIMEOUT;
623           }
624         }
625 
626         /* Go back to read mode */
627         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
628         __DSB();
629       }
630 
631       /* Get Data into Buffer */
632       for (index = 0U; index < hnand->Config.PageSize; index++)
633       {
634         *buff = *(uint8_t *)deviceAddress;
635         buff++;
636       }
637 
638       /* Increment read pages number */
639       numPagesRead++;
640 
641       /* Decrement pages to read */
642       nbpages--;
643 
644       /* Increment the NAND address */
645       nandAddress = (uint32_t)(nandAddress + 1U);
646     }
647 
648     /* Update the NAND controller state */
649     hnand->State = HAL_NAND_STATE_READY;
650 
651     /* Process unlocked */
652     __HAL_UNLOCK(hnand);
653   }
654   else
655   {
656     return HAL_ERROR;
657   }
658 
659   return HAL_OK;
660 }
661 
662 /**
663   * @brief  Read Page(s) from NAND memory block (16-bits addressing)
664   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
665   *                the configuration information for NAND module.
666   * @param  pAddress  pointer to NAND address structure
667   * @param  pBuffer  pointer to destination read buffer. pBuffer should be 16bits aligned
668   * @param  NumPageToRead  number of pages to read from block
669   * @retval HAL status
670   */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)671 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
672 {
673   uint32_t index;
674   uint32_t tickstart;
675   uint32_t deviceAddress, numPagesRead = 0, nandAddress, nbpages = NumPageToRead;
676   uint16_t * buff = pBuffer;
677 
678   /* Check the NAND controller state */
679   if (hnand->State == HAL_NAND_STATE_BUSY)
680   {
681     return HAL_BUSY;
682   }
683   else if (hnand->State == HAL_NAND_STATE_READY)
684   {
685     /* Process Locked */
686     __HAL_LOCK(hnand);
687 
688     /* Update the NAND controller state */
689     hnand->State = HAL_NAND_STATE_BUSY;
690 
691     /* Identify the device address */
692     deviceAddress = NAND_DEVICE;
693 
694     /* NAND raw address calculation */
695     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
696 
697     /* Page(s) read loop */
698     while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
699     {
700       /* Send read page command sequence */
701       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
702       __DSB();
703 
704       /* Cards with page size <= 512 bytes */
705       if ((hnand->Config.PageSize) <= 512U)
706       {
707         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
708         {
709           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
710           __DSB();
711           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
712           __DSB();
713           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
714           __DSB();
715         }
716         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
717         {
718           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
719           __DSB();
720           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
721           __DSB();
722           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
723           __DSB();
724           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
725           __DSB();
726         }
727       }
728       else /* (hnand->Config.PageSize) > 512 */
729       {
730         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
731         {
732           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
733           __DSB();
734           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
735           __DSB();
736           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
737           __DSB();
738           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
739           __DSB();
740         }
741         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
742         {
743           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
744           __DSB();
745           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
746           __DSB();
747           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
748           __DSB();
749           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
750           __DSB();
751           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
752           __DSB();
753         }
754       }
755 
756       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
757       __DSB();
758 
759       if (hnand->Config.ExtraCommandEnable == ENABLE)
760       {
761         /* Get tick */
762         tickstart = HAL_GetTick();
763 
764         /* Read status until NAND is ready */
765         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
766         {
767           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
768           {
769             /* Update the NAND controller state */
770             hnand->State = HAL_NAND_STATE_ERROR;
771 
772             /* Process unlocked */
773             __HAL_UNLOCK(hnand);
774 
775             return HAL_TIMEOUT;
776           }
777         }
778 
779         /* Go back to read mode */
780         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
781         __DSB();
782       }
783 
784       /* Get Data into Buffer */
785       for (index = 0U; index < hnand->Config.PageSize; index++)
786       {
787         *buff = *(uint16_t *)deviceAddress;
788         buff++;
789       }
790 
791       /* Increment read pages number */
792       numPagesRead++;
793 
794       /* Decrement pages to read */
795       nbpages--;
796 
797       /* Increment the NAND address */
798       nandAddress = (uint32_t)(nandAddress + 1U);
799     }
800 
801     /* Update the NAND controller state */
802     hnand->State = HAL_NAND_STATE_READY;
803 
804     /* Process unlocked */
805     __HAL_UNLOCK(hnand);
806   }
807   else
808   {
809     return HAL_ERROR;
810   }
811 
812   return HAL_OK;
813 }
814 
815 /**
816   * @brief  Write Page(s) to NAND memory block (8-bits addressing)
817   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
818   *                the configuration information for NAND module.
819   * @param  pAddress  pointer to NAND address structure
820   * @param  pBuffer  pointer to source buffer to write
821   * @param  NumPageToWrite   number of pages to write to block
822   * @retval HAL status
823   */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)824 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
825 {
826   uint32_t index;
827   uint32_t tickstart;
828   uint32_t deviceAddress, numPagesWritten = 0, nandAddress, nbpages = NumPageToWrite;
829   uint8_t * buff = pBuffer;
830 
831   /* Check the NAND controller state */
832   if (hnand->State == HAL_NAND_STATE_BUSY)
833   {
834     return HAL_BUSY;
835   }
836   else if (hnand->State == HAL_NAND_STATE_READY)
837   {
838     /* Process Locked */
839     __HAL_LOCK(hnand);
840 
841     /* Update the NAND controller state */
842     hnand->State = HAL_NAND_STATE_BUSY;
843 
844     /* Identify the device address */
845     deviceAddress = NAND_DEVICE;
846 
847     /* NAND raw address calculation */
848     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
849 
850     /* Page(s) write loop */
851     while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
852     {
853       /* Send write page command sequence */
854       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
855       __DSB();
856       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
857       __DSB();
858 
859       /* Cards with page size <= 512 bytes */
860       if ((hnand->Config.PageSize) <= 512U)
861       {
862         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
863         {
864           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
865           __DSB();
866           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
867           __DSB();
868           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
869           __DSB();
870         }
871         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
872         {
873           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
874           __DSB();
875           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
876           __DSB();
877           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
878           __DSB();
879           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
880           __DSB();
881         }
882       }
883       else /* (hnand->Config.PageSize) > 512 */
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)) = 0x00U;
890           __DSB();
891           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
892           __DSB();
893           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
894           __DSB();
895         }
896         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
897         {
898           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
899           __DSB();
900           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
901           __DSB();
902           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
903           __DSB();
904           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
905           __DSB();
906           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
907           __DSB();
908         }
909       }
910 
911       /* Write data to memory */
912       for (index = 0U; index < hnand->Config.PageSize; index++)
913       {
914         *(__IO uint8_t *)deviceAddress = *buff;
915         buff++;
916         __DSB();
917       }
918 
919       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
920       __DSB();
921 
922       /* Get tick */
923       tickstart = HAL_GetTick();
924 
925       /* Read status until NAND is ready */
926       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
927       {
928         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
929         {
930           /* Update the NAND controller state */
931           hnand->State = HAL_NAND_STATE_ERROR;
932 
933           /* Process unlocked */
934           __HAL_UNLOCK(hnand);
935 
936           return HAL_TIMEOUT;
937         }
938       }
939 
940       /* Increment written pages number */
941       numPagesWritten++;
942 
943       /* Decrement pages to write */
944       nbpages--;
945 
946       /* Increment the NAND address */
947       nandAddress = (uint32_t)(nandAddress + 1U);
948     }
949 
950     /* Update the NAND controller state */
951     hnand->State = HAL_NAND_STATE_READY;
952 
953     /* Process unlocked */
954     __HAL_UNLOCK(hnand);
955   }
956   else
957   {
958     return HAL_ERROR;
959   }
960 
961   return HAL_OK;
962 }
963 
964 /**
965   * @brief  Write Page(s) to NAND memory block (16-bits addressing)
966   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
967   *                the configuration information for NAND module.
968   * @param  pAddress  pointer to NAND address structure
969   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned
970   * @param  NumPageToWrite   number of pages to write to block
971   * @retval HAL status
972   */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)973 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
974 {
975   uint32_t index;
976   uint32_t tickstart;
977   uint32_t deviceAddress, numPagesWritten = 0, nandAddress, nbpages = NumPageToWrite;
978   uint16_t * buff = pBuffer;
979 
980   /* Check the NAND controller state */
981   if (hnand->State == HAL_NAND_STATE_BUSY)
982   {
983     return HAL_BUSY;
984   }
985   else if (hnand->State == HAL_NAND_STATE_READY)
986   {
987     /* Process Locked */
988     __HAL_LOCK(hnand);
989 
990     /* Update the NAND controller state */
991     hnand->State = HAL_NAND_STATE_BUSY;
992 
993     /* Identify the device address */
994     deviceAddress = NAND_DEVICE;
995 
996     /* NAND raw address calculation */
997     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
998 
999     /* Page(s) write loop */
1000     while ((nbpages != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1001     {
1002       /* Send write page command sequence */
1003       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1004       __DSB();
1005       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1006       __DSB();
1007 
1008       /* Cards with page size <= 512 bytes */
1009       if ((hnand->Config.PageSize) <= 512U)
1010       {
1011         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1012         {
1013           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1014           __DSB();
1015           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1016           __DSB();
1017           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1018           __DSB();
1019         }
1020         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1021         {
1022           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1023           __DSB();
1024           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1025           __DSB();
1026           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1027           __DSB();
1028           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1029           __DSB();
1030         }
1031       }
1032       else /* (hnand->Config.PageSize) > 512 */
1033       {
1034         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1035         {
1036           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1037           __DSB();
1038           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1039           __DSB();
1040           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1041           __DSB();
1042           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1043           __DSB();
1044         }
1045         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1046         {
1047           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1048           __DSB();
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 
1060       /* Write data to memory */
1061       for (index = 0U; index < hnand->Config.PageSize; index++)
1062       {
1063         *(__IO uint16_t *)deviceAddress = *buff;
1064         buff++;
1065         __DSB();
1066       }
1067 
1068       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1069       __DSB();
1070 
1071       /* Get tick */
1072       tickstart = HAL_GetTick();
1073 
1074       /* Read status until NAND is ready */
1075       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1076       {
1077         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1078         {
1079           /* Update the NAND controller state */
1080           hnand->State = HAL_NAND_STATE_ERROR;
1081 
1082           /* Process unlocked */
1083           __HAL_UNLOCK(hnand);
1084 
1085           return HAL_TIMEOUT;
1086         }
1087       }
1088 
1089       /* Increment written pages number */
1090       numPagesWritten++;
1091 
1092       /* Decrement pages to write */
1093       nbpages--;
1094 
1095       /* Increment the NAND address */
1096       nandAddress = (uint32_t)(nandAddress + 1U);
1097     }
1098 
1099     /* Update the NAND controller state */
1100     hnand->State = HAL_NAND_STATE_READY;
1101 
1102     /* Process unlocked */
1103     __HAL_UNLOCK(hnand);
1104   }
1105   else
1106   {
1107     return HAL_ERROR;
1108   }
1109 
1110   return HAL_OK;
1111 }
1112 
1113 /**
1114   * @brief  Read Spare area(s) from NAND memory (8-bits addressing)
1115   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1116   *                the configuration information for NAND module.
1117   * @param  pAddress  pointer to NAND address structure
1118   * @param  pBuffer pointer to source buffer to write
1119   * @param  NumSpareAreaToRead Number of spare area to read
1120   * @retval HAL status
1121 */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1122 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1123 {
1124   uint32_t index;
1125   uint32_t tickstart;
1126   uint32_t deviceAddress, numSpareAreaRead = 0, nandAddress, columnAddress, nbspare = NumSpareAreaToRead;
1127   uint8_t * buff = pBuffer;
1128 
1129   /* Check the NAND controller state */
1130   if (hnand->State == HAL_NAND_STATE_BUSY)
1131   {
1132     return HAL_BUSY;
1133   }
1134   else if (hnand->State == HAL_NAND_STATE_READY)
1135   {
1136     /* Process Locked */
1137     __HAL_LOCK(hnand);
1138 
1139     /* Update the NAND controller state */
1140     hnand->State = HAL_NAND_STATE_BUSY;
1141 
1142     /* Identify the device address */
1143     deviceAddress = NAND_DEVICE;
1144 
1145     /* NAND raw address calculation */
1146     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1147 
1148     /* Column in page address */
1149     columnAddress = COLUMN_ADDRESS(hnand);
1150 
1151     /* Spare area(s) read loop */
1152     while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1153     {
1154       /* Cards with page size <= 512 bytes */
1155       if ((hnand->Config.PageSize) <= 512U)
1156       {
1157         /* Send read spare area command sequence */
1158         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1159         __DSB();
1160 
1161         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1162         {
1163           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1164           __DSB();
1165           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1166           __DSB();
1167           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1168           __DSB();
1169         }
1170         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1171         {
1172           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1173           __DSB();
1174           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1175           __DSB();
1176           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1177           __DSB();
1178           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1179           __DSB();
1180         }
1181       }
1182       else /* (hnand->Config.PageSize) > 512 */
1183       {
1184         /* Send read spare area command sequence */
1185         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1186         __DSB();
1187 
1188         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1189         {
1190           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1191           __DSB();
1192           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1193           __DSB();
1194           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1195           __DSB();
1196           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1197           __DSB();
1198         }
1199         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1200         {
1201           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1202           __DSB();
1203           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1204           __DSB();
1205           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1206           __DSB();
1207           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1208           __DSB();
1209           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1210           __DSB();
1211         }
1212       }
1213 
1214       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1215       __DSB();
1216 
1217       if (hnand->Config.ExtraCommandEnable == ENABLE)
1218       {
1219         /* Get tick */
1220         tickstart = HAL_GetTick();
1221 
1222         /* Read status until NAND is ready */
1223         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1224         {
1225           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1226           {
1227             /* Update the NAND controller state */
1228             hnand->State = HAL_NAND_STATE_ERROR;
1229 
1230             /* Process unlocked */
1231             __HAL_UNLOCK(hnand);
1232 
1233             return HAL_TIMEOUT;
1234           }
1235         }
1236 
1237         /* Go back to read mode */
1238         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1239         __DSB();
1240       }
1241 
1242       /* Get Data into Buffer */
1243       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1244       {
1245         *buff = *(uint8_t *)deviceAddress;
1246         buff++;
1247       }
1248 
1249       /* Increment read spare areas number */
1250       numSpareAreaRead++;
1251 
1252       /* Decrement spare areas to read */
1253       nbspare--;
1254 
1255       /* Increment the NAND address */
1256       nandAddress = (uint32_t)(nandAddress + 1U);
1257     }
1258 
1259     /* Update the NAND controller state */
1260     hnand->State = HAL_NAND_STATE_READY;
1261 
1262     /* Process unlocked */
1263     __HAL_UNLOCK(hnand);
1264   }
1265   else
1266   {
1267     return HAL_ERROR;
1268   }
1269 
1270   return HAL_OK;
1271 }
1272 
1273 /**
1274   * @brief  Read Spare area(s) from NAND memory (16-bits addressing)
1275   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1276   *                the configuration information for NAND module.
1277   * @param  pAddress  pointer to NAND address structure
1278   * @param  pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1279   * @param  NumSpareAreaToRead Number of spare area to read
1280   * @retval HAL status
1281 */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1282 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1283 {
1284   uint32_t index;
1285   uint32_t tickstart;
1286   uint32_t deviceAddress, numSpareAreaRead = 0, nandAddress, columnAddress, nbspare = NumSpareAreaToRead;
1287   uint16_t * buff = pBuffer;
1288 
1289   /* Check the NAND controller state */
1290   if (hnand->State == HAL_NAND_STATE_BUSY)
1291   {
1292     return HAL_BUSY;
1293   }
1294   else if (hnand->State == HAL_NAND_STATE_READY)
1295   {
1296     /* Process Locked */
1297     __HAL_LOCK(hnand);
1298 
1299     /* Update the NAND controller state */
1300     hnand->State = HAL_NAND_STATE_BUSY;
1301 
1302     /* Identify the device address */
1303     deviceAddress = NAND_DEVICE;
1304 
1305     /* NAND raw address calculation */
1306     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1307 
1308     /* Column in page address */
1309     columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
1310 
1311     /* Spare area(s) read loop */
1312     while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1313     {
1314       /* Cards with page size <= 512 bytes */
1315       if ((hnand->Config.PageSize) <= 512U)
1316       {
1317         /* Send read spare area command sequence */
1318         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1319         __DSB();
1320 
1321         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1322         {
1323           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1324           __DSB();
1325           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1326           __DSB();
1327           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1328           __DSB();
1329         }
1330         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1331         {
1332           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1333           __DSB();
1334           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1335           __DSB();
1336           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1337           __DSB();
1338           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1339           __DSB();
1340         }
1341       }
1342       else /* (hnand->Config.PageSize) > 512 */
1343       {
1344         /* Send read spare area command sequence */
1345         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1346         __DSB();
1347 
1348         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1349         {
1350           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1351           __DSB();
1352           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1353           __DSB();
1354           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1355           __DSB();
1356           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1357           __DSB();
1358         }
1359         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1360         {
1361           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1362           __DSB();
1363           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1364           __DSB();
1365           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1366           __DSB();
1367           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1368           __DSB();
1369           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1370           __DSB();
1371         }
1372       }
1373 
1374       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1375       __DSB();
1376 
1377       if (hnand->Config.ExtraCommandEnable == ENABLE)
1378       {
1379         /* Get tick */
1380         tickstart = HAL_GetTick();
1381 
1382         /* Read status until NAND is ready */
1383         while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1384         {
1385           if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1386           {
1387             /* Update the NAND controller state */
1388             hnand->State = HAL_NAND_STATE_ERROR;
1389 
1390             /* Process unlocked */
1391             __HAL_UNLOCK(hnand);
1392 
1393             return HAL_TIMEOUT;
1394           }
1395         }
1396 
1397         /* Go back to read mode */
1398         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1399         __DSB();
1400       }
1401 
1402       /* Get Data into Buffer */
1403       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1404       {
1405         *buff = *(uint16_t *)deviceAddress;
1406         buff++;
1407       }
1408 
1409       /* Increment read spare areas number */
1410       numSpareAreaRead++;
1411 
1412       /* Decrement spare areas to read */
1413       nbspare--;
1414 
1415       /* Increment the NAND address */
1416       nandAddress = (uint32_t)(nandAddress + 1U);
1417     }
1418 
1419     /* Update the NAND controller state */
1420     hnand->State = HAL_NAND_STATE_READY;
1421 
1422     /* Process unlocked */
1423     __HAL_UNLOCK(hnand);
1424   }
1425   else
1426   {
1427     return HAL_ERROR;
1428   }
1429 
1430   return HAL_OK;
1431 }
1432 
1433 /**
1434   * @brief  Write Spare area(s) to NAND memory (8-bits addressing)
1435   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1436   *                the configuration information for NAND module.
1437   * @param  pAddress  pointer to NAND address structure
1438   * @param  pBuffer  pointer to source buffer to write
1439   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1440   * @retval HAL status
1441   */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1442 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1443 {
1444   uint32_t index;
1445   uint32_t tickstart;
1446   uint32_t deviceAddress, numSpareAreaWritten = 0, nandAddress, columnAddress, nbspare = NumSpareAreaTowrite;
1447   uint8_t * buff = pBuffer;
1448 
1449   /* Check the NAND controller state */
1450   if (hnand->State == HAL_NAND_STATE_BUSY)
1451   {
1452     return HAL_BUSY;
1453   }
1454   else if (hnand->State == HAL_NAND_STATE_READY)
1455   {
1456     /* Process Locked */
1457     __HAL_LOCK(hnand);
1458 
1459     /* Update the NAND controller state */
1460     hnand->State = HAL_NAND_STATE_BUSY;
1461 
1462     /* Identify the device address */
1463     deviceAddress = NAND_DEVICE;
1464 
1465     /* Page address calculation */
1466     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1467 
1468     /* Column in page address */
1469     columnAddress = COLUMN_ADDRESS(hnand);
1470 
1471     /* Spare area(s) write loop */
1472     while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1473     {
1474       /* Cards with page size <= 512 bytes */
1475       if ((hnand->Config.PageSize) <= 512U)
1476       {
1477         /* Send write Spare area command sequence */
1478         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1479         __DSB();
1480         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1481         __DSB();
1482 
1483         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1484         {
1485           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1486           __DSB();
1487           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1488           __DSB();
1489           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1490           __DSB();
1491         }
1492         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1493         {
1494           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1495           __DSB();
1496           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1497           __DSB();
1498           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1499           __DSB();
1500           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1501           __DSB();
1502         }
1503       }
1504       else /* (hnand->Config.PageSize) > 512 */
1505       {
1506         /* Send write Spare area command sequence */
1507         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1508         __DSB();
1509         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1510         __DSB();
1511 
1512         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1513         {
1514           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1515           __DSB();
1516           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1517           __DSB();
1518           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1519           __DSB();
1520           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1521           __DSB();
1522         }
1523         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1524         {
1525           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1526           __DSB();
1527           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1528           __DSB();
1529           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1530           __DSB();
1531           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1532           __DSB();
1533           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1534           __DSB();
1535         }
1536       }
1537 
1538       /* Write data to memory */
1539       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1540       {
1541         *(__IO uint8_t *)deviceAddress = *buff;
1542         buff++;
1543         __DSB();
1544       }
1545 
1546       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1547       __DSB();
1548 
1549       /* Get tick */
1550       tickstart = HAL_GetTick();
1551 
1552       /* Read status until NAND is ready */
1553       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1554       {
1555         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1556         {
1557           /* Update the NAND controller state */
1558           hnand->State = HAL_NAND_STATE_ERROR;
1559 
1560           /* Process unlocked */
1561           __HAL_UNLOCK(hnand);
1562 
1563           return HAL_TIMEOUT;
1564         }
1565       }
1566 
1567       /* Increment written spare areas number */
1568       numSpareAreaWritten++;
1569 
1570       /* Decrement spare areas to write */
1571       nbspare--;
1572 
1573       /* Increment the NAND address */
1574       nandAddress = (uint32_t)(nandAddress + 1U);
1575     }
1576 
1577     /* Update the NAND controller state */
1578     hnand->State = HAL_NAND_STATE_READY;
1579 
1580     /* Process unlocked */
1581     __HAL_UNLOCK(hnand);
1582   }
1583   else
1584   {
1585     return HAL_ERROR;
1586   }
1587 
1588   return HAL_OK;
1589 }
1590 
1591 /**
1592   * @brief  Write Spare area(s) to NAND memory (16-bits addressing)
1593   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1594   *                the configuration information for NAND module.
1595   * @param  pAddress  pointer to NAND address structure
1596   * @param  pBuffer  pointer to source buffer to write. pBuffer should be 16bits aligned.
1597   * @param  NumSpareAreaTowrite   number of spare areas to write to block
1598   * @retval HAL status
1599   */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1600 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1601 {
1602   uint32_t index;
1603   uint32_t tickstart;
1604   uint32_t deviceAddress, numSpareAreaWritten = 0, nandAddress, columnAddress, nbspare = NumSpareAreaTowrite;
1605   uint16_t * buff = pBuffer;
1606 
1607   /* Check the NAND controller state */
1608   if (hnand->State == HAL_NAND_STATE_BUSY)
1609   {
1610     return HAL_BUSY;
1611   }
1612   else if (hnand->State == HAL_NAND_STATE_READY)
1613   {
1614     /* Process Locked */
1615     __HAL_LOCK(hnand);
1616 
1617     /* Update the NAND controller state */
1618     hnand->State = HAL_NAND_STATE_BUSY;
1619 
1620     /* Identify the device address */
1621     deviceAddress = NAND_DEVICE;
1622 
1623     /* NAND raw address calculation */
1624     nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1625 
1626     /* Column in page address */
1627     columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
1628 
1629     /* Spare area(s) write loop */
1630     while ((nbspare != 0U) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1631     {
1632       /* Cards with page size <= 512 bytes */
1633       if ((hnand->Config.PageSize) <= 512U)
1634       {
1635         /* Send write Spare area command sequence */
1636         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1637         __DSB();
1638         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1639         __DSB();
1640 
1641         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1642         {
1643           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1644           __DSB();
1645           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1646           __DSB();
1647           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1648           __DSB();
1649         }
1650         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1651         {
1652           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00U;
1653           __DSB();
1654           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1655           __DSB();
1656           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1657           __DSB();
1658           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1659           __DSB();
1660         }
1661       }
1662       else /* (hnand->Config.PageSize) > 512 */
1663       {
1664         /* Send write Spare area command sequence */
1665         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1666         __DSB();
1667         *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1668         __DSB();
1669 
1670         if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1671         {
1672           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1673           __DSB();
1674           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1675           __DSB();
1676           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1677           __DSB();
1678           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1679           __DSB();
1680         }
1681         else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1682         {
1683           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1684           __DSB();
1685           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1686           __DSB();
1687           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1688           __DSB();
1689           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1690           __DSB();
1691           *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1692           __DSB();
1693         }
1694       }
1695 
1696       /* Write data to memory */
1697       for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1698       {
1699         *(__IO uint16_t *)deviceAddress = *buff;
1700         buff++;
1701         __DSB();
1702       }
1703 
1704       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1705       __DSB();
1706 
1707       /* Get tick */
1708       tickstart = HAL_GetTick();
1709 
1710       /* Read status until NAND is ready */
1711       while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1712       {
1713         if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1714         {
1715           /* Update the NAND controller state */
1716           hnand->State = HAL_NAND_STATE_ERROR;
1717 
1718           /* Process unlocked */
1719           __HAL_UNLOCK(hnand);
1720 
1721           return HAL_TIMEOUT;
1722         }
1723       }
1724 
1725       /* Increment written spare areas number */
1726       numSpareAreaWritten++;
1727 
1728       /* Decrement spare areas to write */
1729       nbspare--;
1730 
1731       /* Increment the NAND address */
1732       nandAddress = (uint32_t)(nandAddress + 1U);
1733     }
1734 
1735     /* Update the NAND controller state */
1736     hnand->State = HAL_NAND_STATE_READY;
1737 
1738     /* Process unlocked */
1739     __HAL_UNLOCK(hnand);
1740   }
1741   else
1742   {
1743     return HAL_ERROR;
1744   }
1745 
1746   return HAL_OK;
1747 }
1748 
1749 /**
1750   * @brief  NAND memory Block erase
1751   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1752   *                the configuration information for NAND module.
1753   * @param  pAddress  pointer to NAND address structure
1754   * @retval HAL status
1755   */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1756 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1757 {
1758   uint32_t DeviceAddress;
1759 
1760   /* Check the NAND controller state */
1761   if (hnand->State == HAL_NAND_STATE_BUSY)
1762   {
1763     return HAL_BUSY;
1764   }
1765   else if (hnand->State == HAL_NAND_STATE_READY)
1766   {
1767     /* Process Locked */
1768     __HAL_LOCK(hnand);
1769 
1770     /* Update the NAND controller state */
1771     hnand->State = HAL_NAND_STATE_BUSY;
1772 
1773     /* Identify the device address */
1774     DeviceAddress = NAND_DEVICE;
1775 
1776     /* Send Erase block command sequence */
1777     *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
1778     __DSB();
1779     *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1780     __DSB();
1781     *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1782     __DSB();
1783     *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1784     __DSB();
1785 
1786     *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1787     __DSB();
1788 
1789     /* Update the NAND controller state */
1790     hnand->State = HAL_NAND_STATE_READY;
1791 
1792     /* Process unlocked */
1793     __HAL_UNLOCK(hnand);
1794   }
1795   else
1796   {
1797     return HAL_ERROR;
1798   }
1799 
1800   return HAL_OK;
1801 }
1802 
1803 /**
1804   * @brief  Increment the NAND memory address
1805   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1806   *                the configuration information for NAND module.
1807   * @param pAddress pointer to NAND address structure
1808   * @retval The new status of the increment address operation. It can be:
1809   *           - NAND_VALID_ADDRESS: When the new address is valid address
1810   *           - NAND_INVALID_ADDRESS: When the new address is invalid address
1811   */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1812 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1813 {
1814   uint32_t status = NAND_VALID_ADDRESS;
1815 
1816   /* Increment page address */
1817   pAddress->Page++;
1818 
1819   /* Check NAND address is valid */
1820   if (pAddress->Page == hnand->Config.BlockSize)
1821   {
1822     pAddress->Page = 0;
1823     pAddress->Block++;
1824 
1825     if (pAddress->Block == hnand->Config.PlaneSize)
1826     {
1827       pAddress->Block = 0;
1828       pAddress->Plane++;
1829 
1830       if (pAddress->Plane == (hnand->Config.PlaneNbr))
1831       {
1832         status = NAND_INVALID_ADDRESS;
1833       }
1834     }
1835   }
1836 
1837   return (status);
1838 }
1839 
1840 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1841 /**
1842   * @brief  Register a User NAND Callback
1843   *         To be used instead of the weak (surcharged) predefined callback
1844   * @param hnand : NAND handle
1845   * @param CallbackId : ID of the callback to be registered
1846   *        This parameter can be one of the following values:
1847   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1848   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1849   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1850   * @param pCallback : pointer to the Callback function
1851   * @retval status
1852   */
HAL_NAND_RegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId,pNAND_CallbackTypeDef pCallback)1853 HAL_StatusTypeDef HAL_NAND_RegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, pNAND_CallbackTypeDef pCallback)
1854 {
1855   HAL_StatusTypeDef status = HAL_OK;
1856 
1857   if(pCallback == NULL)
1858   {
1859     return HAL_ERROR;
1860   }
1861 
1862   /* Process locked */
1863   __HAL_LOCK(hnand);
1864 
1865   if(hnand->State == HAL_NAND_STATE_READY)
1866   {
1867     switch (CallbackId)
1868     {
1869     case HAL_NAND_MSP_INIT_CB_ID :
1870       hnand->MspInitCallback = pCallback;
1871       break;
1872     case HAL_NAND_MSP_DEINIT_CB_ID :
1873       hnand->MspDeInitCallback = pCallback;
1874       break;
1875     case HAL_NAND_IT_CB_ID :
1876       hnand->ItCallback = pCallback;
1877       break;
1878     default :
1879       /* update return status */
1880       status =  HAL_ERROR;
1881       break;
1882     }
1883   }
1884   else if(hnand->State == HAL_NAND_STATE_RESET)
1885   {
1886     switch (CallbackId)
1887     {
1888     case HAL_NAND_MSP_INIT_CB_ID :
1889       hnand->MspInitCallback = pCallback;
1890       break;
1891     case HAL_NAND_MSP_DEINIT_CB_ID :
1892       hnand->MspDeInitCallback = pCallback;
1893       break;
1894     default :
1895       /* update return status */
1896       status =  HAL_ERROR;
1897       break;
1898     }
1899   }
1900   else
1901   {
1902     /* update return status */
1903     status =  HAL_ERROR;
1904   }
1905 
1906   /* Release Lock */
1907   __HAL_UNLOCK(hnand);
1908   return status;
1909 }
1910 
1911 /**
1912   * @brief  Unregister a User NAND Callback
1913   *         NAND Callback is redirected to the weak (surcharged) predefined callback
1914   * @param hnand : NAND handle
1915   * @param CallbackId : ID of the callback to be unregistered
1916   *        This parameter can be one of the following values:
1917   *          @arg @ref HAL_NAND_MSP_INIT_CB_ID       NAND MspInit callback ID
1918   *          @arg @ref HAL_NAND_MSP_DEINIT_CB_ID     NAND MspDeInit callback ID
1919   *          @arg @ref HAL_NAND_IT_CB_ID             NAND IT callback ID
1920   * @retval status
1921   */
HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId)1922 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1923 {
1924   HAL_StatusTypeDef status = HAL_OK;
1925 
1926   /* Process locked */
1927   __HAL_LOCK(hnand);
1928 
1929   if(hnand->State == HAL_NAND_STATE_READY)
1930   {
1931     switch (CallbackId)
1932     {
1933     case HAL_NAND_MSP_INIT_CB_ID :
1934       hnand->MspInitCallback = HAL_NAND_MspInit;
1935       break;
1936     case HAL_NAND_MSP_DEINIT_CB_ID :
1937       hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1938       break;
1939     case HAL_NAND_IT_CB_ID :
1940       hnand->ItCallback = HAL_NAND_ITCallback;
1941       break;
1942     default :
1943       /* update return status */
1944       status =  HAL_ERROR;
1945       break;
1946     }
1947   }
1948   else if(hnand->State == HAL_NAND_STATE_RESET)
1949   {
1950     switch (CallbackId)
1951     {
1952     case HAL_NAND_MSP_INIT_CB_ID :
1953       hnand->MspInitCallback = HAL_NAND_MspInit;
1954       break;
1955     case HAL_NAND_MSP_DEINIT_CB_ID :
1956       hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1957       break;
1958     default :
1959       /* update return status */
1960       status =  HAL_ERROR;
1961       break;
1962     }
1963   }
1964   else
1965   {
1966     /* update return status */
1967     status =  HAL_ERROR;
1968   }
1969 
1970   /* Release Lock */
1971   __HAL_UNLOCK(hnand);
1972   return status;
1973 }
1974 #endif
1975 
1976 /**
1977   * @}
1978   */
1979 
1980 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1981  *  @brief   management functions
1982  *
1983 @verbatim
1984   ==============================================================================
1985                          ##### NAND Control functions #####
1986   ==============================================================================
1987   [..]
1988     This subsection provides a set of functions allowing to control dynamically
1989     the NAND interface.
1990 
1991 @endverbatim
1992   * @{
1993   */
1994 
1995 
1996 /**
1997   * @brief  Enables dynamically NAND ECC feature.
1998   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
1999   *                the configuration information for NAND module.
2000   * @retval HAL status
2001   */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)2002 HAL_StatusTypeDef  HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2003 {
2004   /* Check the NAND controller state */
2005   if (hnand->State == HAL_NAND_STATE_BUSY)
2006   {
2007     return HAL_BUSY;
2008   }
2009   else if (hnand->State == HAL_NAND_STATE_READY)
2010   {
2011     /* Update the NAND state */
2012     hnand->State = HAL_NAND_STATE_BUSY;
2013 
2014     /* Enable ECC feature */
2015     (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2016 
2017     /* Update the NAND state */
2018     hnand->State = HAL_NAND_STATE_READY;
2019   }
2020   else
2021   {
2022     return HAL_ERROR;
2023   }
2024 
2025   return HAL_OK;
2026 }
2027 
2028 /**
2029   * @brief  Disables dynamically FMC_NAND ECC feature.
2030   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2031   *                the configuration information for NAND module.
2032   * @retval HAL status
2033   */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)2034 HAL_StatusTypeDef  HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2035 {
2036   /* Check the NAND controller state */
2037   if (hnand->State == HAL_NAND_STATE_BUSY)
2038   {
2039     return HAL_BUSY;
2040   }
2041   else if (hnand->State == HAL_NAND_STATE_READY)
2042   {
2043     /* Update the NAND state */
2044     hnand->State = HAL_NAND_STATE_BUSY;
2045 
2046     /* Disable ECC feature */
2047     (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2048 
2049     /* Update the NAND state */
2050     hnand->State = HAL_NAND_STATE_READY;
2051   }
2052   else
2053   {
2054     return HAL_ERROR;
2055   }
2056 
2057   return HAL_OK;
2058 }
2059 
2060 /**
2061   * @brief  Disables dynamically NAND ECC feature.
2062   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2063   *                the configuration information for NAND module.
2064   * @param  ECCval pointer to ECC value
2065   * @param  Timeout maximum timeout to wait
2066   * @retval HAL status
2067   */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)2068 HAL_StatusTypeDef  HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2069 {
2070   HAL_StatusTypeDef status;
2071 
2072   /* Check the NAND controller state */
2073   if (hnand->State == HAL_NAND_STATE_BUSY)
2074   {
2075     return HAL_BUSY;
2076   }
2077   else if (hnand->State == HAL_NAND_STATE_READY)
2078   {
2079     /* Update the NAND state */
2080     hnand->State = HAL_NAND_STATE_BUSY;
2081 
2082     /* Get NAND ECC value */
2083     status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2084 
2085     /* Update the NAND state */
2086     hnand->State = HAL_NAND_STATE_READY;
2087   }
2088   else
2089   {
2090     return HAL_ERROR;
2091   }
2092 
2093   return status;
2094 }
2095 
2096 /**
2097   * @}
2098   */
2099 
2100 
2101 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2102  *  @brief   Peripheral State functions
2103  *
2104 @verbatim
2105   ==============================================================================
2106                          ##### NAND State functions #####
2107   ==============================================================================
2108   [..]
2109     This subsection permits to get in run-time the status of the NAND controller
2110     and the data flow.
2111 
2112 @endverbatim
2113   * @{
2114   */
2115 
2116 /**
2117   * @brief  return the NAND state
2118   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2119   *                the configuration information for NAND module.
2120   * @retval HAL state
2121   */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)2122 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2123 {
2124   return hnand->State;
2125 }
2126 
2127 /**
2128   * @brief  NAND memory read status
2129   * @param  hnand pointer to a NAND_HandleTypeDef structure that contains
2130   *                the configuration information for NAND module.
2131   * @retval NAND status
2132   */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)2133 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2134 {
2135   uint32_t data;
2136   uint32_t DeviceAddress;
2137   UNUSED(hnand);
2138 
2139   /* Identify the device address */
2140     DeviceAddress = NAND_DEVICE;
2141 
2142   /* Send Read status operation command */
2143   *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
2144 
2145   /* Read status register data */
2146   data = *(__IO uint8_t *)DeviceAddress;
2147 
2148   /* Return the status */
2149   if ((data & NAND_ERROR) == NAND_ERROR)
2150   {
2151     return NAND_ERROR;
2152   }
2153   else if ((data & NAND_READY) == NAND_READY)
2154   {
2155     return NAND_READY;
2156   }
2157   else
2158   {
2159     return NAND_BUSY;
2160   }
2161 }
2162 
2163 /**
2164   * @}
2165   */
2166 
2167 /**
2168   * @}
2169   */
2170 
2171 /**
2172   * @}
2173   */
2174 
2175 #endif /* HAL_NAND_MODULE_ENABLED  */
2176 
2177 /**
2178   * @}
2179   */
2180 
2181 #endif /* FMC_BANK3 */
2182 
2183 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2184