Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

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