source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c

Last change on this file was 1, checked in by AlexLir, 3 years ago
File size: 68.9 KB
Line 
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>&copy; 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 */
176HAL_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 */
228HAL_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 */
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 */
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*/
292void 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 */
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 */
392HAL_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 */
466HAL_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 */
513HAL_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 */
535HAL_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 */
667HAL_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 /* Calculate PageSize */
765#ifdef FSMC_PCR2_PWID
766 if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
767#else /* FMC_PCR2_PWID is defined */
768 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
769#endif
770 {
771 size = size / 2U;
772 }
773 else
774 {
775 /* Do nothing */
776 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
777 }
778
779 /* Get Data into Buffer */
780 for(; index < size; index++)
781 {
782 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
783 }
784
785 /* Increment read pages number */
786 numPagesRead++;
787
788 /* Decrement pages to read */
789 NumPageToRead--;
790
791 /* Increment the NAND address */
792 nandaddress = (uint32_t)(nandaddress + 1U);
793 }
794
795 /* Update the NAND controller state */
796 hnand->State = HAL_NAND_STATE_READY;
797
798 /* Process unlocked */
799 __HAL_UNLOCK(hnand);
800
801 return HAL_OK;
802}
803
804/**
805 * @brief Write Page(s) to NAND memory block (8-bits addressing)
806 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
807 * the configuration information for NAND module.
808 * @param pAddress pointer to NAND address structure
809 * @param pBuffer pointer to source buffer to write
810 * @param NumPageToWrite number of pages to write to block
811 * @retval HAL status
812 */
813HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
814{
815 __IO uint32_t index = 0U;
816 uint32_t tickstart = 0U;
817 uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
818
819 /* Process Locked */
820 __HAL_LOCK(hnand);
821
822 /* Check the NAND controller state */
823 if(hnand->State == HAL_NAND_STATE_BUSY)
824 {
825 return HAL_BUSY;
826 }
827
828 /* Identify the device address */
829 if(hnand->Init.NandBank == FMC_NAND_BANK2)
830 {
831 deviceaddress = NAND_DEVICE1;
832 }
833 else
834 {
835 deviceaddress = NAND_DEVICE2;
836 }
837
838 /* Update the NAND controller state */
839 hnand->State = HAL_NAND_STATE_BUSY;
840
841 /* NAND raw address calculation */
842 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
843
844 /* Page(s) write loop */
845 while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
846 {
847 /* update the buffer size */
848 size = hnand->Config.PageSize + ((hnand->Config.PageSize) * numPagesWritten);
849
850 /* Send write page command sequence */
851 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
852 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
853
854 /* Cards with page size <= 512 bytes */
855 if((hnand->Config.PageSize) <= 512U)
856 {
857 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
858 {
859 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
860 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
861 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
862 }
863 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
864 {
865 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
866 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
867 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
868 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
869 }
870 }
871 else /* (hnand->Config.PageSize) > 512 */
872 {
873 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
874 {
875 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
876 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
877 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
878 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
879 }
880 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
881 {
882 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
883 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
884 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
885 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
886 __DSB();
887 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
888 __DSB();
889 }
890 }
891
892
893 /* Write data to memory */
894 for(; index < size; index++)
895 {
896 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
897 }
898
899 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
900
901 /* Get tick */
902 tickstart = HAL_GetTick();
903
904 /* Read status until NAND is ready */
905 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
906 {
907
908 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
909 {
910 return HAL_TIMEOUT;
911 }
912 }
913
914 /* Increment written pages number */
915 numPagesWritten++;
916
917 /* Decrement pages to write */
918 NumPageToWrite--;
919
920 /* Increment the NAND address */
921 nandaddress = (uint32_t)(nandaddress + 1U);
922 }
923
924 /* Update the NAND controller state */
925 hnand->State = HAL_NAND_STATE_READY;
926
927 /* Process unlocked */
928 __HAL_UNLOCK(hnand);
929
930 return HAL_OK;
931}
932
933/**
934 * @brief Write Page(s) to NAND memory block (16-bits addressing)
935 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
936 * the configuration information for NAND module.
937 * @param pAddress pointer to NAND address structure
938 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
939 * @param NumPageToWrite number of pages to write to block
940 * @retval HAL status
941 */
942HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
943{
944 __IO uint32_t index = 0U;
945 uint32_t tickstart = 0U;
946 uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
947
948 /* Process Locked */
949 __HAL_LOCK(hnand);
950
951 /* Check the NAND controller state */
952 if(hnand->State == HAL_NAND_STATE_BUSY)
953 {
954 return HAL_BUSY;
955 }
956
957 /* Identify the device address */
958 if(hnand->Init.NandBank == FMC_NAND_BANK2)
959 {
960 deviceaddress = NAND_DEVICE1;
961 }
962 else
963 {
964 deviceaddress = NAND_DEVICE2;
965 }
966
967 /* Update the NAND controller state */
968 hnand->State = HAL_NAND_STATE_BUSY;
969
970 /* NAND raw address calculation */
971 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
972
973 /* Page(s) write loop */
974 while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
975 {
976 /* update the buffer size */
977 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
978
979 /* Send write page command sequence */
980 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
981 __DSB();
982 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
983 __DSB();
984
985 /* Cards with page size <= 512 bytes */
986 if((hnand->Config.PageSize) <= 512U)
987 {
988 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
989 {
990 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
991 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
992 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
993 }
994 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
995 {
996 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
997 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
998 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
999 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1000 }
1001 }
1002 else /* (hnand->Config.PageSize) > 512 */
1003 {
1004 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1005 {
1006 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1007 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1008 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1009 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1010 }
1011 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1012 {
1013 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1014 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1015 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1016 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1017 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1018 }
1019 }
1020
1021 /* Calculate PageSize */
1022#ifdef FSMC_PCR2_PWID
1023 if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
1024#else /* FMC_PCR2_PWID is defined */
1025 if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
1026#endif
1027 {
1028 size = size / 2U;
1029 }
1030 else
1031 {
1032 /* Do nothing */
1033 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
1034 }
1035
1036 /* Write data to memory */
1037 for(; index < size; index++)
1038 {
1039 *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
1040 }
1041
1042 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1043
1044 /* Get tick */
1045 tickstart = HAL_GetTick();
1046
1047 /* Read status until NAND is ready */
1048 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1049 {
1050 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1051 {
1052 return HAL_TIMEOUT;
1053 }
1054 }
1055
1056 /* Increment written pages number */
1057 numPagesWritten++;
1058
1059 /* Decrement pages to write */
1060 NumPageToWrite--;
1061
1062 /* Increment the NAND address */
1063 nandaddress = (uint32_t)(nandaddress + 1U);
1064 }
1065
1066 /* Update the NAND controller state */
1067 hnand->State = HAL_NAND_STATE_READY;
1068
1069 /* Process unlocked */
1070 __HAL_UNLOCK(hnand);
1071
1072 return HAL_OK;
1073}
1074
1075/**
1076 * @brief Read Spare area(s) from NAND memory
1077 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1078 * the configuration information for NAND module.
1079 * @param pAddress pointer to NAND address structure
1080 * @param pBuffer pointer to source buffer to write
1081 * @param NumSpareAreaToRead Number of spare area to read
1082 * @retval HAL status
1083*/
1084HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1085{
1086 __IO uint32_t index = 0U;
1087 uint32_t tickstart = 0U;
1088 uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
1089
1090 /* Process Locked */
1091 __HAL_LOCK(hnand);
1092
1093 /* Check the NAND controller state */
1094 if(hnand->State == HAL_NAND_STATE_BUSY)
1095 {
1096 return HAL_BUSY;
1097 }
1098
1099 /* Identify the device address */
1100 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1101 {
1102 deviceaddress = NAND_DEVICE1;
1103 }
1104 else
1105 {
1106 deviceaddress = NAND_DEVICE2;
1107 }
1108
1109 /* Update the NAND controller state */
1110 hnand->State = HAL_NAND_STATE_BUSY;
1111
1112 /* NAND raw address calculation */
1113 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1114
1115 /* Column in page address */
1116 columnaddress = COLUMN_ADDRESS(hnand);
1117
1118 /* Spare area(s) read loop */
1119 while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1120 {
1121 /* update the buffer size */
1122 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1123
1124 /* Cards with page size <= 512 bytes */
1125 if((hnand->Config.PageSize) <= 512U)
1126 {
1127 /* Send read spare area command sequence */
1128 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1129
1130 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1131 {
1132 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1133 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1134 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1135 }
1136 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1137 {
1138 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1139 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1140 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1141 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1142 }
1143 }
1144 else /* (hnand->Config.PageSize) > 512 */
1145 {
1146 /* Send read spare area command sequence */
1147 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1148
1149 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1150 {
1151 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1152 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1153 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1154 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1155 }
1156 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1157 {
1158 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1159 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1160 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1161 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1162 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1163 }
1164 }
1165
1166 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1167
1168 if(hnand->Config.ExtraCommandEnable == ENABLE)
1169 {
1170 /* Get tick */
1171 tickstart = HAL_GetTick();
1172
1173 /* Read status until NAND is ready */
1174 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1175 {
1176 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1177 {
1178 return HAL_TIMEOUT;
1179 }
1180 }
1181
1182 /* Go back to read mode */
1183 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1184 }
1185
1186 /* Get Data into Buffer */
1187 for(; index < size; index++)
1188 {
1189 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
1190 }
1191
1192 /* Increment read spare areas number */
1193 numSpareAreaRead++;
1194
1195 /* Decrement spare areas to read */
1196 NumSpareAreaToRead--;
1197
1198 /* Increment the NAND address */
1199 nandaddress = (uint32_t)(nandaddress + 1U);
1200 }
1201
1202 /* Update the NAND controller state */
1203 hnand->State = HAL_NAND_STATE_READY;
1204
1205 /* Process unlocked */
1206 __HAL_UNLOCK(hnand);
1207
1208 return HAL_OK;
1209}
1210
1211/**
1212 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1213 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1214 * the configuration information for NAND module.
1215 * @param pAddress pointer to NAND address structure
1216 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1217 * @param NumSpareAreaToRead Number of spare area to read
1218 * @retval HAL status
1219*/
1220HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1221{
1222 __IO uint32_t index = 0U;
1223 uint32_t tickstart = 0U;
1224 uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
1225
1226 /* Process Locked */
1227 __HAL_LOCK(hnand);
1228
1229 /* Check the NAND controller state */
1230 if(hnand->State == HAL_NAND_STATE_BUSY)
1231 {
1232 return HAL_BUSY;
1233 }
1234
1235 /* Identify the device address */
1236 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1237 {
1238 deviceaddress = NAND_DEVICE1;
1239 }
1240 else
1241 {
1242 deviceaddress = NAND_DEVICE2;
1243 }
1244
1245 /* Update the NAND controller state */
1246 hnand->State = HAL_NAND_STATE_BUSY;
1247
1248 /* NAND raw address calculation */
1249 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1250
1251 /* Column in page address */
1252 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1253
1254 /* Spare area(s) read loop */
1255 while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1256 {
1257 /* update the buffer size */
1258 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1259
1260 /* Cards with page size <= 512 bytes */
1261 if((hnand->Config.PageSize) <= 512U)
1262 {
1263 /* Send read spare area command sequence */
1264 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1265
1266 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1267 {
1268 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1269 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1270 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1271 }
1272 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1273 {
1274 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1275 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1276 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1277 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1278 }
1279 }
1280 else /* (hnand->Config.PageSize) > 512 */
1281 {
1282 /* Send read spare area command sequence */
1283 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1284
1285 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1286 {
1287 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1288 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1289 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1290 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
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 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1296 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1297 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1298 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1299 }
1300 }
1301
1302 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1303
1304 if(hnand->Config.ExtraCommandEnable == ENABLE)
1305 {
1306 /* Get tick */
1307 tickstart = HAL_GetTick();
1308
1309 /* Read status until NAND is ready */
1310 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1311 {
1312 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1313 {
1314 return HAL_TIMEOUT;
1315 }
1316 }
1317
1318 /* Go back to read mode */
1319 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1320 }
1321
1322 /* Get Data into Buffer */
1323 for(; index < size; index++)
1324 {
1325 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
1326 }
1327
1328 /* Increment read spare areas number */
1329 numSpareAreaRead++;
1330
1331 /* Decrement spare areas to read */
1332 NumSpareAreaToRead--;
1333
1334 /* Increment the NAND address */
1335 nandaddress = (uint32_t)(nandaddress + 1U);
1336 }
1337
1338 /* Update the NAND controller state */
1339 hnand->State = HAL_NAND_STATE_READY;
1340
1341 /* Process unlocked */
1342 __HAL_UNLOCK(hnand);
1343
1344 return HAL_OK;
1345}
1346
1347/**
1348 * @brief Write Spare area(s) to NAND memory
1349 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1350 * the configuration information for NAND module.
1351 * @param pAddress pointer to NAND address structure
1352 * @param pBuffer pointer to source buffer to write
1353 * @param NumSpareAreaTowrite number of spare areas to write to block
1354 * @retval HAL status
1355 */
1356HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1357{
1358 __IO uint32_t index = 0U;
1359 uint32_t tickstart = 0U;
1360 uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
1361
1362 /* Process Locked */
1363 __HAL_LOCK(hnand);
1364
1365 /* Check the NAND controller state */
1366 if(hnand->State == HAL_NAND_STATE_BUSY)
1367 {
1368 return HAL_BUSY;
1369 }
1370
1371 /* Identify the device address */
1372 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1373 {
1374 deviceaddress = NAND_DEVICE1;
1375 }
1376 else
1377 {
1378 deviceaddress = NAND_DEVICE2;
1379 }
1380
1381 /* Update the FMC_NAND controller state */
1382 hnand->State = HAL_NAND_STATE_BUSY;
1383
1384 /* Page address calculation */
1385 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1386
1387 /* Column in page address */
1388 columnaddress = COLUMN_ADDRESS(hnand);
1389
1390 /* Spare area(s) write loop */
1391 while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1392 {
1393 /* update the buffer size */
1394 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1395
1396 /* Cards with page size <= 512 bytes */
1397 if((hnand->Config.PageSize) <= 512U)
1398 {
1399 /* Send write Spare area command sequence */
1400 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1401 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1402
1403 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1404 {
1405 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1406 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1407 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1408 }
1409 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1410 {
1411 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1412 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1413 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1414 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1415 }
1416 }
1417 else /* (hnand->Config.PageSize) > 512 */
1418 {
1419 /* Send write Spare area command sequence */
1420 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1421 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1422
1423 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1424 {
1425 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1426 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1427 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1428 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1429 }
1430 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1431 {
1432 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1433 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1434 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1435 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1436 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1437 }
1438 }
1439
1440 /* Write data to memory */
1441 for(; index < size; index++)
1442 {
1443 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
1444 }
1445
1446 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1447
1448 /* Get tick */
1449 tickstart = HAL_GetTick();
1450
1451 /* Read status until NAND is ready */
1452 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1453 {
1454 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1455 {
1456 return HAL_TIMEOUT;
1457 }
1458 }
1459
1460 /* Increment written spare areas number */
1461 numSpareAreaWritten++;
1462
1463 /* Decrement spare areas to write */
1464 NumSpareAreaTowrite--;
1465
1466 /* Increment the NAND address */
1467 nandaddress = (uint32_t)(nandaddress + 1U);
1468 }
1469
1470 /* Update the NAND controller state */
1471 hnand->State = HAL_NAND_STATE_READY;
1472
1473 /* Process unlocked */
1474 __HAL_UNLOCK(hnand);
1475
1476 return HAL_OK;
1477}
1478
1479/**
1480 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1481 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1482 * the configuration information for NAND module.
1483 * @param pAddress pointer to NAND address structure
1484 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1485 * @param NumSpareAreaTowrite number of spare areas to write to block
1486 * @retval HAL status
1487 */
1488HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1489{
1490 __IO uint32_t index = 0U;
1491 uint32_t tickstart = 0U;
1492 uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
1493
1494 /* Process Locked */
1495 __HAL_LOCK(hnand);
1496
1497 /* Check the NAND controller state */
1498 if(hnand->State == HAL_NAND_STATE_BUSY)
1499 {
1500 return HAL_BUSY;
1501 }
1502
1503 /* Identify the device address */
1504 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1505 {
1506 deviceaddress = NAND_DEVICE1;
1507 }
1508 else
1509 {
1510 deviceaddress = NAND_DEVICE2;
1511 }
1512
1513 /* Update the FMC_NAND controller state */
1514 hnand->State = HAL_NAND_STATE_BUSY;
1515
1516 /* NAND raw address calculation */
1517 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1518
1519 /* Column in page address */
1520 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1521
1522 /* Spare area(s) write loop */
1523 while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1524 {
1525 /* update the buffer size */
1526 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1527
1528 /* Cards with page size <= 512 bytes */
1529 if((hnand->Config.PageSize) <= 512U)
1530 {
1531 /* Send write Spare area command sequence */
1532 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1533 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1534
1535 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1536 {
1537 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1538 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1539 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1540 }
1541 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1542 {
1543 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
1544 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1545 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1546 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1547 }
1548 }
1549 else /* (hnand->Config.PageSize) > 512 */
1550 {
1551 /* Send write Spare area command sequence */
1552 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1553 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1554
1555 if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
1556 {
1557 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1558 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1559 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1560 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1561 }
1562 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1563 {
1564 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1565 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1566 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1567 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1568 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1569 }
1570 }
1571
1572 /* Write data to memory */
1573 for(; index < size; index++)
1574 {
1575 *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
1576 }
1577
1578 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1579
1580 /* Get tick */
1581 tickstart = HAL_GetTick();
1582
1583 /* Read status until NAND is ready */
1584 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1585 {
1586 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1587 {
1588 return HAL_TIMEOUT;
1589 }
1590 }
1591
1592 /* Increment written spare areas number */
1593 numSpareAreaWritten++;
1594
1595 /* Decrement spare areas to write */
1596 NumSpareAreaTowrite--;
1597
1598 /* Increment the NAND address */
1599 nandaddress = (uint32_t)(nandaddress + 1U);
1600 }
1601
1602 /* Update the NAND controller state */
1603 hnand->State = HAL_NAND_STATE_READY;
1604
1605 /* Process unlocked */
1606 __HAL_UNLOCK(hnand);
1607
1608 return HAL_OK;
1609}
1610
1611/**
1612 * @brief NAND memory Block erase
1613 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1614 * the configuration information for NAND module.
1615 * @param pAddress pointer to NAND address structure
1616 * @retval HAL status
1617 */
1618HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1619{
1620 uint32_t deviceaddress = 0U;
1621 uint32_t tickstart = 0U;
1622
1623 /* Process Locked */
1624 __HAL_LOCK(hnand);
1625
1626 /* Check the NAND controller state */
1627 if(hnand->State == HAL_NAND_STATE_BUSY)
1628 {
1629 return HAL_BUSY;
1630 }
1631
1632 /* Identify the device address */
1633 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1634 {
1635 deviceaddress = NAND_DEVICE1;
1636 }
1637 else
1638 {
1639 deviceaddress = NAND_DEVICE2;
1640 }
1641
1642 /* Update the NAND controller state */
1643 hnand->State = HAL_NAND_STATE_BUSY;
1644
1645 /* Send Erase block command sequence */
1646 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
1647
1648 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1649 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1650 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1651
1652 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
1653
1654 /* Update the NAND controller state */
1655 hnand->State = HAL_NAND_STATE_READY;
1656
1657 /* Get tick */
1658 tickstart = HAL_GetTick();
1659
1660 /* Read status until NAND is ready */
1661 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1662 {
1663 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1664 {
1665 /* Process unlocked */
1666 __HAL_UNLOCK(hnand);
1667
1668 return HAL_TIMEOUT;
1669 }
1670 }
1671
1672 /* Process unlocked */
1673 __HAL_UNLOCK(hnand);
1674
1675 return HAL_OK;
1676}
1677
1678/**
1679 * @brief NAND memory read status
1680 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1681 * the configuration information for NAND module.
1682 * @retval NAND status
1683 */
1684uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
1685{
1686 uint32_t data = 0U;
1687 uint32_t deviceaddress = 0U;
1688
1689 /* Identify the device address */
1690 if(hnand->Init.NandBank == FMC_NAND_BANK2)
1691 {
1692 deviceaddress = NAND_DEVICE1;
1693 }
1694 else
1695 {
1696 deviceaddress = NAND_DEVICE2;
1697 }
1698
1699 /* Send Read status operation command */
1700 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
1701
1702 /* Read status register data */
1703 data = *(__IO uint8_t *)deviceaddress;
1704
1705 /* Return the status */
1706 if((data & NAND_ERROR) == NAND_ERROR)
1707 {
1708 return NAND_ERROR;
1709 }
1710 else if((data & NAND_READY) == NAND_READY)
1711 {
1712 return NAND_READY;
1713 }
1714
1715 return NAND_BUSY;
1716}
1717
1718/**
1719 * @brief Increment the NAND memory address
1720 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1721 * the configuration information for NAND module.
1722 * @param pAddress pointer to NAND address structure
1723 * @retval The new status of the increment address operation. It can be:
1724 * - NAND_VALID_ADDRESS: When the new address is valid address
1725 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1726 */
1727uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1728{
1729 uint32_t status = NAND_VALID_ADDRESS;
1730
1731 /* Increment page address */
1732 pAddress->Page++;
1733
1734 /* Check NAND address is valid */
1735 if(pAddress->Page == hnand->Config.BlockSize)
1736 {
1737 pAddress->Page = 0U;
1738 pAddress->Block++;
1739
1740 if(pAddress->Block == hnand->Config.PlaneSize)
1741 {
1742 pAddress->Block = 0U;
1743 pAddress->Plane++;
1744
1745 if(pAddress->Plane == (hnand->Config.PlaneNbr))
1746 {
1747 status = NAND_INVALID_ADDRESS;
1748 }
1749 }
1750 }
1751
1752 return (status);
1753}
1754
1755#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1756/**
1757 * @brief Register a User NAND Callback
1758 * To be used instead of the weak (surcharged) predefined callback
1759 * @param hnand : NAND handle
1760 * @param CallbackId : ID of the callback to be registered
1761 * This parameter can be one of the following values:
1762 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1763 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1764 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1765 * @param pCallback : pointer to the Callback function
1766 * @retval status
1767 */
1768HAL_StatusTypeDef HAL_NAND_RegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, pNAND_CallbackTypeDef pCallback)
1769{
1770 HAL_StatusTypeDef status = HAL_OK;
1771
1772 if(pCallback == NULL)
1773 {
1774 return HAL_ERROR;
1775 }
1776
1777 /* Process locked */
1778 __HAL_LOCK(hnand);
1779
1780 if(hnand->State == HAL_NAND_STATE_READY)
1781 {
1782 switch (CallbackId)
1783 {
1784 case HAL_NAND_MSP_INIT_CB_ID :
1785 hnand->MspInitCallback = pCallback;
1786 break;
1787 case HAL_NAND_MSP_DEINIT_CB_ID :
1788 hnand->MspDeInitCallback = pCallback;
1789 break;
1790 case HAL_NAND_IT_CB_ID :
1791 hnand->ItCallback = pCallback;
1792 break;
1793 default :
1794 /* update return status */
1795 status = HAL_ERROR;
1796 break;
1797 }
1798 }
1799 else if(hnand->State == HAL_NAND_STATE_RESET)
1800 {
1801 switch (CallbackId)
1802 {
1803 case HAL_NAND_MSP_INIT_CB_ID :
1804 hnand->MspInitCallback = pCallback;
1805 break;
1806 case HAL_NAND_MSP_DEINIT_CB_ID :
1807 hnand->MspDeInitCallback = pCallback;
1808 break;
1809 default :
1810 /* update return status */
1811 status = HAL_ERROR;
1812 break;
1813 }
1814 }
1815 else
1816 {
1817 /* update return status */
1818 status = HAL_ERROR;
1819 }
1820
1821 /* Release Lock */
1822 __HAL_UNLOCK(hnand);
1823 return status;
1824}
1825
1826/**
1827 * @brief Unregister a User NAND Callback
1828 * NAND Callback is redirected to the weak (surcharged) predefined callback
1829 * @param hnand : NAND handle
1830 * @param CallbackId : ID of the callback to be unregistered
1831 * This parameter can be one of the following values:
1832 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1833 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1834 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1835 * @retval status
1836 */
1837HAL_StatusTypeDef HAL_NAND_UnRegisterCallback (NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1838{
1839 HAL_StatusTypeDef status = HAL_OK;
1840
1841 /* Process locked */
1842 __HAL_LOCK(hnand);
1843
1844 if(hnand->State == HAL_NAND_STATE_READY)
1845 {
1846 switch (CallbackId)
1847 {
1848 case HAL_NAND_MSP_INIT_CB_ID :
1849 hnand->MspInitCallback = HAL_NAND_MspInit;
1850 break;
1851 case HAL_NAND_MSP_DEINIT_CB_ID :
1852 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1853 break;
1854 case HAL_NAND_IT_CB_ID :
1855 hnand->ItCallback = HAL_NAND_ITCallback;
1856 break;
1857 default :
1858 /* update return status */
1859 status = HAL_ERROR;
1860 break;
1861 }
1862 }
1863 else if(hnand->State == HAL_NAND_STATE_RESET)
1864 {
1865 switch (CallbackId)
1866 {
1867 case HAL_NAND_MSP_INIT_CB_ID :
1868 hnand->MspInitCallback = HAL_NAND_MspInit;
1869 break;
1870 case HAL_NAND_MSP_DEINIT_CB_ID :
1871 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1872 break;
1873 default :
1874 /* update return status */
1875 status = HAL_ERROR;
1876 break;
1877 }
1878 }
1879 else
1880 {
1881 /* update return status */
1882 status = HAL_ERROR;
1883 }
1884
1885 /* Release Lock */
1886 __HAL_UNLOCK(hnand);
1887 return status;
1888}
1889#endif
1890
1891/**
1892 * @}
1893 */
1894
1895/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1896 * @brief management functions
1897 *
1898@verbatim
1899 ==============================================================================
1900 ##### NAND Control functions #####
1901 ==============================================================================
1902 [..]
1903 This subsection provides a set of functions allowing to control dynamically
1904 the NAND interface.
1905
1906@endverbatim
1907 * @{
1908 */
1909
1910
1911/**
1912 * @brief Enables dynamically NAND ECC feature.
1913 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1914 * the configuration information for NAND module.
1915 * @retval HAL status
1916 */
1917HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
1918{
1919 /* Check the NAND controller state */
1920 if(hnand->State == HAL_NAND_STATE_BUSY)
1921 {
1922 return HAL_BUSY;
1923 }
1924
1925 /* Update the NAND state */
1926 hnand->State = HAL_NAND_STATE_BUSY;
1927
1928 /* Enable ECC feature */
1929 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1930
1931 /* Update the NAND state */
1932 hnand->State = HAL_NAND_STATE_READY;
1933
1934 return HAL_OK;
1935}
1936
1937/**
1938 * @brief Disables dynamically FMC_NAND ECC feature.
1939 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1940 * the configuration information for NAND module.
1941 * @retval HAL status
1942 */
1943HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
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 /* Disable ECC feature */
1955 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1956
1957 /* Update the NAND state */
1958 hnand->State = HAL_NAND_STATE_READY;
1959
1960 return HAL_OK;
1961}
1962
1963/**
1964 * @brief Disables dynamically NAND ECC feature.
1965 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1966 * the configuration information for NAND module.
1967 * @param ECCval pointer to ECC value
1968 * @param Timeout maximum timeout to wait
1969 * @retval HAL status
1970 */
1971HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1972{
1973 HAL_StatusTypeDef status = HAL_OK;
1974
1975 /* Check the NAND controller state */
1976 if(hnand->State == HAL_NAND_STATE_BUSY)
1977 {
1978 return HAL_BUSY;
1979 }
1980
1981 /* Update the NAND state */
1982 hnand->State = HAL_NAND_STATE_BUSY;
1983
1984 /* Get NAND ECC value */
1985 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1986
1987 /* Update the NAND state */
1988 hnand->State = HAL_NAND_STATE_READY;
1989
1990 return status;
1991}
1992
1993/**
1994 * @}
1995 */
1996
1997
1998/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1999 * @brief Peripheral State functions
2000 *
2001@verbatim
2002 ==============================================================================
2003 ##### NAND State functions #####
2004 ==============================================================================
2005 [..]
2006 This subsection permits to get in run-time the status of the NAND controller
2007 and the data flow.
2008
2009@endverbatim
2010 * @{
2011 */
2012
2013/**
2014 * @brief return the NAND state
2015 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2016 * the configuration information for NAND module.
2017 * @retval HAL state
2018 */
2019HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2020{
2021 return hnand->State;
2022}
2023
2024/**
2025 * @}
2026 */
2027
2028/**
2029 * @}
2030 */
2031
2032/**
2033 * @}
2034 */
2035
2036#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
2037 STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\
2038 STM32F446xx || STM32F469xx || STM32F479xx */
2039#endif /* HAL_NAND_MODULE_ENABLED */
2040
2041/**
2042 * @}
2043 */
2044
2045/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.