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