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