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