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