1 /**
2 ******************************************************************************
3 * @file stm32l5xx_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) 2019 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 "stm32l5xx_hal.h"
111
112
113 /** @addtogroup STM32L5xx_HAL_Driver
114 * @{
115 */
116
117 #ifdef HAL_NAND_MODULE_ENABLED
118
119 /** @defgroup NAND NAND
120 * @brief NAND HAL module driver
121 * @{
122 */
123
124 /* Private typedef -----------------------------------------------------------*/
125 /* Private Constants ------------------------------------------------------------*/
126 /* Private macro -------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /* Private function prototypes -----------------------------------------------*/
129 /* Exported functions ---------------------------------------------------------*/
130
131 /** @defgroup NAND_Exported_Functions NAND Exported Functions
132 * @{
133 */
134
135 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
136 * @brief Initialization and Configuration functions
137 *
138 @verbatim
139 ==============================================================================
140 ##### NAND Initialization and de-initialization functions #####
141 ==============================================================================
142 [..]
143 This section provides functions allowing to initialize/de-initialize
144 the NAND memory
145
146 @endverbatim
147 * @{
148 */
149
150 /**
151 * @brief Perform NAND memory Initialization sequence
152 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
153 * the configuration information for NAND module.
154 * @param ComSpace_Timing pointer to Common space timing structure
155 * @param AttSpace_Timing pointer to Attribute space timing structure
156 * @retval HAL status
157 */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)158 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing,
159 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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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 /* (USE_HAL_NAND_REGISTER_CALLBACKS) */
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,
518 uint32_t NumPageToRead)
519 {
520 uint32_t index;
521 uint32_t tickstart;
522 uint32_t deviceaddress;
523 uint32_t numpagesread = 0U;
524 uint32_t nandaddress;
525 uint32_t nbpages = NumPageToRead;
526 uint8_t *buff = pBuffer;
527
528 /* Check the NAND controller state */
529 if (hnand->State == HAL_NAND_STATE_BUSY)
530 {
531 return HAL_BUSY;
532 }
533 else if (hnand->State == HAL_NAND_STATE_READY)
534 {
535 /* Process Locked */
536 __HAL_LOCK(hnand);
537
538 /* Update the NAND controller state */
539 hnand->State = HAL_NAND_STATE_BUSY;
540
541 /* Identify the device address */
542 deviceaddress = NAND_DEVICE;
543
544 /* NAND raw address calculation */
545 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
546
547 /* Page(s) read loop */
548 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
549 {
550 /* Send read page command sequence */
551 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
552 __DSB();
553
554 /* Cards with page size <= 512 bytes */
555 if ((hnand->Config.PageSize) <= 512U)
556 {
557 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
558 {
559 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
560 __DSB();
561 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
562 __DSB();
563 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
564 __DSB();
565 }
566 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
567 {
568 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
569 __DSB();
570 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
571 __DSB();
572 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
573 __DSB();
574 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
575 __DSB();
576 }
577 }
578 else /* (hnand->Config.PageSize) > 512 */
579 {
580 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
581 {
582 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
583 __DSB();
584 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
585 __DSB();
586 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
587 __DSB();
588 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
589 __DSB();
590 }
591 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
592 {
593 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
594 __DSB();
595 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
596 __DSB();
597 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
598 __DSB();
599 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
600 __DSB();
601 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
602 __DSB();
603 }
604 }
605
606 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
607 __DSB();
608
609
610 if (hnand->Config.ExtraCommandEnable == ENABLE)
611 {
612 /* Get tick */
613 tickstart = HAL_GetTick();
614
615 /* Read status until NAND is ready */
616 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
617 {
618 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
619 {
620 /* Update the NAND controller state */
621 hnand->State = HAL_NAND_STATE_ERROR;
622
623 /* Process unlocked */
624 __HAL_UNLOCK(hnand);
625
626 return HAL_TIMEOUT;
627 }
628 }
629
630 /* Go back to read mode */
631 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
632 __DSB();
633 }
634
635 /* Get Data into Buffer */
636 for (index = 0U; index < hnand->Config.PageSize; index++)
637 {
638 *buff = *(uint8_t *)deviceaddress;
639 buff++;
640 }
641
642 /* Increment read pages number */
643 numpagesread++;
644
645 /* Decrement pages to read */
646 nbpages--;
647
648 /* Increment the NAND address */
649 nandaddress = (uint32_t)(nandaddress + 1U);
650 }
651
652 /* Update the NAND controller state */
653 hnand->State = HAL_NAND_STATE_READY;
654
655 /* Process unlocked */
656 __HAL_UNLOCK(hnand);
657 }
658 else
659 {
660 return HAL_ERROR;
661 }
662
663 return HAL_OK;
664 }
665
666 /**
667 * @brief Read Page(s) from NAND memory block (16-bits addressing)
668 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
669 * the configuration information for NAND module.
670 * @param pAddress pointer to NAND address structure
671 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned
672 * @param NumPageToRead number of pages to read from block
673 * @retval HAL status
674 */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)675 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
676 uint32_t NumPageToRead)
677 {
678 uint32_t index;
679 uint32_t tickstart;
680 uint32_t deviceaddress;
681 uint32_t numpagesread = 0U;
682 uint32_t nandaddress;
683 uint32_t nbpages = NumPageToRead;
684 uint16_t *buff = pBuffer;
685
686 /* Check the NAND controller state */
687 if (hnand->State == HAL_NAND_STATE_BUSY)
688 {
689 return HAL_BUSY;
690 }
691 else if (hnand->State == HAL_NAND_STATE_READY)
692 {
693 /* Process Locked */
694 __HAL_LOCK(hnand);
695
696 /* Update the NAND controller state */
697 hnand->State = HAL_NAND_STATE_BUSY;
698
699 /* Identify the device address */
700 deviceaddress = NAND_DEVICE;
701
702 /* NAND raw address calculation */
703 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
704
705 /* Page(s) read loop */
706 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
707 {
708 /* Send read page command sequence */
709 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
710 __DSB();
711
712 /* Cards with page size <= 512 bytes */
713 if ((hnand->Config.PageSize) <= 512U)
714 {
715 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
716 {
717 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
718 __DSB();
719 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
720 __DSB();
721 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
722 __DSB();
723 }
724 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
725 {
726 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
727 __DSB();
728 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
729 __DSB();
730 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
731 __DSB();
732 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
733 __DSB();
734 }
735 }
736 else /* (hnand->Config.PageSize) > 512 */
737 {
738 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
739 {
740 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
741 __DSB();
742 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
743 __DSB();
744 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
745 __DSB();
746 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
747 __DSB();
748 }
749 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
750 {
751 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
752 __DSB();
753 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
754 __DSB();
755 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
756 __DSB();
757 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
758 __DSB();
759 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
760 __DSB();
761 }
762 }
763
764 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
765 __DSB();
766
767 if (hnand->Config.ExtraCommandEnable == ENABLE)
768 {
769 /* Get tick */
770 tickstart = HAL_GetTick();
771
772 /* Read status until NAND is ready */
773 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
774 {
775 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
776 {
777 /* Update the NAND controller state */
778 hnand->State = HAL_NAND_STATE_ERROR;
779
780 /* Process unlocked */
781 __HAL_UNLOCK(hnand);
782
783 return HAL_TIMEOUT;
784 }
785 }
786
787 /* Go back to read mode */
788 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
789 __DSB();
790 }
791
792 /* Calculate PageSize */
793 if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
794 {
795 hnand->Config.PageSize = hnand->Config.PageSize / 2U;
796 }
797 else
798 {
799 /* Do nothing */
800 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
801 }
802
803 /* Get Data into Buffer */
804 for (index = 0U; index < hnand->Config.PageSize; index++)
805 {
806 *buff = *(uint16_t *)deviceaddress;
807 buff++;
808 }
809
810 /* Increment read pages number */
811 numpagesread++;
812
813 /* Decrement pages to read */
814 nbpages--;
815
816 /* Increment the NAND address */
817 nandaddress = (uint32_t)(nandaddress + 1U);
818 }
819
820 /* Update the NAND controller state */
821 hnand->State = HAL_NAND_STATE_READY;
822
823 /* Process unlocked */
824 __HAL_UNLOCK(hnand);
825 }
826 else
827 {
828 return HAL_ERROR;
829 }
830
831 return HAL_OK;
832 }
833
834 /**
835 * @brief Write Page(s) to NAND memory block (8-bits addressing)
836 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
837 * the configuration information for NAND module.
838 * @param pAddress pointer to NAND address structure
839 * @param pBuffer pointer to source buffer to write
840 * @param NumPageToWrite number of pages to write to block
841 * @retval HAL status
842 */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)843 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
844 uint32_t NumPageToWrite)
845 {
846 uint32_t index;
847 uint32_t tickstart;
848 uint32_t deviceaddress;
849 uint32_t numpageswritten = 0U;
850 uint32_t nandaddress;
851 uint32_t nbpages = NumPageToWrite;
852 uint8_t *buff = pBuffer;
853
854 /* Check the NAND controller state */
855 if (hnand->State == HAL_NAND_STATE_BUSY)
856 {
857 return HAL_BUSY;
858 }
859 else if (hnand->State == HAL_NAND_STATE_READY)
860 {
861 /* Process Locked */
862 __HAL_LOCK(hnand);
863
864 /* Update the NAND controller state */
865 hnand->State = HAL_NAND_STATE_BUSY;
866
867 /* Identify the device address */
868 deviceaddress = NAND_DEVICE;
869
870 /* NAND raw address calculation */
871 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
872
873 /* Page(s) write loop */
874 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
875 {
876 /* Send write page command sequence */
877 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
878 __DSB();
879 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
880 __DSB();
881
882 /* Cards with page size <= 512 bytes */
883 if ((hnand->Config.PageSize) <= 512U)
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)) = ADDR_1ST_CYCLE(nandaddress);
890 __DSB();
891 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
892 __DSB();
893 }
894 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
895 {
896 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
897 __DSB();
898 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
899 __DSB();
900 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
901 __DSB();
902 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
903 __DSB();
904 }
905 }
906 else /* (hnand->Config.PageSize) > 512 */
907 {
908 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
909 {
910 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
911 __DSB();
912 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
913 __DSB();
914 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
915 __DSB();
916 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
917 __DSB();
918 }
919 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
920 {
921 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
922 __DSB();
923 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
924 __DSB();
925 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
926 __DSB();
927 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
928 __DSB();
929 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
930 __DSB();
931 }
932 }
933
934 /* Write data to memory */
935 for (index = 0U; index < hnand->Config.PageSize; index++)
936 {
937 *(__IO uint8_t *)deviceaddress = *buff;
938 buff++;
939 __DSB();
940 }
941
942 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
943 __DSB();
944
945 /* Get tick */
946 tickstart = HAL_GetTick();
947
948 /* Read status until NAND is ready */
949 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
950 {
951 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
952 {
953 /* Update the NAND controller state */
954 hnand->State = HAL_NAND_STATE_ERROR;
955
956 /* Process unlocked */
957 __HAL_UNLOCK(hnand);
958
959 return HAL_TIMEOUT;
960 }
961 }
962
963 /* Increment written pages number */
964 numpageswritten++;
965
966 /* Decrement pages to write */
967 nbpages--;
968
969 /* Increment the NAND address */
970 nandaddress = (uint32_t)(nandaddress + 1U);
971 }
972
973 /* Update the NAND controller state */
974 hnand->State = HAL_NAND_STATE_READY;
975
976 /* Process unlocked */
977 __HAL_UNLOCK(hnand);
978 }
979 else
980 {
981 return HAL_ERROR;
982 }
983
984 return HAL_OK;
985 }
986
987 /**
988 * @brief Write Page(s) to NAND memory block (16-bits addressing)
989 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
990 * the configuration information for NAND module.
991 * @param pAddress pointer to NAND address structure
992 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
993 * @param NumPageToWrite number of pages to write to block
994 * @retval HAL status
995 */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)996 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer,
997 uint32_t NumPageToWrite)
998 {
999 uint32_t index;
1000 uint32_t tickstart;
1001 uint32_t deviceaddress;
1002 uint32_t numpageswritten = 0U;
1003 uint32_t nandaddress;
1004 uint32_t nbpages = NumPageToWrite;
1005 uint16_t *buff = pBuffer;
1006
1007 /* Check the NAND controller state */
1008 if (hnand->State == HAL_NAND_STATE_BUSY)
1009 {
1010 return HAL_BUSY;
1011 }
1012 else if (hnand->State == HAL_NAND_STATE_READY)
1013 {
1014 /* Process Locked */
1015 __HAL_LOCK(hnand);
1016
1017 /* Update the NAND controller state */
1018 hnand->State = HAL_NAND_STATE_BUSY;
1019
1020 /* Identify the device address */
1021 deviceaddress = NAND_DEVICE;
1022
1023 /* NAND raw address calculation */
1024 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1025
1026 /* Page(s) write loop */
1027 while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1028 {
1029 /* Send write page command sequence */
1030 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1031 __DSB();
1032 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1033 __DSB();
1034
1035 /* Cards with page size <= 512 bytes */
1036 if ((hnand->Config.PageSize) <= 512U)
1037 {
1038 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1039 {
1040 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1041 __DSB();
1042 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1043 __DSB();
1044 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1045 __DSB();
1046 }
1047 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1048 {
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 else /* (hnand->Config.PageSize) > 512 */
1060 {
1061 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1062 {
1063 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1064 __DSB();
1065 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1066 __DSB();
1067 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1068 __DSB();
1069 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1070 __DSB();
1071 }
1072 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1073 {
1074 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1075 __DSB();
1076 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1077 __DSB();
1078 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1079 __DSB();
1080 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1081 __DSB();
1082 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1083 __DSB();
1084 }
1085 }
1086
1087 /* Calculate PageSize */
1088 if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
1089 {
1090 hnand->Config.PageSize = hnand->Config.PageSize / 2U;
1091 }
1092 else
1093 {
1094 /* Do nothing */
1095 /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/
1096 }
1097
1098 /* Write data to memory */
1099 for (index = 0U; index < hnand->Config.PageSize; index++)
1100 {
1101 *(__IO uint16_t *)deviceaddress = *buff;
1102 buff++;
1103 __DSB();
1104 }
1105
1106 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1107 __DSB();
1108
1109 /* Get tick */
1110 tickstart = HAL_GetTick();
1111
1112 /* Read status until NAND is ready */
1113 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1114 {
1115 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1116 {
1117 /* Update the NAND controller state */
1118 hnand->State = HAL_NAND_STATE_ERROR;
1119
1120 /* Process unlocked */
1121 __HAL_UNLOCK(hnand);
1122
1123 return HAL_TIMEOUT;
1124 }
1125 }
1126
1127 /* Increment written pages number */
1128 numpageswritten++;
1129
1130 /* Decrement pages to write */
1131 nbpages--;
1132
1133 /* Increment the NAND address */
1134 nandaddress = (uint32_t)(nandaddress + 1U);
1135 }
1136
1137 /* Update the NAND controller state */
1138 hnand->State = HAL_NAND_STATE_READY;
1139
1140 /* Process unlocked */
1141 __HAL_UNLOCK(hnand);
1142 }
1143 else
1144 {
1145 return HAL_ERROR;
1146 }
1147
1148 return HAL_OK;
1149 }
1150
1151 /**
1152 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
1153 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1154 * the configuration information for NAND module.
1155 * @param pAddress pointer to NAND address structure
1156 * @param pBuffer pointer to source buffer to write
1157 * @param NumSpareAreaToRead Number of spare area to read
1158 * @retval HAL status
1159 */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1160 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer,
1161 uint32_t NumSpareAreaToRead)
1162 {
1163 uint32_t index;
1164 uint32_t tickstart;
1165 uint32_t deviceaddress;
1166 uint32_t numsparearearead = 0U;
1167 uint32_t nandaddress;
1168 uint32_t columnaddress;
1169 uint32_t nbspare = NumSpareAreaToRead;
1170 uint8_t *buff = pBuffer;
1171
1172 /* Check the NAND controller state */
1173 if (hnand->State == HAL_NAND_STATE_BUSY)
1174 {
1175 return HAL_BUSY;
1176 }
1177 else if (hnand->State == HAL_NAND_STATE_READY)
1178 {
1179 /* Process Locked */
1180 __HAL_LOCK(hnand);
1181
1182 /* Update the NAND controller state */
1183 hnand->State = HAL_NAND_STATE_BUSY;
1184
1185 /* Identify the device address */
1186 deviceaddress = NAND_DEVICE;
1187
1188 /* NAND raw address calculation */
1189 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1190
1191 /* Column in page address */
1192 columnaddress = COLUMN_ADDRESS(hnand);
1193
1194 /* Spare area(s) read loop */
1195 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1196 {
1197 /* Cards with page size <= 512 bytes */
1198 if ((hnand->Config.PageSize) <= 512U)
1199 {
1200 /* Send read spare area command sequence */
1201 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1202 __DSB();
1203
1204 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1205 {
1206 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1207 __DSB();
1208 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1209 __DSB();
1210 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1211 __DSB();
1212 }
1213 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1214 {
1215 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1216 __DSB();
1217 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1218 __DSB();
1219 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1220 __DSB();
1221 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1222 __DSB();
1223 }
1224 }
1225 else /* (hnand->Config.PageSize) > 512 */
1226 {
1227 /* Send read spare area command sequence */
1228 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1229 __DSB();
1230
1231 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1232 {
1233 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1234 __DSB();
1235 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1236 __DSB();
1237 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1238 __DSB();
1239 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1240 __DSB();
1241 }
1242 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1243 {
1244 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1245 __DSB();
1246 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1247 __DSB();
1248 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1249 __DSB();
1250 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1251 __DSB();
1252 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1253 __DSB();
1254 }
1255 }
1256
1257 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1258 __DSB();
1259
1260 if (hnand->Config.ExtraCommandEnable == ENABLE)
1261 {
1262 /* Get tick */
1263 tickstart = HAL_GetTick();
1264
1265 /* Read status until NAND is ready */
1266 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1267 {
1268 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1269 {
1270 /* Update the NAND controller state */
1271 hnand->State = HAL_NAND_STATE_ERROR;
1272
1273 /* Process unlocked */
1274 __HAL_UNLOCK(hnand);
1275
1276 return HAL_TIMEOUT;
1277 }
1278 }
1279
1280 /* Go back to read mode */
1281 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1282 __DSB();
1283 }
1284
1285 /* Get Data into Buffer */
1286 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1287 {
1288 *buff = *(uint8_t *)deviceaddress;
1289 buff++;
1290 }
1291
1292 /* Increment read spare areas number */
1293 numsparearearead++;
1294
1295 /* Decrement spare areas to read */
1296 nbspare--;
1297
1298 /* Increment the NAND address */
1299 nandaddress = (uint32_t)(nandaddress + 1U);
1300 }
1301
1302 /* Update the NAND controller state */
1303 hnand->State = HAL_NAND_STATE_READY;
1304
1305 /* Process unlocked */
1306 __HAL_UNLOCK(hnand);
1307 }
1308 else
1309 {
1310 return HAL_ERROR;
1311 }
1312
1313 return HAL_OK;
1314 }
1315
1316 /**
1317 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1318 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1319 * the configuration information for NAND module.
1320 * @param pAddress pointer to NAND address structure
1321 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1322 * @param NumSpareAreaToRead Number of spare area to read
1323 * @retval HAL status
1324 */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1325 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1326 uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1327 {
1328 uint32_t index;
1329 uint32_t tickstart;
1330 uint32_t deviceaddress;
1331 uint32_t numsparearearead = 0U;
1332 uint32_t nandaddress;
1333 uint32_t columnaddress;
1334 uint32_t nbspare = NumSpareAreaToRead;
1335 uint16_t *buff = pBuffer;
1336
1337 /* Check the NAND controller state */
1338 if (hnand->State == HAL_NAND_STATE_BUSY)
1339 {
1340 return HAL_BUSY;
1341 }
1342 else if (hnand->State == HAL_NAND_STATE_READY)
1343 {
1344 /* Process Locked */
1345 __HAL_LOCK(hnand);
1346
1347 /* Update the NAND controller state */
1348 hnand->State = HAL_NAND_STATE_BUSY;
1349
1350 /* Identify the device address */
1351 deviceaddress = NAND_DEVICE;
1352
1353 /* NAND raw address calculation */
1354 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1355
1356 /* Column in page address */
1357 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1358
1359 /* Spare area(s) read loop */
1360 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1361 {
1362 /* Cards with page size <= 512 bytes */
1363 if ((hnand->Config.PageSize) <= 512U)
1364 {
1365 /* Send read spare area command sequence */
1366 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1367 __DSB();
1368
1369 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1370 {
1371 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1372 __DSB();
1373 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1374 __DSB();
1375 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1376 __DSB();
1377 }
1378 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1379 {
1380 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1381 __DSB();
1382 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1383 __DSB();
1384 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1385 __DSB();
1386 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1387 __DSB();
1388 }
1389 }
1390 else /* (hnand->Config.PageSize) > 512 */
1391 {
1392 /* Send read spare area command sequence */
1393 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1394 __DSB();
1395
1396 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1397 {
1398 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1399 __DSB();
1400 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1401 __DSB();
1402 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1403 __DSB();
1404 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1405 __DSB();
1406 }
1407 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1408 {
1409 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1410 __DSB();
1411 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1412 __DSB();
1413 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1414 __DSB();
1415 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1416 __DSB();
1417 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1418 __DSB();
1419 }
1420 }
1421
1422 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1423 __DSB();
1424
1425 if (hnand->Config.ExtraCommandEnable == ENABLE)
1426 {
1427 /* Get tick */
1428 tickstart = HAL_GetTick();
1429
1430 /* Read status until NAND is ready */
1431 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1432 {
1433 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1434 {
1435 /* Update the NAND controller state */
1436 hnand->State = HAL_NAND_STATE_ERROR;
1437
1438 /* Process unlocked */
1439 __HAL_UNLOCK(hnand);
1440
1441 return HAL_TIMEOUT;
1442 }
1443 }
1444
1445 /* Go back to read mode */
1446 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
1447 __DSB();
1448 }
1449
1450 /* Get Data into Buffer */
1451 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1452 {
1453 *buff = *(uint16_t *)deviceaddress;
1454 buff++;
1455 }
1456
1457 /* Increment read spare areas number */
1458 numsparearearead++;
1459
1460 /* Decrement spare areas to read */
1461 nbspare--;
1462
1463 /* Increment the NAND address */
1464 nandaddress = (uint32_t)(nandaddress + 1U);
1465 }
1466
1467 /* Update the NAND controller state */
1468 hnand->State = HAL_NAND_STATE_READY;
1469
1470 /* Process unlocked */
1471 __HAL_UNLOCK(hnand);
1472 }
1473 else
1474 {
1475 return HAL_ERROR;
1476 }
1477
1478 return HAL_OK;
1479 }
1480
1481 /**
1482 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1483 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1484 * the configuration information for NAND module.
1485 * @param pAddress pointer to NAND address structure
1486 * @param pBuffer pointer to source buffer to write
1487 * @param NumSpareAreaTowrite number of spare areas to write to block
1488 * @retval HAL status
1489 */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1490 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1491 uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1492 {
1493 uint32_t index;
1494 uint32_t tickstart;
1495 uint32_t deviceaddress;
1496 uint32_t numspareareawritten = 0U;
1497 uint32_t nandaddress;
1498 uint32_t columnaddress;
1499 uint32_t nbspare = NumSpareAreaTowrite;
1500 uint8_t *buff = pBuffer;
1501
1502 /* Check the NAND controller state */
1503 if (hnand->State == HAL_NAND_STATE_BUSY)
1504 {
1505 return HAL_BUSY;
1506 }
1507 else if (hnand->State == HAL_NAND_STATE_READY)
1508 {
1509 /* Process Locked */
1510 __HAL_LOCK(hnand);
1511
1512 /* Update the NAND controller state */
1513 hnand->State = HAL_NAND_STATE_BUSY;
1514
1515 /* Identify the device address */
1516 deviceaddress = NAND_DEVICE;
1517
1518 /* Page address calculation */
1519 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1520
1521 /* Column in page address */
1522 columnaddress = COLUMN_ADDRESS(hnand);
1523
1524 /* Spare area(s) write loop */
1525 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1526 {
1527 /* Cards with page size <= 512 bytes */
1528 if ((hnand->Config.PageSize) <= 512U)
1529 {
1530 /* Send write Spare area command sequence */
1531 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1532 __DSB();
1533 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1534 __DSB();
1535
1536 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1537 {
1538 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1539 __DSB();
1540 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1541 __DSB();
1542 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1543 __DSB();
1544 }
1545 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1546 {
1547 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1548 __DSB();
1549 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1550 __DSB();
1551 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1552 __DSB();
1553 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1554 __DSB();
1555 }
1556 }
1557 else /* (hnand->Config.PageSize) > 512 */
1558 {
1559 /* Send write Spare area command sequence */
1560 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1561 __DSB();
1562 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1563 __DSB();
1564
1565 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1566 {
1567 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1568 __DSB();
1569 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1570 __DSB();
1571 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1572 __DSB();
1573 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1574 __DSB();
1575 }
1576 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1577 {
1578 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1579 __DSB();
1580 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1581 __DSB();
1582 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1583 __DSB();
1584 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1585 __DSB();
1586 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1587 __DSB();
1588 }
1589 }
1590
1591 /* Write data to memory */
1592 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1593 {
1594 *(__IO uint8_t *)deviceaddress = *buff;
1595 buff++;
1596 __DSB();
1597 }
1598
1599 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1600 __DSB();
1601
1602 /* Get tick */
1603 tickstart = HAL_GetTick();
1604
1605 /* Read status until NAND is ready */
1606 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1607 {
1608 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1609 {
1610 /* Update the NAND controller state */
1611 hnand->State = HAL_NAND_STATE_ERROR;
1612
1613 /* Process unlocked */
1614 __HAL_UNLOCK(hnand);
1615
1616 return HAL_TIMEOUT;
1617 }
1618 }
1619
1620 /* Increment written spare areas number */
1621 numspareareawritten++;
1622
1623 /* Decrement spare areas to write */
1624 nbspare--;
1625
1626 /* Increment the NAND address */
1627 nandaddress = (uint32_t)(nandaddress + 1U);
1628 }
1629
1630 /* Update the NAND controller state */
1631 hnand->State = HAL_NAND_STATE_READY;
1632
1633 /* Process unlocked */
1634 __HAL_UNLOCK(hnand);
1635 }
1636 else
1637 {
1638 return HAL_ERROR;
1639 }
1640
1641 return HAL_OK;
1642 }
1643
1644 /**
1645 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1646 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1647 * the configuration information for NAND module.
1648 * @param pAddress pointer to NAND address structure
1649 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1650 * @param NumSpareAreaTowrite number of spare areas to write to block
1651 * @retval HAL status
1652 */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1653 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress,
1654 uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1655 {
1656 uint32_t index;
1657 uint32_t tickstart;
1658 uint32_t deviceaddress;
1659 uint32_t numspareareawritten = 0U;
1660 uint32_t nandaddress;
1661 uint32_t columnaddress;
1662 uint32_t nbspare = NumSpareAreaTowrite;
1663 uint16_t *buff = pBuffer;
1664
1665 /* Check the NAND controller state */
1666 if (hnand->State == HAL_NAND_STATE_BUSY)
1667 {
1668 return HAL_BUSY;
1669 }
1670 else if (hnand->State == HAL_NAND_STATE_READY)
1671 {
1672 /* Process Locked */
1673 __HAL_LOCK(hnand);
1674
1675 /* Update the NAND controller state */
1676 hnand->State = HAL_NAND_STATE_BUSY;
1677
1678 /* Identify the device address */
1679 deviceaddress = NAND_DEVICE;
1680
1681 /* NAND raw address calculation */
1682 nandaddress = ARRAY_ADDRESS(pAddress, hnand);
1683
1684 /* Column in page address */
1685 columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand));
1686
1687 /* Spare area(s) write loop */
1688 while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1689 {
1690 /* Cards with page size <= 512 bytes */
1691 if ((hnand->Config.PageSize) <= 512U)
1692 {
1693 /* Send write Spare area command sequence */
1694 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
1695 __DSB();
1696 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1697 __DSB();
1698
1699 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1700 {
1701 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1702 __DSB();
1703 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1704 __DSB();
1705 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1706 __DSB();
1707 }
1708 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1709 {
1710 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U;
1711 __DSB();
1712 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1713 __DSB();
1714 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1715 __DSB();
1716 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1717 __DSB();
1718 }
1719 }
1720 else /* (hnand->Config.PageSize) > 512 */
1721 {
1722 /* Send write Spare area command sequence */
1723 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
1724 __DSB();
1725 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
1726 __DSB();
1727
1728 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U)
1729 {
1730 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1731 __DSB();
1732 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1733 __DSB();
1734 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1735 __DSB();
1736 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1737 __DSB();
1738 }
1739 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1740 {
1741 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
1742 __DSB();
1743 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
1744 __DSB();
1745 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
1746 __DSB();
1747 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
1748 __DSB();
1749 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
1750 __DSB();
1751 }
1752 }
1753
1754 /* Write data to memory */
1755 for (index = 0U; index < hnand->Config.SpareAreaSize; index++)
1756 {
1757 *(__IO uint16_t *)deviceaddress = *buff;
1758 buff++;
1759 __DSB();
1760 }
1761
1762 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1763 __DSB();
1764
1765 /* Get tick */
1766 tickstart = HAL_GetTick();
1767
1768 /* Read status until NAND is ready */
1769 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1770 {
1771 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1772 {
1773 /* Update the NAND controller state */
1774 hnand->State = HAL_NAND_STATE_ERROR;
1775
1776 /* Process unlocked */
1777 __HAL_UNLOCK(hnand);
1778
1779 return HAL_TIMEOUT;
1780 }
1781 }
1782
1783 /* Increment written spare areas number */
1784 numspareareawritten++;
1785
1786 /* Decrement spare areas to write */
1787 nbspare--;
1788
1789 /* Increment the NAND address */
1790 nandaddress = (uint32_t)(nandaddress + 1U);
1791 }
1792
1793 /* Update the NAND controller state */
1794 hnand->State = HAL_NAND_STATE_READY;
1795
1796 /* Process unlocked */
1797 __HAL_UNLOCK(hnand);
1798 }
1799 else
1800 {
1801 return HAL_ERROR;
1802 }
1803
1804 return HAL_OK;
1805 }
1806
1807 /**
1808 * @brief NAND memory Block erase
1809 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1810 * the configuration information for NAND module.
1811 * @param pAddress pointer to NAND address structure
1812 * @retval HAL status
1813 */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1814 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1815 {
1816 uint32_t deviceaddress;
1817
1818 /* Check the NAND controller state */
1819 if (hnand->State == HAL_NAND_STATE_BUSY)
1820 {
1821 return HAL_BUSY;
1822 }
1823 else if (hnand->State == HAL_NAND_STATE_READY)
1824 {
1825 /* Process Locked */
1826 __HAL_LOCK(hnand);
1827
1828 /* Update the NAND controller state */
1829 hnand->State = HAL_NAND_STATE_BUSY;
1830
1831 /* Identify the device address */
1832 deviceaddress = NAND_DEVICE;
1833
1834 /* Send Erase block command sequence */
1835 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
1836 __DSB();
1837 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1838 __DSB();
1839 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1840 __DSB();
1841 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1842 __DSB();
1843
1844 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
1845 __DSB();
1846
1847 /* Update the NAND controller state */
1848 hnand->State = HAL_NAND_STATE_READY;
1849
1850 /* Process unlocked */
1851 __HAL_UNLOCK(hnand);
1852 }
1853 else
1854 {
1855 return HAL_ERROR;
1856 }
1857
1858 return HAL_OK;
1859 }
1860
1861 /**
1862 * @brief Increment the NAND memory address
1863 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1864 * the configuration information for NAND module.
1865 * @param pAddress pointer to NAND address structure
1866 * @retval The new status of the increment address operation. It can be:
1867 * - NAND_VALID_ADDRESS: When the new address is valid address
1868 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1869 */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1870 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1871 {
1872 uint32_t status = NAND_VALID_ADDRESS;
1873
1874 /* Increment page address */
1875 pAddress->Page++;
1876
1877 /* Check NAND address is valid */
1878 if (pAddress->Page == hnand->Config.BlockSize)
1879 {
1880 pAddress->Page = 0;
1881 pAddress->Block++;
1882
1883 if (pAddress->Block == hnand->Config.PlaneSize)
1884 {
1885 pAddress->Block = 0;
1886 pAddress->Plane++;
1887
1888 if (pAddress->Plane == (hnand->Config.PlaneNbr))
1889 {
1890 status = NAND_INVALID_ADDRESS;
1891 }
1892 }
1893 }
1894
1895 return (status);
1896 }
1897
1898 #if (USE_HAL_NAND_REGISTER_CALLBACKS == 1)
1899 /**
1900 * @brief Register a User NAND Callback
1901 * To be used instead of the weak (surcharged) predefined callback
1902 * @param hnand : NAND handle
1903 * @param CallbackId : ID of the callback to be registered
1904 * This parameter can be one of the following values:
1905 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1906 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1907 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1908 * @param pCallback : pointer to the Callback function
1909 * @retval status
1910 */
HAL_NAND_RegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId,pNAND_CallbackTypeDef pCallback)1911 HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId,
1912 pNAND_CallbackTypeDef pCallback)
1913 {
1914 HAL_StatusTypeDef status = HAL_OK;
1915
1916 if (pCallback == NULL)
1917 {
1918 return HAL_ERROR;
1919 }
1920
1921 /* Process locked */
1922 __HAL_LOCK(hnand);
1923
1924 if (hnand->State == HAL_NAND_STATE_READY)
1925 {
1926 switch (CallbackId)
1927 {
1928 case HAL_NAND_MSP_INIT_CB_ID :
1929 hnand->MspInitCallback = pCallback;
1930 break;
1931 case HAL_NAND_MSP_DEINIT_CB_ID :
1932 hnand->MspDeInitCallback = pCallback;
1933 break;
1934 case HAL_NAND_IT_CB_ID :
1935 hnand->ItCallback = pCallback;
1936 break;
1937 default :
1938 /* update return status */
1939 status = HAL_ERROR;
1940 break;
1941 }
1942 }
1943 else if (hnand->State == HAL_NAND_STATE_RESET)
1944 {
1945 switch (CallbackId)
1946 {
1947 case HAL_NAND_MSP_INIT_CB_ID :
1948 hnand->MspInitCallback = pCallback;
1949 break;
1950 case HAL_NAND_MSP_DEINIT_CB_ID :
1951 hnand->MspDeInitCallback = pCallback;
1952 break;
1953 default :
1954 /* update return status */
1955 status = HAL_ERROR;
1956 break;
1957 }
1958 }
1959 else
1960 {
1961 /* update return status */
1962 status = HAL_ERROR;
1963 }
1964
1965 /* Release Lock */
1966 __HAL_UNLOCK(hnand);
1967 return status;
1968 }
1969
1970 /**
1971 * @brief Unregister a User NAND Callback
1972 * NAND Callback is redirected to the weak (surcharged) predefined callback
1973 * @param hnand : NAND handle
1974 * @param CallbackId : ID of the callback to be unregistered
1975 * This parameter can be one of the following values:
1976 * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID
1977 * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID
1978 * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID
1979 * @retval status
1980 */
HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef * hnand,HAL_NAND_CallbackIDTypeDef CallbackId)1981 HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId)
1982 {
1983 HAL_StatusTypeDef status = HAL_OK;
1984
1985 /* Process locked */
1986 __HAL_LOCK(hnand);
1987
1988 if (hnand->State == HAL_NAND_STATE_READY)
1989 {
1990 switch (CallbackId)
1991 {
1992 case HAL_NAND_MSP_INIT_CB_ID :
1993 hnand->MspInitCallback = HAL_NAND_MspInit;
1994 break;
1995 case HAL_NAND_MSP_DEINIT_CB_ID :
1996 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
1997 break;
1998 case HAL_NAND_IT_CB_ID :
1999 hnand->ItCallback = HAL_NAND_ITCallback;
2000 break;
2001 default :
2002 /* update return status */
2003 status = HAL_ERROR;
2004 break;
2005 }
2006 }
2007 else if (hnand->State == HAL_NAND_STATE_RESET)
2008 {
2009 switch (CallbackId)
2010 {
2011 case HAL_NAND_MSP_INIT_CB_ID :
2012 hnand->MspInitCallback = HAL_NAND_MspInit;
2013 break;
2014 case HAL_NAND_MSP_DEINIT_CB_ID :
2015 hnand->MspDeInitCallback = HAL_NAND_MspDeInit;
2016 break;
2017 default :
2018 /* update return status */
2019 status = HAL_ERROR;
2020 break;
2021 }
2022 }
2023 else
2024 {
2025 /* update return status */
2026 status = HAL_ERROR;
2027 }
2028
2029 /* Release Lock */
2030 __HAL_UNLOCK(hnand);
2031 return status;
2032 }
2033 #endif /* USE_HAL_NAND_REGISTER_CALLBACKS */
2034
2035 /**
2036 * @}
2037 */
2038
2039 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
2040 * @brief management functions
2041 *
2042 @verbatim
2043 ==============================================================================
2044 ##### NAND Control functions #####
2045 ==============================================================================
2046 [..]
2047 This subsection provides a set of functions allowing to control dynamically
2048 the NAND interface.
2049
2050 @endverbatim
2051 * @{
2052 */
2053
2054
2055 /**
2056 * @brief Enables dynamically NAND ECC feature.
2057 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2058 * the configuration information for NAND module.
2059 * @retval HAL status
2060 */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)2061 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
2062 {
2063 /* Check the NAND controller state */
2064 if (hnand->State == HAL_NAND_STATE_BUSY)
2065 {
2066 return HAL_BUSY;
2067 }
2068 else if (hnand->State == HAL_NAND_STATE_READY)
2069 {
2070 /* Update the NAND state */
2071 hnand->State = HAL_NAND_STATE_BUSY;
2072
2073 /* Enable ECC feature */
2074 (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
2075
2076 /* Update the NAND state */
2077 hnand->State = HAL_NAND_STATE_READY;
2078 }
2079 else
2080 {
2081 return HAL_ERROR;
2082 }
2083
2084 return HAL_OK;
2085 }
2086
2087 /**
2088 * @brief Disables dynamically FMC_NAND ECC feature.
2089 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2090 * the configuration information for NAND module.
2091 * @retval HAL status
2092 */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)2093 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
2094 {
2095 /* Check the NAND controller state */
2096 if (hnand->State == HAL_NAND_STATE_BUSY)
2097 {
2098 return HAL_BUSY;
2099 }
2100 else if (hnand->State == HAL_NAND_STATE_READY)
2101 {
2102 /* Update the NAND state */
2103 hnand->State = HAL_NAND_STATE_BUSY;
2104
2105 /* Disable ECC feature */
2106 (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
2107
2108 /* Update the NAND state */
2109 hnand->State = HAL_NAND_STATE_READY;
2110 }
2111 else
2112 {
2113 return HAL_ERROR;
2114 }
2115
2116 return HAL_OK;
2117 }
2118
2119 /**
2120 * @brief Disables dynamically NAND ECC feature.
2121 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2122 * the configuration information for NAND module.
2123 * @param ECCval pointer to ECC value
2124 * @param Timeout maximum timeout to wait
2125 * @retval HAL status
2126 */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)2127 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
2128 {
2129 HAL_StatusTypeDef status;
2130
2131 /* Check the NAND controller state */
2132 if (hnand->State == HAL_NAND_STATE_BUSY)
2133 {
2134 return HAL_BUSY;
2135 }
2136 else if (hnand->State == HAL_NAND_STATE_READY)
2137 {
2138 /* Update the NAND state */
2139 hnand->State = HAL_NAND_STATE_BUSY;
2140
2141 /* Get NAND ECC value */
2142 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
2143
2144 /* Update the NAND state */
2145 hnand->State = HAL_NAND_STATE_READY;
2146 }
2147 else
2148 {
2149 return HAL_ERROR;
2150 }
2151
2152 return status;
2153 }
2154
2155 /**
2156 * @}
2157 */
2158
2159
2160 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
2161 * @brief Peripheral State functions
2162 *
2163 @verbatim
2164 ==============================================================================
2165 ##### NAND State functions #####
2166 ==============================================================================
2167 [..]
2168 This subsection permits to get in run-time the status of the NAND controller
2169 and the data flow.
2170
2171 @endverbatim
2172 * @{
2173 */
2174
2175 /**
2176 * @brief return the NAND state
2177 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2178 * the configuration information for NAND module.
2179 * @retval HAL state
2180 */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)2181 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
2182 {
2183 return hnand->State;
2184 }
2185
2186 /**
2187 * @brief NAND memory read status
2188 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
2189 * the configuration information for NAND module.
2190 * @retval NAND status
2191 */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)2192 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
2193 {
2194 uint32_t data;
2195 uint32_t deviceaddress;
2196 UNUSED(hnand);
2197
2198 /* Identify the device address */
2199 deviceaddress = NAND_DEVICE;
2200
2201 /* Send Read status operation command */
2202 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
2203
2204 /* Read status register data */
2205 data = *(__IO uint8_t *)deviceaddress;
2206
2207 /* Return the status */
2208 if ((data & NAND_ERROR) == NAND_ERROR)
2209 {
2210 return NAND_ERROR;
2211 }
2212 else if ((data & NAND_READY) == NAND_READY)
2213 {
2214 return NAND_READY;
2215 }
2216 else
2217 {
2218 return NAND_BUSY;
2219 }
2220 }
2221
2222 /**
2223 * @}
2224 */
2225
2226 /**
2227 * @}
2228 */
2229
2230 /**
2231 * @}
2232 */
2233
2234 #endif /* HAL_NAND_MODULE_ENABLED */
2235
2236 /**
2237 * @}
2238 */
2239
2240
2241 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2242