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