Subversion Repositories LedShow

Rev

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