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