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