comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c @ 128:c78bcbd5deda FlipDisplay

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