Subversion Repositories LedShow

Rev

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