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