Subversion Repositories canSerial

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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