1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_nand.c
4 * @author MCD Application Team
5 * @version V1.0.1
6 * @date 25-June-2015
7 * @brief NAND HAL module driver.
8 * This file provides a generic firmware to drive NAND memories mounted
9 * as external device.
10 *
11 @verbatim
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
15 [..]
16 This driver is a generic layered driver which contains a set of APIs used to
17 control NAND flash memories. It uses the FMC/FSMC layer functions to interface
18 with NAND devices. This driver is used as follows:
19
20 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
21 with control and timing parameters for both common and attribute spaces.
22
23 (+) Read NAND flash memory maker and device IDs using the function
24 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
25 structure declared by the function caller.
26
27 (+) Access NAND flash memory by read/write operations using the functions
28 HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
29 to read/write page(s)/spare area(s). These functions use specific device
30 information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
31 structure. The read/write address information is contained by the Nand_Address_Typedef
32 structure passed as parameter.
33
34 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
35
36 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
37 The erase block address information is contained in the Nand_Address_Typedef
38 structure passed as parameter.
39
40 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
41
42 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
43 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
44 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
45
46 (+) You can monitor the NAND device HAL state by calling the function
47 HAL_NAND_GetState()
48
49 [..]
50 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
51 If a NAND flash device contains different operations and/or implementations,
52 it should be implemented separately.
53
54 @endverbatim
55 ******************************************************************************
56 * @attention
57 *
58 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
59 *
60 * Redistribution and use in source and binary forms, with or without modification,
61 * are permitted provided that the following conditions are met:
62 * 1. Redistributions of source code must retain the above copyright notice,
63 * this list of conditions and the following disclaimer.
64 * 2. Redistributions in binary form must reproduce the above copyright notice,
65 * this list of conditions and the following disclaimer in the documentation
66 * and/or other materials provided with the distribution.
67 * 3. Neither the name of STMicroelectronics nor the names of its contributors
68 * may be used to endorse or promote products derived from this software
69 * without specific prior written permission.
70 *
71 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
72 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
73 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
75 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
76 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
78 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
79 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81 *
82 ******************************************************************************
83 */
84
85 /* Includes ------------------------------------------------------------------*/
86 #include "stm32f7xx_hal.h"
87
88 /** @addtogroup STM32F7xx_HAL_Driver
89 * @{
90 */
91
92
93 #ifdef HAL_NAND_MODULE_ENABLED
94
95 /** @defgroup NAND NAND
96 * @brief NAND HAL module driver
97 * @{
98 */
99
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private Constants ------------------------------------------------------------*/
102 /* Private macro -------------------------------------------------------------*/
103 /* Private variables ---------------------------------------------------------*/
104 /* Private function prototypes -----------------------------------------------*/
105 /* Exported functions ---------------------------------------------------------*/
106
107 /** @defgroup NAND_Exported_Functions NAND Exported Functions
108 * @{
109 */
110
111 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
112 * @brief Initialization and Configuration functions
113 *
114 @verbatim
115 ==============================================================================
116 ##### NAND Initialization and de-initialization functions #####
117 ==============================================================================
118 [..]
119 This section provides functions allowing to initialize/de-initialize
120 the NAND memory
121
122 @endverbatim
123 * @{
124 */
125
126 /**
127 * @brief Perform NAND memory Initialization sequence
128 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
129 * the configuration information for NAND module.
130 * @param ComSpace_Timing: pointer to Common space timing structure
131 * @param AttSpace_Timing: pointer to Attribute space timing structure
132 * @retval HAL status
133 */
HAL_NAND_Init(NAND_HandleTypeDef * hnand,FMC_NAND_PCC_TimingTypeDef * ComSpace_Timing,FMC_NAND_PCC_TimingTypeDef * AttSpace_Timing)134 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
135 {
136 /* Check the NAND handle state */
137 if (hnand == NULL) {
138 return HAL_ERROR;
139 }
140
141 if (hnand->State == HAL_NAND_STATE_RESET) {
142 /* Allocate lock resource and initialize it */
143 hnand->Lock = HAL_UNLOCKED;
144 /* Initialize the low level hardware (MSP) */
145 HAL_NAND_MspInit(hnand);
146 }
147
148 /* Initialize NAND control Interface */
149 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
150
151 /* Initialize NAND common space timing Interface */
152 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
153
154 /* Initialize NAND attribute space timing Interface */
155 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
156
157 /* Enable the NAND device */
158 __FMC_NAND_ENABLE(hnand->Instance);
159
160 /* Update the NAND controller state */
161 hnand->State = HAL_NAND_STATE_READY;
162
163 return HAL_OK;
164 }
165
166 /**
167 * @brief Perform NAND memory De-Initialization sequence
168 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
169 * the configuration information for NAND module.
170 * @retval HAL status
171 */
HAL_NAND_DeInit(NAND_HandleTypeDef * hnand)172 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
173 {
174 /* Initialize the low level hardware (MSP) */
175 HAL_NAND_MspDeInit(hnand);
176
177 /* Configure the NAND registers with their reset values */
178 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
179
180 /* Reset the NAND controller state */
181 hnand->State = HAL_NAND_STATE_RESET;
182
183 /* Release Lock */
184 __HAL_UNLOCK(hnand);
185
186 return HAL_OK;
187 }
188
189 /**
190 * @brief NAND MSP Init
191 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
192 * the configuration information for NAND module.
193 * @retval None
194 */
HAL_NAND_MspInit(NAND_HandleTypeDef * hnand)195 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
196 {
197 /* NOTE : This function Should not be modified, when the callback is needed,
198 the HAL_NAND_MspInit could be implemented in the user file
199 */
200 }
201
202 /**
203 * @brief NAND MSP DeInit
204 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
205 * the configuration information for NAND module.
206 * @retval None
207 */
HAL_NAND_MspDeInit(NAND_HandleTypeDef * hnand)208 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
209 {
210 /* NOTE : This function Should not be modified, when the callback is needed,
211 the HAL_NAND_MspDeInit could be implemented in the user file
212 */
213 }
214
215
216 /**
217 * @brief This function handles NAND device interrupt request.
218 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
219 * the configuration information for NAND module.
220 * @retval HAL status
221 */
HAL_NAND_IRQHandler(NAND_HandleTypeDef * hnand)222 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
223 {
224 /* Check NAND interrupt Rising edge flag */
225 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE)) {
226 /* NAND interrupt callback*/
227 HAL_NAND_ITCallback(hnand);
228
229 /* Clear NAND interrupt Rising edge pending bit */
230 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
231 }
232
233 /* Check NAND interrupt Level flag */
234 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL)) {
235 /* NAND interrupt callback*/
236 HAL_NAND_ITCallback(hnand);
237
238 /* Clear NAND interrupt Level pending bit */
239 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
240 }
241
242 /* Check NAND interrupt Falling edge flag */
243 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE)) {
244 /* NAND interrupt callback*/
245 HAL_NAND_ITCallback(hnand);
246
247 /* Clear NAND interrupt Falling edge pending bit */
248 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
249 }
250
251 /* Check NAND interrupt FIFO empty flag */
252 if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT)) {
253 /* NAND interrupt callback*/
254 HAL_NAND_ITCallback(hnand);
255
256 /* Clear NAND interrupt FIFO empty pending bit */
257 __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
258 }
259
260 }
261
262 /**
263 * @brief NAND interrupt feature callback
264 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
265 * the configuration information for NAND module.
266 * @retval None
267 */
HAL_NAND_ITCallback(NAND_HandleTypeDef * hnand)268 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
269 {
270 /* NOTE : This function Should not be modified, when the callback is needed,
271 the HAL_NAND_ITCallback could be implemented in the user file
272 */
273 }
274
275 /**
276 * @}
277 */
278
279 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
280 * @brief Input Output and memory control functions
281 *
282 @verbatim
283 ==============================================================================
284 ##### NAND Input and Output functions #####
285 ==============================================================================
286 [..]
287 This section provides functions allowing to use and control the NAND
288 memory
289
290 @endverbatim
291 * @{
292 */
293
294 /**
295 * @brief Read the NAND memory electronic signature
296 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
297 * the configuration information for NAND module.
298 * @param pNAND_ID: NAND ID structure
299 * @retval HAL status
300 */
HAL_NAND_Read_ID(NAND_HandleTypeDef * hnand,NAND_IDTypeDef * pNAND_ID)301 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
302 {
303 __IO uint32_t data = 0;
304 uint32_t deviceAddress = 0;
305
306 /* Process Locked */
307 __HAL_LOCK(hnand);
308
309 /* Check the NAND controller state */
310 if (hnand->State == HAL_NAND_STATE_BUSY) {
311 return HAL_BUSY;
312 }
313
314 /* Identify the device address */
315 deviceAddress = NAND_DEVICE;
316
317 /* Update the NAND controller state */
318 hnand->State = HAL_NAND_STATE_BUSY;
319
320 /* Send Read ID command sequence */
321 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
322 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
323
324 /* Read the electronic signature from NAND flash */
325 data = *(__IO uint32_t *)deviceAddress;
326
327 /* Return the data read */
328 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
329 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
330 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
331 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
332
333 /* Update the NAND controller state */
334 hnand->State = HAL_NAND_STATE_READY;
335
336 /* Process unlocked */
337 __HAL_UNLOCK(hnand);
338
339 return HAL_OK;
340 }
341
342 /**
343 * @brief NAND memory reset
344 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
345 * the configuration information for NAND module.
346 * @retval HAL status
347 */
HAL_NAND_Reset(NAND_HandleTypeDef * hnand)348 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
349 {
350 uint32_t deviceAddress = 0;
351
352 /* Process Locked */
353 __HAL_LOCK(hnand);
354
355 /* Check the NAND controller state */
356 if (hnand->State == HAL_NAND_STATE_BUSY) {
357 return HAL_BUSY;
358 }
359
360 /* Identify the device address */
361 deviceAddress = NAND_DEVICE;
362
363 /* Update the NAND controller state */
364 hnand->State = HAL_NAND_STATE_BUSY;
365
366 /* Send NAND reset command */
367 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
368
369
370 /* Update the NAND controller state */
371 hnand->State = HAL_NAND_STATE_READY;
372
373 /* Process unlocked */
374 __HAL_UNLOCK(hnand);
375
376 return HAL_OK;
377
378 }
379
380 /**
381 * @brief Read Page(s) from NAND memory block
382 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
383 * the configuration information for NAND module.
384 * @param pAddress : pointer to NAND address structure
385 * @param pBuffer : pointer to destination read buffer
386 * @param NumPageToRead : number of pages to read from block
387 * @retval HAL status
388 */
HAL_NAND_Read_Page(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToRead)389 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
390 {
391 __IO uint32_t index = 0;
392 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
393
394 /* Process Locked */
395 __HAL_LOCK(hnand);
396
397 /* Check the NAND controller state */
398 if (hnand->State == HAL_NAND_STATE_BUSY) {
399 return HAL_BUSY;
400 }
401
402 /* Identify the device address */
403 deviceAddress = NAND_DEVICE;
404
405 /* Update the NAND controller state */
406 hnand->State = HAL_NAND_STATE_BUSY;
407
408 /* NAND raw address calculation */
409 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
410
411 /* Page(s) read loop */
412 while ((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize)))) {
413 /* update the buffer size */
414 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
415
416 /* Send read page command sequence */
417 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
418
419 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
420 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
421 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
422 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
423
424 /* for 512 and 1 GB devices, 4th cycle is required */
425 if (hnand->Info.BlockNbr >= 1024) {
426 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
427 }
428
429 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
430
431 /* Get Data into Buffer */
432 for (index = 0; index < size; index++) {
433 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
434 }
435
436 /* Increment read pages number */
437 numPagesRead++;
438
439 /* Decrement pages to read */
440 NumPageToRead--;
441
442 /* Increment the NAND address */
443 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
444
445 }
446
447 /* Update the NAND controller state */
448 hnand->State = HAL_NAND_STATE_READY;
449
450 /* Process unlocked */
451 __HAL_UNLOCK(hnand);
452
453 return HAL_OK;
454
455 }
456
457 /**
458 * @brief Write Page(s) to NAND memory block
459 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
460 * the configuration information for NAND module.
461 * @param pAddress : pointer to NAND address structure
462 * @param pBuffer : pointer to source buffer to write
463 * @param NumPageToWrite : number of pages to write to block
464 * @retval HAL status
465 */
HAL_NAND_Write_Page(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumPageToWrite)466 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
467 {
468 __IO uint32_t index = 0;
469 uint32_t tickstart = 0;
470 uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
471
472 /* Process Locked */
473 __HAL_LOCK(hnand);
474
475 /* Check the NAND controller state */
476 if (hnand->State == HAL_NAND_STATE_BUSY) {
477 return HAL_BUSY;
478 }
479
480 /* Identify the device address */
481 deviceAddress = NAND_DEVICE;
482
483 /* Update the NAND controller state */
484 hnand->State = HAL_NAND_STATE_BUSY;
485
486 /* NAND raw address calculation */
487 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
488
489 /* Page(s) write loop */
490 while ((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize)))) {
491 /* update the buffer size */
492 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
493
494 /* Send write page command sequence */
495 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
496 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
497
498 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
499 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
500 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
501 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
502 __DSB();
503
504 /* for 512 and 1 GB devices, 4th cycle is required */
505 if (hnand->Info.BlockNbr >= 1024) {
506 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
507 __DSB();
508 }
509
510 /* Write data to memory */
511 for (index = 0; index < size; index++) {
512 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
513 __DSB();
514 }
515
516 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
517
518 /* Read status until NAND is ready */
519 while (HAL_NAND_Read_Status(hnand) != NAND_READY) {
520 /* Get tick */
521 tickstart = HAL_GetTick();
522
523 if ((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) {
524 return HAL_TIMEOUT;
525 }
526 }
527
528 /* Increment written pages number */
529 numPagesWritten++;
530
531 /* Decrement pages to write */
532 NumPageToWrite--;
533
534 /* Increment the NAND address */
535 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
536 }
537
538 /* Update the NAND controller state */
539 hnand->State = HAL_NAND_STATE_READY;
540
541 /* Process unlocked */
542 __HAL_UNLOCK(hnand);
543
544 return HAL_OK;
545 }
546
547 /**
548 * @brief Read Spare area(s) from NAND memory
549 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
550 * the configuration information for NAND module.
551 * @param pAddress : pointer to NAND address structure
552 * @param pBuffer: pointer to source buffer to write
553 * @param NumSpareAreaToRead: Number of spare area to read
554 * @retval HAL status
555 */
HAL_NAND_Read_SpareArea(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaToRead)556 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
557 {
558 __IO uint32_t index = 0;
559 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
560
561 /* Process Locked */
562 __HAL_LOCK(hnand);
563
564 /* Check the NAND controller state */
565 if (hnand->State == HAL_NAND_STATE_BUSY) {
566 return HAL_BUSY;
567 }
568
569 /* Identify the device address */
570 deviceAddress = NAND_DEVICE;
571
572 /* Update the NAND controller state */
573 hnand->State = HAL_NAND_STATE_BUSY;
574
575 /* NAND raw address calculation */
576 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
577
578 /* Spare area(s) read loop */
579 while ((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize)))) {
580
581 /* update the buffer size */
582 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
583
584 /* Send read spare area command sequence */
585 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
586
587 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
588 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
589 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
590 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
591
592 /* for 512 and 1 GB devices, 4th cycle is required */
593 if (hnand->Info.BlockNbr >= 1024) {
594 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
595 }
596
597 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
598
599 /* Get Data into Buffer */
600 for (index = 0; index < size; index++) {
601 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
602 }
603
604 /* Increment read spare areas number */
605 numSpareAreaRead++;
606
607 /* Decrement spare areas to read */
608 NumSpareAreaToRead--;
609
610 /* Increment the NAND address */
611 nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
612 }
613
614 /* Update the NAND controller state */
615 hnand->State = HAL_NAND_STATE_READY;
616
617 /* Process unlocked */
618 __HAL_UNLOCK(hnand);
619
620 return HAL_OK;
621 }
622
623 /**
624 * @brief Write Spare area(s) to NAND memory
625 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
626 * the configuration information for NAND module.
627 * @param pAddress : pointer to NAND address structure
628 * @param pBuffer : pointer to source buffer to write
629 * @param NumSpareAreaTowrite : number of spare areas to write to block
630 * @retval HAL status
631 */
HAL_NAND_Write_SpareArea(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress,uint8_t * pBuffer,uint32_t NumSpareAreaTowrite)632 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
633 {
634 __IO uint32_t index = 0;
635 uint32_t tickstart = 0;
636 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
637
638 /* Process Locked */
639 __HAL_LOCK(hnand);
640
641 /* Check the NAND controller state */
642 if (hnand->State == HAL_NAND_STATE_BUSY) {
643 return HAL_BUSY;
644 }
645
646 /* Identify the device address */
647 deviceAddress = NAND_DEVICE;
648
649 /* Update the FMC_NAND controller state */
650 hnand->State = HAL_NAND_STATE_BUSY;
651
652 /* NAND raw address calculation */
653 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
654
655 /* Spare area(s) write loop */
656 while ((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize)))) {
657 /* update the buffer size */
658 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
659
660 /* Send write Spare area command sequence */
661 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
662 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
663
664 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
665 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
666 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
667 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
668 __DSB();
669 /* for 512 and 1 GB devices, 4th cycle is required */
670 if (hnand->Info.BlockNbr >= 1024) {
671 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
672 __DSB();
673 }
674
675 /* Write data to memory */
676 for (index = 0; index < size; index++) {
677 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
678 __DSB();
679 }
680
681 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
682 __DSB();
683
684 /* Read status until NAND is ready */
685 while (HAL_NAND_Read_Status(hnand) != NAND_READY) {
686 /* Get tick */
687 tickstart = HAL_GetTick();
688
689 if ((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) {
690 return HAL_TIMEOUT;
691 }
692 }
693
694 /* Increment written spare areas number */
695 numSpareAreaWritten++;
696
697 /* Decrement spare areas to write */
698 NumSpareAreaTowrite--;
699
700 /* Increment the NAND address */
701 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));
702 }
703
704 /* Update the NAND controller state */
705 hnand->State = HAL_NAND_STATE_READY;
706
707 /* Process unlocked */
708 __HAL_UNLOCK(hnand);
709
710 return HAL_OK;
711 }
712
713 /**
714 * @brief NAND memory Block erase
715 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
716 * the configuration information for NAND module.
717 * @param pAddress : pointer to NAND address structure
718 * @retval HAL status
719 */
HAL_NAND_Erase_Block(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)720 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
721 {
722 uint32_t DeviceAddress = 0;
723
724 /* Process Locked */
725 __HAL_LOCK(hnand);
726
727 /* Check the NAND controller state */
728 if (hnand->State == HAL_NAND_STATE_BUSY) {
729 return HAL_BUSY;
730 }
731
732 /* Identify the device address */
733 DeviceAddress = NAND_DEVICE;
734
735 /* Update the NAND controller state */
736 hnand->State = HAL_NAND_STATE_BUSY;
737
738 /* Send Erase block command sequence */
739 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
740
741 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
742 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
743 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
744 __DSB();
745
746 /* for 512 and 1 GB devices, 4th cycle is required */
747 if (hnand->Info.BlockNbr >= 1024) {
748 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
749 __DSB();
750 }
751
752 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
753 __DSB();
754
755 /* Update the NAND controller state */
756 hnand->State = HAL_NAND_STATE_READY;
757
758 /* Process unlocked */
759 __HAL_UNLOCK(hnand);
760
761 return HAL_OK;
762 }
763
764 /**
765 * @brief NAND memory read status
766 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
767 * the configuration information for NAND module.
768 * @retval NAND status
769 */
HAL_NAND_Read_Status(NAND_HandleTypeDef * hnand)770 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
771 {
772 uint32_t data = 0;
773 uint32_t DeviceAddress = 0;
774
775 /* Identify the device address */
776 DeviceAddress = NAND_DEVICE;
777
778 /* Send Read status operation command */
779 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
780
781 /* Read status register data */
782 data = *(__IO uint8_t *)DeviceAddress;
783
784 /* Return the status */
785 if ((data & NAND_ERROR) == NAND_ERROR) {
786 return NAND_ERROR;
787 } else if ((data & NAND_READY) == NAND_READY) {
788 return NAND_READY;
789 }
790
791 return NAND_BUSY;
792 }
793
794 /**
795 * @brief Increment the NAND memory address
796 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
797 * the configuration information for NAND module.
798 * @param pAddress: pointer to NAND address structure
799 * @retval The new status of the increment address operation. It can be:
800 * - NAND_VALID_ADDRESS: When the new address is valid address
801 * - NAND_INVALID_ADDRESS: When the new address is invalid address
802 */
HAL_NAND_Address_Inc(NAND_HandleTypeDef * hnand,NAND_AddressTypeDef * pAddress)803 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
804 {
805 uint32_t status = NAND_VALID_ADDRESS;
806
807 /* Increment page address */
808 pAddress->Page++;
809
810 /* Check NAND address is valid */
811 if (pAddress->Page == hnand->Info.BlockSize) {
812 pAddress->Page = 0;
813 pAddress->Block++;
814
815 if (pAddress->Block == hnand->Info.ZoneSize) {
816 pAddress->Block = 0;
817 pAddress->Zone++;
818
819 if (pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr)) {
820 status = NAND_INVALID_ADDRESS;
821 }
822 }
823 }
824
825 return (status);
826 }
827 /**
828 * @}
829 */
830
831 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
832 * @brief management functions
833 *
834 @verbatim
835 ==============================================================================
836 ##### NAND Control functions #####
837 ==============================================================================
838 [..]
839 This subsection provides a set of functions allowing to control dynamically
840 the NAND interface.
841
842 @endverbatim
843 * @{
844 */
845
846
847 /**
848 * @brief Enables dynamically NAND ECC feature.
849 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
850 * the configuration information for NAND module.
851 * @retval HAL status
852 */
HAL_NAND_ECC_Enable(NAND_HandleTypeDef * hnand)853 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
854 {
855 /* Check the NAND controller state */
856 if (hnand->State == HAL_NAND_STATE_BUSY) {
857 return HAL_BUSY;
858 }
859
860 /* Update the NAND state */
861 hnand->State = HAL_NAND_STATE_BUSY;
862
863 /* Enable ECC feature */
864 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
865
866 /* Update the NAND state */
867 hnand->State = HAL_NAND_STATE_READY;
868
869 return HAL_OK;
870 }
871
872 /**
873 * @brief Disables dynamically FMC_NAND ECC feature.
874 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
875 * the configuration information for NAND module.
876 * @retval HAL status
877 */
HAL_NAND_ECC_Disable(NAND_HandleTypeDef * hnand)878 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
879 {
880 /* Check the NAND controller state */
881 if (hnand->State == HAL_NAND_STATE_BUSY) {
882 return HAL_BUSY;
883 }
884
885 /* Update the NAND state */
886 hnand->State = HAL_NAND_STATE_BUSY;
887
888 /* Disable ECC feature */
889 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
890
891 /* Update the NAND state */
892 hnand->State = HAL_NAND_STATE_READY;
893
894 return HAL_OK;
895 }
896
897 /**
898 * @brief Disables dynamically NAND ECC feature.
899 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
900 * the configuration information for NAND module.
901 * @param ECCval: pointer to ECC value
902 * @param Timeout: maximum timeout to wait
903 * @retval HAL status
904 */
HAL_NAND_GetECC(NAND_HandleTypeDef * hnand,uint32_t * ECCval,uint32_t Timeout)905 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
906 {
907 HAL_StatusTypeDef status = HAL_OK;
908
909 /* Check the NAND controller state */
910 if (hnand->State == HAL_NAND_STATE_BUSY) {
911 return HAL_BUSY;
912 }
913
914 /* Update the NAND state */
915 hnand->State = HAL_NAND_STATE_BUSY;
916
917 /* Get NAND ECC value */
918 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
919
920 /* Update the NAND state */
921 hnand->State = HAL_NAND_STATE_READY;
922
923 return status;
924 }
925
926 /**
927 * @}
928 */
929
930
931 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
932 * @brief Peripheral State functions
933 *
934 @verbatim
935 ==============================================================================
936 ##### NAND State functions #####
937 ==============================================================================
938 [..]
939 This subsection permits to get in run-time the status of the NAND controller
940 and the data flow.
941
942 @endverbatim
943 * @{
944 */
945
946 /**
947 * @brief return the NAND state
948 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
949 * the configuration information for NAND module.
950 * @retval HAL state
951 */
HAL_NAND_GetState(NAND_HandleTypeDef * hnand)952 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
953 {
954 return hnand->State;
955 }
956
957 /**
958 * @}
959 */
960
961 /**
962 * @}
963 */
964
965 #endif /* HAL_NAND_MODULE_ENABLED */
966
967 /**
968 * @}
969 */
970
971 /**
972 * @}
973 */
974
975 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
976