1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_nand.c
4 * @author MCD Application Team
5 * @brief NAND HAL module driver.
6 * This file provides a generic firmware to drive NAND memories mounted
7 * as external device.
8 *
9 @verbatim
10 ==============================================================================
11 ##### How to use this driver #####
12 ==============================================================================
13 [..]
14 This driver is a generic layered driver which contains a set of APIs used to
15 control NAND flash memories. It uses the FMC layer functions to interface
16 with NAND devices. This driver is used as follows:
17
18 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
19 with control and timing parameters for both common and attribute spaces.
20
21 (+) Read NAND flash memory maker and device IDs using the function
22 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
23 structure declared by the function caller.
24
25 (+) Access NAND flash memory by read/write operations using the functions
26 HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
27 HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
28 HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
29 HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
30 to read/write page(s)/spare area(s). These functions use specific device
31 information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
32 structure. The read/write address information is contained by the Nand_Address_Typedef
33 structure passed as parameter.
34
35 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
36
37 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
38 The erase block address information is contained in the Nand_Address_Typedef
39 structure passed as parameter.
40
41 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
42
43 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
44 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
45 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
46
47 (+) You can monitor the NAND device HAL state by calling the function
48 HAL_NAND_GetState()
49
50 [..]
51 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
52 If a NAND flash device contains different operations and/or implementations,
53 it should be implemented separately.
54
55 @endverbatim
56 ******************************************************************************
57 * @attention
58 *
59 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
60 *
61 * Redistribution and use in source and binary forms, with or without modification,
62 * are permitted provided that the following conditions are met:
63 * 1. Redistributions of source code must retain the above copyright notice,
64 * this list of conditions and the following disclaimer.
65 * 2. Redistributions in binary form must reproduce the above copyright notice,
66 * this list of conditions and the following disclaimer in the documentation
67 * and/or other materials provided with the distribution.
68 * 3. Neither the name of STMicroelectronics nor the names of its contributors
69 * may be used to endorse or promote products derived from this software
70 * without specific prior written permission.
71 *
72 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
73 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
76 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
78 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
79 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
80 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
81 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 *
83 ******************************************************************************
84 */
85
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32l4xx_hal.h"
88
89 #if defined(FMC_BANK3)
90
91 /** @addtogroup STM32L4xx_HAL_Driver
92 * @{
93 */
94
95 #ifdef HAL_NAND_MODULE_ENABLED
96
97 /** @defgroup NAND NAND
98 * @brief NAND HAL module driver
99 * @{
100 */
101
102 /* Private typedef -----------------------------------------------------------*/
103 /* Private Constants ------------------------------------------------------------*/
104 /* Private macro -------------------------------------------------------------*/
105 /* Private variables ---------------------------------------------------------*/
106 /* Private function prototypes -----------------------------------------------*/
107 /* Exported functions ---------------------------------------------------------*/
108
109 /** @defgroup NAND_Exported_Functions NAND Exported Functions
110 * @{
111 */
112
113 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
114 * @brief Initialization and Configuration functions
115 *
116 @verbatim
117 ==============================================================================
118 ##### NAND Initialization and de-initialization functions #####
119 ==============================================================================
120 [..]
121 This section provides functions allowing to initialize/de-initialize
122 the NAND memory
123
124 @endverbatim
125 * @{
126 */
127
128 /**
129 * @brief Perform NAND memory Initialization sequence
130 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
131 * the configuration information for NAND module.
132 * @param ComSpace_Timing pointer to Common space timing structure
133 * @param AttSpace_Timing pointer to Attribute space timing structure
134 * @retval HAL status
135 */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)136 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
137 {
138 /* Check the NAND handle state */
139 if(hnand == NULL)
140 {
141 return HAL_ERROR;
142 }
143
144 if(hnand->State == HAL_NAND_STATE_RESET)
145 {
146 /* Allocate lock resource and initialize it */
147 hnand->Lock = HAL_UNLOCKED;
148 /* Initialize the low level hardware (MSP) */
149 HAL_NAND_MspInit(hnand);
150 }
151
152 /* Initialize NAND control Interface */
153 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
154
155 /* Initialize NAND common space timing Interface */
156 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
157
158 /* Initialize NAND attribute space timing Interface */
159 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
160
161 /* Enable the NAND device */
162 __FMC_NAND_ENABLE(hnand->Instance);
163
164 /* Update the NAND controller state */
165 hnand->State = HAL_NAND_STATE_READY;
166
167 return HAL_OK;
168 }
169
170 /**
171 * @brief Perform NAND memory De-Initialization sequence
172 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
173 * the configuration information for NAND module.
174 * @retval HAL status
175 */
HAL_NAND_DeInit(NAND_HandleTypeDef * hnand)176 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
177 {
178 /* Initialize the low level hardware (MSP) */
179 HAL_NAND_MspDeInit(hnand);
180
181 /* Configure the NAND registers with their reset values */
182 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
183
184 /* Reset the NAND controller state */
185 hnand->State = HAL_NAND_STATE_RESET;
186
187 /* Release Lock */
188 __HAL_UNLOCK(hnand);
189
190 return HAL_OK;
191 }
192
193 /**
194 * @brief Initialize the NAND MSP
195 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
196 * the configuration information for NAND module.
197 * @retval None
198 */
HAL_NAND_MspInit(NAND_HandleTypeDef * hnand)199 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
200 {
201 /* Prevent unused argument(s) compilation warning */
202 UNUSED(hnand);
203
204 /* NOTE : This function should not be modified, when the callback is needed,
205 the HAL_NAND_MspInit could be implemented in the user file
206 */
207 }
208
209 /**
210 * @brief DeInitialize the NAND MSP
211 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
212 * the configuration information for NAND module.
213 * @retval None
214 */
HAL_NAND_MspDeInit(NAND_HandleTypeDef * hnand)215 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
216 {
217 /* Prevent unused argument(s) compilation warning */
218 UNUSED(hnand);
219
220 /* NOTE : This function should not be modified, when the callback is needed,
221 the HAL_NAND_MspDeInit could be implemented in the user file
222 */
223 }
224
225
226 /**
227 * @brief This function handles NAND device interrupt request.
228 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
229 * the configuration information for NAND module.
230 * @retval HAL status
231 */
HAL_NAND_IRQHandler(NAND_HandleTypeDef * hnand)232 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
233 {
234 /* Check NAND interrupt Rising edge flag */
235 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
236 {
237 /* NAND interrupt callback*/
238 HAL_NAND_ITCallback(hnand);
239
240 /* Clear NAND interrupt Rising edge pending bit */
241 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
242 }
243
244 /* Check NAND interrupt Level flag */
245 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
246 {
247 /* NAND interrupt callback*/
248 HAL_NAND_ITCallback(hnand);
249
250 /* Clear NAND interrupt Level pending bit */
251 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
252 }
253
254 /* Check NAND interrupt Falling edge flag */
255 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
256 {
257 /* NAND interrupt callback*/
258 HAL_NAND_ITCallback(hnand);
259
260 /* Clear NAND interrupt Falling edge pending bit */
261 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
262 }
263
264 /* Check NAND interrupt FIFO empty flag */
265 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
266 {
267 /* NAND interrupt callback*/
268 HAL_NAND_ITCallback(hnand);
269
270 /* Clear NAND interrupt FIFO empty pending bit */
271 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
272 }
273
274 }
275
276 /**
277 * @brief NAND interrupt feature callback
278 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
279 * the configuration information for NAND module.
280 * @retval None
281 */
HAL_NAND_ITCallback(NAND_HandleTypeDef * hnand)282 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
283 {
284 /* Prevent unused argument(s) compilation warning */
285 UNUSED(hnand);
286
287 /* NOTE : This function should not be modified, when the callback is needed,
288 the HAL_NAND_ITCallback could be implemented in the user file
289 */
290 }
291
292 /**
293 * @}
294 */
295
296 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
297 * @brief Input Output and memory control functions
298 *
299 @verbatim
300 ==============================================================================
301 ##### NAND Input and Output functions #####
302 ==============================================================================
303 [..]
304 This section provides functions allowing to use and control the NAND
305 memory
306
307 @endverbatim
308 * @{
309 */
310
311 /**
312 * @brief Read the NAND memory electronic signature
313 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
314 * the configuration information for NAND module.
315 * @param pNAND_ID NAND ID structure
316 * @retval HAL status
317 */
HAL_NAND_Read_ID(NAND_HandleTypeDef * hnand,NAND_IDTypeDef * pNAND_ID)318 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
319 {
320 __IO uint32_t data = 0;
321 __IO uint32_t data1 = 0;
322 uint32_t deviceAddress = 0;
323
324 /* Process Locked */
325 __HAL_LOCK(hnand);
326
327 /* Check the NAND controller state */
328 if(hnand->State == HAL_NAND_STATE_BUSY)
329 {
330 return HAL_BUSY;
331 }
332
333 /* Identify the device address */
334 deviceAddress = NAND_DEVICE;
335
336 /* Update the NAND controller state */
337 hnand->State = HAL_NAND_STATE_BUSY;
338
339 /* Send Read ID command sequence */
340 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
341 __DSB();
342 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
343 __DSB();
344
345 /* Read the electronic signature from NAND flash */
346 if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
347 {
348 data = *(__IO uint32_t *)deviceAddress;
349
350 /* Return the data read */
351 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
352 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
353 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
354 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
355 }
356 else
357 {
358 data = *(__IO uint32_t *)deviceAddress;
359 data1 = *((__IO uint32_t *)deviceAddress + 4);
360
361 /* Return the data read */
362 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
363 pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
364 pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
365 pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
366 }
367
368 /* Update the NAND controller state */
369 hnand->State = HAL_NAND_STATE_READY;
370
371 /* Process unlocked */
372 __HAL_UNLOCK(hnand);
373
374 return HAL_OK;
375 }
376
377 /**
378 * @brief NAND memory reset
379 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
380 * the configuration information for NAND module.
381 * @retval HAL status
382 */
HAL_NAND_Reset(NAND_HandleTypeDef * hnand)383 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
384 {
385 uint32_t deviceAddress = 0;
386
387 /* Process Locked */
388 __HAL_LOCK(hnand);
389
390 /* Check the NAND controller state */
391 if(hnand->State == HAL_NAND_STATE_BUSY)
392 {
393 return HAL_BUSY;
394 }
395
396 /* Identify the device address */
397 deviceAddress = NAND_DEVICE;
398
399 /* Update the NAND controller state */
400 hnand->State = HAL_NAND_STATE_BUSY;
401
402 /* Send NAND reset command */
403 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
404
405 /* Update the NAND controller state */
406 hnand->State = HAL_NAND_STATE_READY;
407
408 /* Process unlocked */
409 __HAL_UNLOCK(hnand);
410
411 return HAL_OK;
412
413 }
414
415 /**
416 * @brief Configure the device: Enter the physical parameters of the device
417 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
418 * the configuration information for NAND module.
419 * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure
420 * @retval HAL status
421 */
HAL_NAND_ConfigDevice(NAND_HandleTypeDef * hnand,NAND_DeviceConfigTypeDef * pDeviceConfig)422 HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
423 {
424 hnand->Config.PageSize = pDeviceConfig->PageSize;
425 hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
426 hnand->Config.BlockSize = pDeviceConfig->BlockSize;
427 hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
428 hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
429 hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
430 hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
431
432 return HAL_OK;
433 }
434
435
436 /**
437 * @brief Read Page(s) from NAND memory block (8-bits addressing)
438 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
439 * the configuration information for NAND module.
440 * @param pAddress pointer to NAND address structure
441 * @param pBuffer pointer to destination read buffer
442 * @param NumPageToRead number of pages to read from block
443 * @retval HAL status
444 */
HAL_NAND_Read_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToRead)445 HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
446 {
447 __IO uint32_t index = 0;
448 uint32_t tickstart = 0U;
449 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
450
451 /* Process Locked */
452 __HAL_LOCK(hnand);
453
454 /* Check the NAND controller state */
455 if(hnand->State == HAL_NAND_STATE_BUSY)
456 {
457 return HAL_BUSY;
458 }
459
460 /* Identify the device address */
461 deviceAddress = NAND_DEVICE;
462
463 /* Update the NAND controller state */
464 hnand->State = HAL_NAND_STATE_BUSY;
465
466 /* NAND raw address calculation */
467 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
468
469 /* Page(s) read loop */
470 while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
471 {
472 /* update the buffer size */
473 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
474
475 /* Send read page command sequence */
476 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
477 __DSB();
478
479 /* Cards with page size <= 512 bytes */
480 if ((hnand->Config.PageSize) <= 512)
481 {
482 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
483 {
484 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
485 __DSB();
486 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
487 __DSB();
488 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
489 __DSB();
490 }
491 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
492 {
493 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
494 __DSB();
495 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
496 __DSB();
497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
498 __DSB();
499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
500 __DSB();
501 }
502 }
503 else /* (hnand->Config.PageSize) > 512 */
504 {
505 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
506 {
507 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
508 __DSB();
509 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
510 __DSB();
511 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
512 __DSB();
513 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
514 __DSB();
515 }
516 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
517 {
518 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
519 __DSB();
520 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
521 __DSB();
522 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
523 __DSB();
524 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
525 __DSB();
526 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
527 __DSB();
528 }
529 }
530
531 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
532 __DSB();
533
534
535 if (hnand->Config.ExtraCommandEnable == ENABLE)
536 {
537 /* Get tick */
538 tickstart = HAL_GetTick();
539
540 /* Read status until NAND is ready */
541 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
542 {
543 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
544 {
545 return HAL_TIMEOUT;
546 }
547 }
548
549 /* Go back to read mode */
550 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
551 __DSB();
552 }
553
554 /* Get Data into Buffer */
555 for(; index < size; index++)
556 {
557 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
558 }
559
560 /* Increment read pages number */
561 numPagesRead++;
562
563 /* Decrement pages to read */
564 NumPageToRead--;
565
566 /* Increment the NAND address */
567 nandAddress = (uint32_t)(nandAddress + 1);
568 }
569
570 /* Update the NAND controller state */
571 hnand->State = HAL_NAND_STATE_READY;
572
573 /* Process unlocked */
574 __HAL_UNLOCK(hnand);
575
576 return HAL_OK;
577 }
578
579 /**
580 * @brief Read Page(s) from NAND memory block (16-bits addressing)
581 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
582 * the configuration information for NAND module.
583 * @param pAddress pointer to NAND address structure
584 * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned
585 * @param NumPageToRead number of pages to read from block
586 * @retval HAL status
587 */
HAL_NAND_Read_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToRead)588 HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
589 {
590 __IO uint32_t index = 0;
591 uint32_t tickstart = 0;
592 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
593
594 /* Process Locked */
595 __HAL_LOCK(hnand);
596
597 /* Check the NAND controller state */
598 if (hnand->State == HAL_NAND_STATE_BUSY)
599 {
600 return HAL_BUSY;
601 }
602
603 /* Identify the device address */
604 deviceAddress = NAND_DEVICE;
605
606 /* Update the NAND controller state */
607 hnand->State = HAL_NAND_STATE_BUSY;
608
609 /* NAND raw address calculation */
610 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
611
612 /* Page(s) read loop */
613 while ((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
614 {
615 /* update the buffer size */
616 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
617
618 /* Send read page command sequence */
619 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
620 __DSB();
621
622 /* Cards with page size <= 512 bytes */
623 if ((hnand->Config.PageSize) <= 512)
624 {
625 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
626 {
627 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
628 __DSB();
629 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
630 __DSB();
631 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
632 __DSB();
633 }
634 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
635 {
636 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
637 __DSB();
638 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
639 __DSB();
640 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
641 __DSB();
642 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
643 __DSB();
644 }
645 }
646 else /* (hnand->Config.PageSize) > 512 */
647 {
648 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
649 {
650 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
651 __DSB();
652 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
653 __DSB();
654 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
655 __DSB();
656 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
657 __DSB();
658 }
659 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
660 {
661 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
662 __DSB();
663 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
664 __DSB();
665 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
666 __DSB();
667 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
668 __DSB();
669 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
670 __DSB();
671 }
672 }
673
674 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
675 __DSB();
676
677 if (hnand->Config.ExtraCommandEnable == ENABLE)
678 {
679 /* Get tick */
680 tickstart = HAL_GetTick();
681
682 /* Read status until NAND is ready */
683 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
684 {
685 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
686 {
687 return HAL_TIMEOUT;
688 }
689 }
690
691 /* Go back to read mode */
692 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
693 __DSB();
694 }
695
696 /* Get Data into Buffer */
697 for (; index < size; index++)
698 {
699 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
700 }
701
702 /* Increment read pages number */
703 numPagesRead++;
704
705 /* Decrement pages to read */
706 NumPageToRead--;
707
708 /* Increment the NAND address */
709 nandAddress = (uint32_t)(nandAddress + 1);
710 }
711
712 /* Update the NAND controller state */
713 hnand->State = HAL_NAND_STATE_READY;
714
715 /* Process unlocked */
716 __HAL_UNLOCK(hnand);
717
718 return HAL_OK;
719 }
720
721 /**
722 * @brief Write Page(s) to NAND memory block (8-bits addressing)
723 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
724 * the configuration information for NAND module.
725 * @param pAddress pointer to NAND address structure
726 * @param pBuffer pointer to source buffer to write
727 * @param NumPageToWrite number of pages to write to block
728 * @retval HAL status
729 */
HAL_NAND_Write_Page_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)730 HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
731 {
732 __IO uint32_t index = 0;
733 uint32_t tickstart = 0;
734 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
735
736 /* Process Locked */
737 __HAL_LOCK(hnand);
738
739 /* Check the NAND controller state */
740 if(hnand->State == HAL_NAND_STATE_BUSY)
741 {
742 return HAL_BUSY;
743 }
744
745 /* Identify the device address */
746 deviceAddress = NAND_DEVICE;
747
748 /* Update the NAND controller state */
749 hnand->State = HAL_NAND_STATE_BUSY;
750
751 /* NAND raw address calculation */
752 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
753
754 /* Page(s) write loop */
755 while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
756 {
757 /* update the buffer size */
758 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
759
760 /* Send write page command sequence */
761 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
762 __DSB();
763 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
764 __DSB();
765
766 /* Cards with page size <= 512 bytes */
767 if ((hnand->Config.PageSize) <= 512)
768 {
769 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
770 {
771 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
772 __DSB();
773 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
774 __DSB();
775 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
776 __DSB();
777 }
778 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
779 {
780 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
781 __DSB();
782 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
783 __DSB();
784 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
785 __DSB();
786 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
787 __DSB();
788 }
789 }
790 else /* (hnand->Config.PageSize) > 512 */
791 {
792 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
793 {
794 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
795 __DSB();
796 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
797 __DSB();
798 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
799 __DSB();
800 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
801 __DSB();
802 }
803 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
804 {
805 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
806 __DSB();
807 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
808 __DSB();
809 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
810 __DSB();
811 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
812 __DSB();
813 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
814 __DSB();
815 }
816 }
817
818 /* Write data to memory */
819 for (; index < size; index++)
820 {
821 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
822 __DSB();
823 }
824
825 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
826 __DSB();
827
828 /* Get tick */
829 tickstart = HAL_GetTick();
830
831 /* Read status until NAND is ready */
832 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
833 {
834 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
835 {
836 return HAL_TIMEOUT;
837 }
838 }
839
840 /* Increment written pages number */
841 numPagesWritten++;
842
843 /* Decrement pages to write */
844 NumPageToWrite--;
845
846 /* Increment the NAND address */
847 nandAddress = (uint32_t)(nandAddress + 1);
848 }
849
850 /* Update the NAND controller state */
851 hnand->State = HAL_NAND_STATE_READY;
852
853 /* Process unlocked */
854 __HAL_UNLOCK(hnand);
855
856 return HAL_OK;
857 }
858
859 /**
860 * @brief Write Page(s) to NAND memory block (16-bits addressing)
861 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
862 * the configuration information for NAND module.
863 * @param pAddress pointer to NAND address structure
864 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned
865 * @param NumPageToWrite number of pages to write to block
866 * @retval HAL status
867 */
HAL_NAND_Write_Page_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumPageToWrite)868 HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
869 {
870 __IO uint32_t index = 0;
871 uint32_t tickstart = 0;
872 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
873
874 /* Process Locked */
875 __HAL_LOCK(hnand);
876
877 /* Check the NAND controller state */
878 if (hnand->State == HAL_NAND_STATE_BUSY)
879 {
880 return HAL_BUSY;
881 }
882
883 /* Identify the device address */
884 deviceAddress = NAND_DEVICE;
885
886 /* Update the NAND controller state */
887 hnand->State = HAL_NAND_STATE_BUSY;
888
889 /* NAND raw address calculation */
890 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
891
892 /* Page(s) write loop */
893 while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
894 {
895 /* update the buffer size */
896 size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
897
898 /* Send write page command sequence */
899 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
900 __DSB();
901 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
902 __DSB();
903
904 /* Cards with page size <= 512 bytes */
905 if ((hnand->Config.PageSize) <= 512)
906 {
907 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
908 {
909 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
910 __DSB();
911 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
912 __DSB();
913 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
914 __DSB();
915 }
916 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
917 {
918 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
919 __DSB();
920 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
921 __DSB();
922 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
923 __DSB();
924 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
925 __DSB();
926 }
927 }
928 else /* (hnand->Config.PageSize) > 512 */
929 {
930 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
931 {
932 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
933 __DSB();
934 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
935 __DSB();
936 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
937 __DSB();
938 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
939 __DSB();
940 }
941 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
942 {
943 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
944 __DSB();
945 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
946 __DSB();
947 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
948 __DSB();
949 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
950 __DSB();
951 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
952 __DSB();
953 }
954 }
955
956 /* Write data to memory */
957 for(; index < size; index++)
958 {
959 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
960 __DSB();
961 }
962
963 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
964 __DSB();
965
966 /* Get tick */
967 tickstart = HAL_GetTick();
968
969 /* Read status until NAND is ready */
970 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
971 {
972 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
973 {
974 return HAL_TIMEOUT;
975 }
976 }
977
978 /* Increment written pages number */
979 numPagesWritten++;
980
981 /* Decrement pages to write */
982 NumPageToWrite--;
983
984 /* Increment the NAND address */
985 nandAddress = (uint32_t)(nandAddress + 1);
986 }
987
988 /* Update the NAND controller state */
989 hnand->State = HAL_NAND_STATE_READY;
990
991 /* Process unlocked */
992 __HAL_UNLOCK(hnand);
993
994 return HAL_OK;
995 }
996
997 /**
998 * @brief Read Spare area(s) from NAND memory (8-bits addressing)
999 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1000 * the configuration information for NAND module.
1001 * @param pAddress pointer to NAND address structure
1002 * @param pBuffer pointer to source buffer to write
1003 * @param NumSpareAreaToRead Number of spare area to read
1004 * @retval HAL status
1005 */
HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)1006 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
1007 {
1008 __IO uint32_t index = 0;
1009 uint32_t tickstart = 0U;
1010 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1011
1012 /* Process Locked */
1013 __HAL_LOCK(hnand);
1014
1015 /* Check the NAND controller state */
1016 if (hnand->State == HAL_NAND_STATE_BUSY)
1017 {
1018 return HAL_BUSY;
1019 }
1020
1021 /* Identify the device address */
1022 deviceAddress = NAND_DEVICE;
1023
1024 /* Update the NAND controller state */
1025 hnand->State = HAL_NAND_STATE_BUSY;
1026
1027 /* NAND raw address calculation */
1028 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1029
1030 /* Column in page address */
1031 columnAddress = COLUMN_ADDRESS(hnand);
1032
1033 /* Spare area(s) read loop */
1034 while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1035 {
1036 /* update the buffer size */
1037 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1038
1039 /* Cards with page size <= 512 bytes */
1040 if ((hnand->Config.PageSize) <= 512)
1041 {
1042 /* Send read spare area command sequence */
1043 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1044 __DSB();
1045
1046 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1047 {
1048 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1049 __DSB();
1050 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1051 __DSB();
1052 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1053 __DSB();
1054 }
1055 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1056 {
1057 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1058 __DSB();
1059 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1060 __DSB();
1061 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1062 __DSB();
1063 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1064 __DSB();
1065 }
1066 }
1067 else /* (hnand->Config.PageSize) > 512 */
1068 {
1069 /* Send read spare area command sequence */
1070 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1071 __DSB();
1072
1073 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1074 {
1075 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1076 __DSB();
1077 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
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 }
1084 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1085 {
1086 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1087 __DSB();
1088 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1089 __DSB();
1090 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1091 __DSB();
1092 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1093 __DSB();
1094 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1095 __DSB();
1096 }
1097 }
1098
1099 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1100 __DSB();
1101
1102 if (hnand->Config.ExtraCommandEnable == ENABLE)
1103 {
1104 /* Get tick */
1105 tickstart = HAL_GetTick();
1106
1107 /* Read status until NAND is ready */
1108 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1109 {
1110 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1111 {
1112 return HAL_TIMEOUT;
1113 }
1114 }
1115
1116 /* Go back to read mode */
1117 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
1118 __DSB();
1119 }
1120
1121 /* Get Data into Buffer */
1122 for (; index < size; index++)
1123 {
1124 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
1125 }
1126
1127 /* Increment read spare areas number */
1128 numSpareAreaRead++;
1129
1130 /* Decrement spare areas to read */
1131 NumSpareAreaToRead--;
1132
1133 /* Increment the NAND address */
1134 nandAddress = (uint32_t)(nandAddress + 1);
1135 }
1136
1137 /* Update the NAND controller state */
1138 hnand->State = HAL_NAND_STATE_READY;
1139
1140 /* Process unlocked */
1141 __HAL_UNLOCK(hnand);
1142
1143 return HAL_OK;
1144 }
1145
1146 /**
1147 * @brief Read Spare area(s) from NAND memory (16-bits addressing)
1148 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1149 * the configuration information for NAND module.
1150 * @param pAddress pointer to NAND address structure
1151 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1152 * @param NumSpareAreaToRead Number of spare area to read
1153 * @retval HAL status
1154 */
HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaToRead)1155 HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
1156 {
1157 __IO uint32_t index = 0;
1158 uint32_t tickstart = 0U;
1159 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
1160
1161 /* Process Locked */
1162 __HAL_LOCK(hnand);
1163
1164 /* Check the NAND controller state */
1165 if(hnand->State == HAL_NAND_STATE_BUSY)
1166 {
1167 return HAL_BUSY;
1168 }
1169
1170 /* Identify the device address */
1171 deviceAddress = NAND_DEVICE;
1172
1173 /* Update the NAND controller state */
1174 hnand->State = HAL_NAND_STATE_BUSY;
1175
1176 /* NAND raw address calculation */
1177 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1178
1179 /* Column in page address */
1180 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1181
1182 /* Spare area(s) read loop */
1183 while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1184 {
1185 /* update the buffer size */
1186 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
1187
1188 /* Cards with page size <= 512 bytes */
1189 if ((hnand->Config.PageSize) <= 512)
1190 {
1191 /* Send read spare area command sequence */
1192 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1193 __DSB();
1194
1195 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1196 {
1197 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1198 __DSB();
1199 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1200 __DSB();
1201 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1202 __DSB();
1203 }
1204 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1205 {
1206 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1207 __DSB();
1208 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1209 __DSB();
1210 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1211 __DSB();
1212 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1213 __DSB();
1214 }
1215 }
1216 else /* (hnand->Config.PageSize) > 512 */
1217 {
1218 /* Send read spare area command sequence */
1219 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1220 __DSB();
1221
1222 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1223 {
1224 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1225 __DSB();
1226 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1227 __DSB();
1228 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1229 __DSB();
1230 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1231 __DSB();
1232 }
1233 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1234 {
1235 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1236 __DSB();
1237 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1238 __DSB();
1239 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1240 __DSB();
1241 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1242 __DSB();
1243 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1244 __DSB();
1245 }
1246 }
1247
1248 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
1249 __DSB();
1250
1251 if (hnand->Config.ExtraCommandEnable == ENABLE)
1252 {
1253 /* Get tick */
1254 tickstart = HAL_GetTick();
1255
1256 /* Read status until NAND is ready */
1257 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1258 {
1259 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
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)0x00U);
1267 __DSB();
1268 }
1269
1270 /* Get Data into Buffer */
1271 for ( ;index < size; index++)
1272 {
1273 *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
1274 }
1275
1276 /* Increment read spare areas number */
1277 numSpareAreaRead++;
1278
1279 /* Decrement spare areas to read */
1280 NumSpareAreaToRead--;
1281
1282 /* Increment the NAND address */
1283 nandAddress = (uint32_t)(nandAddress + 1);
1284 }
1285
1286 /* Update the NAND controller state */
1287 hnand->State = HAL_NAND_STATE_READY;
1288
1289 /* Process unlocked */
1290 __HAL_UNLOCK(hnand);
1291
1292 return HAL_OK;
1293 }
1294
1295 /**
1296 * @brief Write Spare area(s) to NAND memory (8-bits addressing)
1297 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1298 * the configuration information for NAND module.
1299 * @param pAddress pointer to NAND address structure
1300 * @param pBuffer pointer to source buffer to write
1301 * @param NumSpareAreaTowrite number of spare areas to write to block
1302 * @retval HAL status
1303 */
HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)1304 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
1305 {
1306 __IO uint32_t index = 0;
1307 uint32_t tickstart = 0;
1308 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
1309
1310 /* Process Locked */
1311 __HAL_LOCK(hnand);
1312
1313 /* Check the NAND controller state */
1314 if(hnand->State == HAL_NAND_STATE_BUSY)
1315 {
1316 return HAL_BUSY;
1317 }
1318
1319 /* Identify the device address */
1320 deviceAddress = NAND_DEVICE;
1321
1322 /* Update the FMC_NAND controller state */
1323 hnand->State = HAL_NAND_STATE_BUSY;
1324
1325 /* Page address calculation */
1326 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1327
1328 /* Column in page address */
1329 columnAddress = COLUMN_ADDRESS(hnand);
1330
1331 /* Spare area(s) write loop */
1332 while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1333 {
1334 /* update the buffer size */
1335 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1336
1337 /* Cards with page size <= 512 bytes */
1338 if ((hnand->Config.PageSize) <= 512)
1339 {
1340 /* Send write Spare area command sequence */
1341 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1342 __DSB();
1343 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1344 __DSB();
1345
1346 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1347 {
1348 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1349 __DSB();
1350 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1351 __DSB();
1352 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1353 __DSB();
1354 }
1355 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1356 {
1357 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1358 __DSB();
1359 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1360 __DSB();
1361 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1362 __DSB();
1363 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1364 __DSB();
1365 }
1366 }
1367 else /* (hnand->Config.PageSize) > 512 */
1368 {
1369 /* Send write Spare area command sequence */
1370 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1371 __DSB();
1372 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1373 __DSB();
1374
1375 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1376 {
1377 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1378 __DSB();
1379 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1380 __DSB();
1381 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1382 __DSB();
1383 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1384 __DSB();
1385 }
1386 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1387 {
1388 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1389 __DSB();
1390 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1391 __DSB();
1392 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1393 __DSB();
1394 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1395 __DSB();
1396 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1397 __DSB();
1398 }
1399 }
1400
1401 /* Write data to memory */
1402 for(; index < size; index++)
1403 {
1404 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
1405 __DSB();
1406 }
1407
1408 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1409 __DSB();
1410
1411 /* Get tick */
1412 tickstart = HAL_GetTick();
1413
1414 /* Read status until NAND is ready */
1415 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
1416 {
1417 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
1418 {
1419 return HAL_TIMEOUT;
1420 }
1421 }
1422
1423 /* Increment written spare areas number */
1424 numSpareAreaWritten++;
1425
1426 /* Decrement spare areas to write */
1427 NumSpareAreaTowrite--;
1428
1429 /* Increment the NAND address */
1430 nandAddress = (uint32_t)(nandAddress + 1);
1431 }
1432
1433 /* Update the NAND controller state */
1434 hnand->State = HAL_NAND_STATE_READY;
1435
1436 /* Process unlocked */
1437 __HAL_UNLOCK(hnand);
1438
1439 return HAL_OK;
1440 }
1441
1442 /**
1443 * @brief Write Spare area(s) to NAND memory (16-bits addressing)
1444 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1445 * the configuration information for NAND module.
1446 * @param pAddress pointer to NAND address structure
1447 * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned.
1448 * @param NumSpareAreaTowrite number of spare areas to write to block
1449 * @retval HAL status
1450 */
HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint16_t * pBuffer,uint32_t NumSpareAreaTowrite)1451 HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
1452 {
1453 __IO uint32_t index = 0;
1454 uint32_t tickstart = 0;
1455 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
1456
1457 /* Process Locked */
1458 __HAL_LOCK(hnand);
1459
1460 /* Check the NAND controller state */
1461 if (hnand->State == HAL_NAND_STATE_BUSY)
1462 {
1463 return HAL_BUSY;
1464 }
1465
1466 /* Identify the device address */
1467 deviceAddress = NAND_DEVICE;
1468
1469 /* Update the FMC_NAND controller state */
1470 hnand->State = HAL_NAND_STATE_BUSY;
1471
1472 /* NAND raw address calculation */
1473 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
1474
1475 /* Column in page address */
1476 columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
1477
1478 /* Spare area(s) write loop */
1479 while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
1480 {
1481 /* update the buffer size */
1482 size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
1483
1484 /* Cards with page size <= 512 bytes */
1485 if ((hnand->Config.PageSize) <= 512)
1486 {
1487 /* Send write Spare area command sequence */
1488 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
1489 __DSB();
1490 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1491 __DSB();
1492
1493 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1494 {
1495 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1496 __DSB();
1497 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1498 __DSB();
1499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1500 __DSB();
1501 }
1502 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1503 {
1504 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
1505 __DSB();
1506 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1507 __DSB();
1508 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1509 __DSB();
1510 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1511 __DSB();
1512 }
1513 }
1514 else /* (hnand->Config.PageSize) > 512 */
1515 {
1516 /* Send write Spare area command sequence */
1517 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
1518 __DSB();
1519 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
1520 __DSB();
1521
1522 if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535)
1523 {
1524 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1525 __DSB();
1526 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1527 __DSB();
1528 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1529 __DSB();
1530 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1531 __DSB();
1532 }
1533 else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
1534 {
1535 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
1536 __DSB();
1537 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
1538 __DSB();
1539 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
1540 __DSB();
1541 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
1542 __DSB();
1543 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
1544 __DSB();
1545 }
1546 }
1547
1548 /* Write data to memory */
1549 for (; index < size; index++)
1550 {
1551 *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
1552 __DSB();
1553 }
1554
1555 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
1556 __DSB();
1557
1558 /* Get tick */
1559 tickstart = HAL_GetTick();
1560
1561 /* Read status until NAND is ready */
1562 while (HAL_NAND_Read_Status(hnand) != NAND_READY)
1563 {
1564 if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT)
1565 {
1566 return HAL_TIMEOUT;
1567 }
1568 }
1569
1570 /* Increment written spare areas number */
1571 numSpareAreaWritten++;
1572
1573 /* Decrement spare areas to write */
1574 NumSpareAreaTowrite--;
1575
1576 /* Increment the NAND address */
1577 nandAddress = (uint32_t)(nandAddress + 1);
1578 }
1579
1580 /* Update the NAND controller state */
1581 hnand->State = HAL_NAND_STATE_READY;
1582
1583 /* Process unlocked */
1584 __HAL_UNLOCK(hnand);
1585
1586 return HAL_OK;
1587 }
1588
1589 /**
1590 * @brief NAND memory Block erase
1591 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1592 * the configuration information for NAND module.
1593 * @param pAddress pointer to NAND address structure
1594 * @retval HAL status
1595 */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1596 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1597 {
1598 uint32_t DeviceAddress = 0;
1599
1600 /* Process Locked */
1601 __HAL_LOCK(hnand);
1602
1603 /* Check the NAND controller state */
1604 if(hnand->State == HAL_NAND_STATE_BUSY)
1605 {
1606 return HAL_BUSY;
1607 }
1608
1609 /* Identify the device address */
1610 DeviceAddress = NAND_DEVICE;
1611
1612 /* Update the NAND controller state */
1613 hnand->State = HAL_NAND_STATE_BUSY;
1614
1615 /* Send Erase block command sequence */
1616 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
1617 __DSB();
1618 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1619 __DSB();
1620 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1621 __DSB();
1622 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
1623 __DSB();
1624
1625 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
1626 __DSB();
1627
1628 /* Update the NAND controller state */
1629 hnand->State = HAL_NAND_STATE_READY;
1630
1631 /* Process unlocked */
1632 __HAL_UNLOCK(hnand);
1633
1634 return HAL_OK;
1635 }
1636
1637 /**
1638 * @brief Increment the NAND memory address
1639 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1640 * the configuration information for NAND module.
1641 * @param pAddress pointer to NAND address structure
1642 * @retval The new status of the increment address operation. It can be:
1643 * - NAND_VALID_ADDRESS: When the new address is valid address
1644 * - NAND_INVALID_ADDRESS: When the new address is invalid address
1645 */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)1646 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
1647 {
1648 uint32_t status = NAND_VALID_ADDRESS;
1649
1650 /* Increment page address */
1651 pAddress->Page++;
1652
1653 /* Check NAND address is valid */
1654 if (pAddress->Page == hnand->Config.BlockSize)
1655 {
1656 pAddress->Page = 0;
1657 pAddress->Block++;
1658
1659 if (pAddress->Block == hnand->Config.PlaneSize)
1660 {
1661 pAddress->Block = 0;
1662 pAddress->Plane++;
1663
1664 if (pAddress->Plane == (hnand->Config.PlaneNbr))
1665 {
1666 status = NAND_INVALID_ADDRESS;
1667 }
1668 }
1669 }
1670
1671 return (status);
1672 }
1673 /**
1674 * @}
1675 */
1676
1677 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
1678 * @brief management functions
1679 *
1680 @verbatim
1681 ==============================================================================
1682 ##### NAND Control functions #####
1683 ==============================================================================
1684 [..]
1685 This subsection provides a set of functions allowing to control dynamically
1686 the NAND interface.
1687
1688 @endverbatim
1689 * @{
1690 */
1691
1692
1693 /**
1694 * @brief Enable dynamically NAND ECC feature.
1695 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1696 * the configuration information for NAND module.
1697 * @retval HAL status
1698 */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)1699 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
1700 {
1701 /* Check the NAND controller state */
1702 if(hnand->State == HAL_NAND_STATE_BUSY)
1703 {
1704 return HAL_BUSY;
1705 }
1706
1707 /* Update the NAND state */
1708 hnand->State = HAL_NAND_STATE_BUSY;
1709
1710 /* Enable ECC feature */
1711 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1712
1713 /* Update the NAND state */
1714 hnand->State = HAL_NAND_STATE_READY;
1715
1716 return HAL_OK;
1717 }
1718
1719 /**
1720 * @brief Disable dynamically NAND ECC feature
1721 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1722 * the configuration information for NAND module.
1723 * @retval HAL status
1724 */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)1725 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
1726 {
1727 /* Check the NAND controller state */
1728 if(hnand->State == HAL_NAND_STATE_BUSY)
1729 {
1730 return HAL_BUSY;
1731 }
1732
1733 /* Update the NAND state */
1734 hnand->State = HAL_NAND_STATE_BUSY;
1735
1736 /* Disable ECC feature */
1737 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1738
1739 /* Update the NAND state */
1740 hnand->State = HAL_NAND_STATE_READY;
1741
1742 return HAL_OK;
1743 }
1744
1745 /**
1746 * @brief Get NAND ECC value
1747 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1748 * the configuration information for NAND module.
1749 * @param ECCval pointer to ECC value
1750 * @param Timeout maximum timeout to wait
1751 * @retval HAL status
1752 */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)1753 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1754 {
1755 HAL_StatusTypeDef status = HAL_OK;
1756
1757 /* Check the NAND controller state */
1758 if(hnand->State == HAL_NAND_STATE_BUSY)
1759 {
1760 return HAL_BUSY;
1761 }
1762
1763 /* Update the NAND state */
1764 hnand->State = HAL_NAND_STATE_BUSY;
1765
1766 /* Get NAND ECC value */
1767 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1768
1769 /* Update the NAND state */
1770 hnand->State = HAL_NAND_STATE_READY;
1771
1772 return status;
1773 }
1774
1775 /**
1776 * @}
1777 */
1778
1779
1780 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1781 * @brief Peripheral State functions
1782 *
1783 @verbatim
1784 ==============================================================================
1785 ##### NAND State functions #####
1786 ==============================================================================
1787 [..]
1788 This subsection permits to get in run-time the status of the NAND controller
1789 and the data flow.
1790
1791 @endverbatim
1792 * @{
1793 */
1794
1795 /**
1796 * @brief Return the NAND state
1797 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1798 * the configuration information for NAND module.
1799 * @retval HAL state
1800 */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)1801 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1802 {
1803 /* Return NAND handle state */
1804 return hnand->State;
1805 }
1806
1807 /**
1808 * @brief NAND memory read status
1809 * @param hnand pointer to a NAND_HandleTypeDef structure that contains
1810 * the configuration information for NAND module.
1811 * @retval NAND status
1812 */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)1813 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
1814 {
1815 uint32_t data = 0;
1816 uint32_t DeviceAddress = 0;
1817
1818 /* Identify the device address */
1819 DeviceAddress = NAND_DEVICE;
1820
1821 /* Send Read status operation command */
1822 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
1823
1824 /* Read status register data */
1825 data = *(__IO uint8_t *)DeviceAddress;
1826
1827 /* Return the status */
1828 if ((data & NAND_ERROR) == NAND_ERROR)
1829 {
1830 return NAND_ERROR;
1831 }
1832 else if ((data & NAND_READY) == NAND_READY)
1833 {
1834 return NAND_READY;
1835 }
1836
1837 return NAND_BUSY;
1838 }
1839
1840 /**
1841 * @}
1842 */
1843
1844 /**
1845 * @}
1846 */
1847
1848 /**
1849 * @}
1850 */
1851
1852 #endif /* HAL_NAND_MODULE_ENABLED */
1853
1854 /**
1855 * @}
1856 */
1857
1858 #endif /* FMC_BANK3 */
1859
1860 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1861