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