source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

File size: 34.4 KB
Line 
1/**
2 ******************************************************************************
3 * @file stm32f4xx_hal_nand.c
4 * @author MCD Application Team
5 * @version V1.4.1
6 * @date 09-October-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>&copy; 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 "stm32f4xx_hal.h"
87
88/** @addtogroup STM32F4xx_HAL_Driver
89 * @{
90 */
91
92
93#ifdef HAL_NAND_MODULE_ENABLED
94
95#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
96 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
97 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
98
99/** @defgroup NAND NAND
100 * @brief NAND HAL module driver
101 * @{
102 */
103
104/* Private typedef -----------------------------------------------------------*/
105/* Private define ------------------------------------------------------------*/
106/** @defgroup NAND_Private_Constants NAND Private Constants
107 * @{
108 */
109
110/**
111 * @}
112 */
113
114/* Private macro -------------------------------------------------------------*/
115/** @defgroup NAND_Private_Macros NAND Private Macros
116 * @{
117 */
118
119/**
120 * @}
121 */
122/* Private variables ---------------------------------------------------------*/
123/* Private function prototypes -----------------------------------------------*/
124/* Exported functions --------------------------------------------------------*/
125/** @defgroup NAND_Exported_Functions NAND Exported Functions
126 * @{
127 */
128
129/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
130 * @brief Initialization and Configuration functions
131 *
132 @verbatim
133 ==============================================================================
134 ##### NAND Initialization and de-initialization functions #####
135 ==============================================================================
136 [..]
137 This section provides functions allowing to initialize/de-initialize
138 the NAND memory
139
140@endverbatim
141 * @{
142 */
143
144/**
145 * @brief Perform NAND memory Initialization sequence
146 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
147 * the configuration information for NAND module.
148 * @param ComSpace_Timing: pointer to Common space timing structure
149 * @param AttSpace_Timing: pointer to Attribute space timing structure
150 * @retval HAL status
151 */
152HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
153{
154 /* Check the NAND handle state */
155 if(hnand == NULL)
156 {
157 return HAL_ERROR;
158 }
159
160 if(hnand->State == HAL_NAND_STATE_RESET)
161 {
162 /* Allocate lock resource and initialize it */
163 hnand->Lock = HAL_UNLOCKED;
164 /* Initialize the low level hardware (MSP) */
165 HAL_NAND_MspInit(hnand);
166 }
167
168 /* Initialize NAND control Interface */
169 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
170
171 /* Initialize NAND common space timing Interface */
172 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
173
174 /* Initialize NAND attribute space timing Interface */
175 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
176
177 /* Enable the NAND device */
178 __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
179
180 /* Update the NAND controller state */
181 hnand->State = HAL_NAND_STATE_READY;
182
183 return HAL_OK;
184}
185
186/**
187 * @brief Perform NAND memory De-Initialization sequence
188 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
189 * the configuration information for NAND module.
190 * @retval HAL status
191 */
192HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
193{
194 /* Initialize the low level hardware (MSP) */
195 HAL_NAND_MspDeInit(hnand);
196
197 /* Configure the NAND registers with their reset values */
198 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
199
200 /* Reset the NAND controller state */
201 hnand->State = HAL_NAND_STATE_RESET;
202
203 /* Release Lock */
204 __HAL_UNLOCK(hnand);
205
206 return HAL_OK;
207}
208
209/**
210 * @brief NAND MSP Init
211 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
212 * the configuration information for NAND module.
213 * @retval None
214 */
215__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
216{
217 /* NOTE : This function Should not be modified, when the callback is needed,
218 the HAL_NAND_MspInit could be implemented in the user file
219 */
220}
221
222/**
223 * @brief NAND MSP DeInit
224 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
225 * the configuration information for NAND module.
226 * @retval None
227 */
228__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
229{
230 /* NOTE : This function Should not be modified, when the callback is needed,
231 the HAL_NAND_MspDeInit could be implemented in the user file
232 */
233}
234
235
236/**
237 * @brief This function handles NAND device interrupt request.
238 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
239 * the configuration information for NAND module.
240 * @retval HAL status
241*/
242void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
243{
244 /* Check NAND interrupt Rising edge flag */
245 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
246 {
247 /* NAND interrupt callback*/
248 HAL_NAND_ITCallback(hnand);
249
250 /* Clear NAND interrupt Rising edge pending bit */
251 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
252 }
253
254 /* Check NAND interrupt Level flag */
255 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
256 {
257 /* NAND interrupt callback*/
258 HAL_NAND_ITCallback(hnand);
259
260 /* Clear NAND interrupt Level pending bit */
261 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
262 }
263
264 /* Check NAND interrupt Falling edge flag */
265 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
266 {
267 /* NAND interrupt callback*/
268 HAL_NAND_ITCallback(hnand);
269
270 /* Clear NAND interrupt Falling edge pending bit */
271 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
272 }
273
274 /* Check NAND interrupt FIFO empty flag */
275 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
276 {
277 /* NAND interrupt callback*/
278 HAL_NAND_ITCallback(hnand);
279
280 /* Clear NAND interrupt FIFO empty pending bit */
281 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
282 }
283
284}
285
286/**
287 * @brief NAND interrupt feature callback
288 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
289 * the configuration information for NAND module.
290 * @retval None
291 */
292__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
293{
294 /* NOTE : This function Should not be modified, when the callback is needed,
295 the HAL_NAND_ITCallback could be implemented in the user file
296 */
297}
298
299/**
300 * @}
301 */
302
303/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
304 * @brief Input Output and memory control functions
305 *
306 @verbatim
307 ==============================================================================
308 ##### NAND Input and Output functions #####
309 ==============================================================================
310 [..]
311 This section provides functions allowing to use and control the NAND
312 memory
313
314@endverbatim
315 * @{
316 */
317
318/**
319 * @brief Read the NAND memory electronic signature
320 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
321 * the configuration information for NAND module.
322 * @param pNAND_ID: NAND ID structure
323 * @retval HAL status
324 */
325HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
326{
327 __IO uint32_t data = 0;
328 uint32_t deviceaddress = 0;
329
330 /* Process Locked */
331 __HAL_LOCK(hnand);
332
333 /* Check the NAND controller state */
334 if(hnand->State == HAL_NAND_STATE_BUSY)
335 {
336 return HAL_BUSY;
337 }
338
339 /* Identify the device address */
340 if(hnand->Init.NandBank == FMC_NAND_BANK2)
341 {
342 deviceaddress = NAND_DEVICE1;
343 }
344 else
345 {
346 deviceaddress = NAND_DEVICE2;
347 }
348
349 /* Update the NAND controller state */
350 hnand->State = HAL_NAND_STATE_BUSY;
351
352 /* Send Read ID command sequence */
353 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
354 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
355
356 /* Read the electronic signature from NAND flash */
357 data = *(__IO uint32_t *)deviceaddress;
358
359 /* Return the data read */
360 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
361 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
362 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
363 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
364
365 /* Update the NAND controller state */
366 hnand->State = HAL_NAND_STATE_READY;
367
368 /* Process unlocked */
369 __HAL_UNLOCK(hnand);
370
371 return HAL_OK;
372}
373
374/**
375 * @brief NAND memory reset
376 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
377 * the configuration information for NAND module.
378 * @retval HAL status
379 */
380HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
381{
382 uint32_t deviceaddress = 0;
383
384 /* Process Locked */
385 __HAL_LOCK(hnand);
386
387 /* Check the NAND controller state */
388 if(hnand->State == HAL_NAND_STATE_BUSY)
389 {
390 return HAL_BUSY;
391 }
392
393 /* Identify the device address */
394 if(hnand->Init.NandBank == FMC_NAND_BANK2)
395 {
396 deviceaddress = NAND_DEVICE1;
397 }
398 else
399 {
400 deviceaddress = NAND_DEVICE2;
401 }
402
403 /* Update the NAND controller state */
404 hnand->State = HAL_NAND_STATE_BUSY;
405
406 /* Send NAND reset command */
407 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
408
409
410 /* Update the NAND controller state */
411 hnand->State = HAL_NAND_STATE_READY;
412
413 /* Process unlocked */
414 __HAL_UNLOCK(hnand);
415
416 return HAL_OK;
417
418}
419
420/**
421 * @brief Read Page(s) from NAND memory block
422 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
423 * the configuration information for NAND module.
424 * @param pAddress : pointer to NAND address structure
425 * @param pBuffer : pointer to destination read buffer
426 * @param NumPageToRead : number of pages to read from block
427 * @retval HAL status
428 */
429HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
430{
431 __IO uint32_t index = 0;
432 uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
433 NAND_AddressTypeDef nandaddress;
434 uint32_t addressoffset = 0;
435
436 /* Process Locked */
437 __HAL_LOCK(hnand);
438
439 /* Check the NAND controller state */
440 if(hnand->State == HAL_NAND_STATE_BUSY)
441 {
442 return HAL_BUSY;
443 }
444
445 /* Identify the device address */
446 if(hnand->Init.NandBank == FMC_NAND_BANK2)
447 {
448 deviceaddress = NAND_DEVICE1;
449 }
450 else
451 {
452 deviceaddress = NAND_DEVICE2;
453 }
454
455 /* Update the NAND controller state */
456 hnand->State = HAL_NAND_STATE_BUSY;
457
458 /* Save the content of pAddress as it will be modified */
459 nandaddress.Block = pAddress->Block;
460 nandaddress.Page = pAddress->Page;
461 nandaddress.Zone = pAddress->Zone;
462
463 /* Page(s) read loop */
464 while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
465 {
466 /* update the buffer size */
467 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
468
469 /* Get the address offset */
470 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
471
472 /* Send read page command sequence */
473 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
474
475 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
476 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
477 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
478 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
479
480 /* for 512 and 1 GB devices, 4th cycle is required */
481 if(hnand->Info.BlockNbr >= 1024)
482 {
483 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
484 }
485
486 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
487
488 /* Get Data into Buffer */
489 for(index = size; index != 0; index--)
490 {
491 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
492 }
493
494 /* Increment read pages number */
495 numpagesread++;
496
497 /* Decrement pages to read */
498 NumPageToRead--;
499
500 /* Increment the NAND address */
501 addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
502 }
503
504 /* Update the NAND controller state */
505 hnand->State = HAL_NAND_STATE_READY;
506
507 /* Process unlocked */
508 __HAL_UNLOCK(hnand);
509
510 return HAL_OK;
511
512}
513
514/**
515 * @brief Write Page(s) to NAND memory block
516 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
517 * the configuration information for NAND module.
518 * @param pAddress : pointer to NAND address structure
519 * @param pBuffer : pointer to source buffer to write
520 * @param NumPageToWrite : number of pages to write to block
521 * @retval HAL status
522 */
523HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
524{
525 __IO uint32_t index = 0;
526 uint32_t tickstart = 0;
527 uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
528 NAND_AddressTypeDef nandaddress;
529 uint32_t addressoffset = 0;
530
531 /* Process Locked */
532 __HAL_LOCK(hnand);
533
534 /* Check the NAND controller state */
535 if(hnand->State == HAL_NAND_STATE_BUSY)
536 {
537 return HAL_BUSY;
538 }
539
540 /* Identify the device address */
541 if(hnand->Init.NandBank == FMC_NAND_BANK2)
542 {
543 deviceaddress = NAND_DEVICE1;
544 }
545 else
546 {
547 deviceaddress = NAND_DEVICE2;
548 }
549
550 /* Update the NAND controller state */
551 hnand->State = HAL_NAND_STATE_BUSY;
552
553 /* Save the content of pAddress as it will be modified */
554 nandaddress.Block = pAddress->Block;
555 nandaddress.Page = pAddress->Page;
556 nandaddress.Zone = pAddress->Zone;
557
558 /* Page(s) write loop */
559 while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
560 {
561 /* update the buffer size */
562 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
563
564 /* Get the address offset */
565 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
566
567 /* Send write page command sequence */
568 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
569 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
570
571 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
572 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
573 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
574 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
575
576 /* for 512 and 1 GB devices, 4th cycle is required */
577 if(hnand->Info.BlockNbr >= 1024)
578 {
579 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
580 }
581
582 /* Write data to memory */
583 for(index = size; index != 0; index--)
584 {
585 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
586 }
587
588 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
589
590 /* Get tick */
591 tickstart = HAL_GetTick();
592
593 /* Read status until NAND is ready */
594 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
595 {
596 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
597 {
598 return HAL_TIMEOUT;
599 }
600 }
601
602 /* Increment written pages number */
603 numpageswritten++;
604
605 /* Decrement pages to write */
606 NumPageToWrite--;
607
608 /* Increment the NAND address */
609 addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
610 }
611
612 /* Update the NAND controller state */
613 hnand->State = HAL_NAND_STATE_READY;
614
615 /* Process unlocked */
616 __HAL_UNLOCK(hnand);
617
618 return HAL_OK;
619}
620
621/**
622 * @brief Read Spare area(s) from NAND memory
623 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
624 * the configuration information for NAND module.
625 * @param pAddress : pointer to NAND address structure
626 * @param pBuffer: pointer to source buffer to write
627 * @param NumSpareAreaToRead: Number of spare area to read
628 * @retval HAL status
629*/
630HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
631{
632 __IO uint32_t index = 0;
633 uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
634 NAND_AddressTypeDef nandaddress;
635 uint32_t addressoffset = 0;
636
637 /* Process Locked */
638 __HAL_LOCK(hnand);
639
640 /* Check the NAND controller state */
641 if(hnand->State == HAL_NAND_STATE_BUSY)
642 {
643 return HAL_BUSY;
644 }
645
646 /* Identify the device address */
647 if(hnand->Init.NandBank == FMC_NAND_BANK2)
648 {
649 deviceaddress = NAND_DEVICE1;
650 }
651 else
652 {
653 deviceaddress = NAND_DEVICE2;
654 }
655
656 /* Update the NAND controller state */
657 hnand->State = HAL_NAND_STATE_BUSY;
658
659 /* Save the content of pAddress as it will be modified */
660 nandaddress.Block = pAddress->Block;
661 nandaddress.Page = pAddress->Page;
662 nandaddress.Zone = pAddress->Zone;
663
664 /* Spare area(s) read loop */
665 while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
666 {
667 /* update the buffer size */
668 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);
669
670 /* Get the address offset */
671 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
672
673 /* Send read spare area command sequence */
674 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
675
676 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
677 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
678 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
679 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
680
681 /* for 512 and 1 GB devices, 4th cycle is required */
682 if(hnand->Info.BlockNbr >= 1024)
683 {
684 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
685 }
686
687 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
688
689 /* Get Data into Buffer */
690 for (index = size ;index != 0; index--)
691 {
692 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
693 }
694
695 /* Increment read spare areas number */
696 num_spare_area_read++;
697
698 /* Decrement spare areas to read */
699 NumSpareAreaToRead--;
700
701 /* Increment the NAND address */
702 addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
703 }
704
705 /* Update the NAND controller state */
706 hnand->State = HAL_NAND_STATE_READY;
707
708 /* Process unlocked */
709 __HAL_UNLOCK(hnand);
710
711 return HAL_OK;
712}
713
714/**
715 * @brief Write Spare area(s) to NAND memory
716 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
717 * the configuration information for NAND module.
718 * @param pAddress : pointer to NAND address structure
719 * @param pBuffer : pointer to source buffer to write
720 * @param NumSpareAreaTowrite : number of spare areas to write to block
721 * @retval HAL status
722 */
723HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
724{
725 __IO uint32_t index = 0;
726 uint32_t tickstart = 0;
727 uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
728 NAND_AddressTypeDef nandaddress;
729 uint32_t addressoffset = 0;
730
731 /* Process Locked */
732 __HAL_LOCK(hnand);
733
734 /* Check the NAND controller state */
735 if(hnand->State == HAL_NAND_STATE_BUSY)
736 {
737 return HAL_BUSY;
738 }
739
740 /* Identify the device address */
741 if(hnand->Init.NandBank == FMC_NAND_BANK2)
742 {
743 deviceaddress = NAND_DEVICE1;
744 }
745 else
746 {
747 deviceaddress = NAND_DEVICE2;
748 }
749
750 /* Update the FMC_NAND controller state */
751 hnand->State = HAL_NAND_STATE_BUSY;
752
753 /* Save the content of pAddress as it will be modified */
754 nandaddress.Block = pAddress->Block;
755 nandaddress.Page = pAddress->Page;
756 nandaddress.Zone = pAddress->Zone;
757
758 /* Spare area(s) write loop */
759 while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
760 {
761 /* update the buffer size */
762 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
763
764 /* Get the address offset */
765 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
766
767 /* Send write Spare area command sequence */
768 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
769 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
770
771 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
772 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
773 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
774 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
775
776 /* for 512 and 1 GB devices, 4th cycle is required */
777 if(hnand->Info.BlockNbr >= 1024)
778 {
779 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
780 }
781
782 /* Write data to memory */
783 for(; index < size; index++)
784 {
785 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
786 }
787
788 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
789
790 /* Get tick */
791 tickstart = HAL_GetTick();
792
793 /* Read status until NAND is ready */
794 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
795 {
796 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
797 {
798 return HAL_TIMEOUT;
799 }
800 }
801
802 /* Increment written spare areas number */
803 num_spare_area_written++;
804
805 /* Decrement spare areas to write */
806 NumSpareAreaTowrite--;
807
808 /* Increment the NAND address */
809 addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
810 }
811
812 /* Update the NAND controller state */
813 hnand->State = HAL_NAND_STATE_READY;
814
815 /* Process unlocked */
816 __HAL_UNLOCK(hnand);
817
818 return HAL_OK;
819}
820
821/**
822 * @brief NAND memory Block erase
823 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
824 * the configuration information for NAND module.
825 * @param pAddress : pointer to NAND address structure
826 * @retval HAL status
827 */
828HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
829{
830 uint32_t deviceaddress = 0;
831 uint32_t tickstart = 0;
832
833 /* Process Locked */
834 __HAL_LOCK(hnand);
835
836 /* Check the NAND controller state */
837 if(hnand->State == HAL_NAND_STATE_BUSY)
838 {
839 return HAL_BUSY;
840 }
841
842 /* Identify the device address */
843 if(hnand->Init.NandBank == FMC_NAND_BANK2)
844 {
845 deviceaddress = NAND_DEVICE1;
846 }
847 else
848 {
849 deviceaddress = NAND_DEVICE2;
850 }
851
852 /* Update the NAND controller state */
853 hnand->State = HAL_NAND_STATE_BUSY;
854
855 /* Send Erase block command sequence */
856 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
857
858 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
859 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
860 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
861
862 /* for 512 and 1 GB devices, 4th cycle is required */
863 if(hnand->Info.BlockNbr >= 1024)
864 {
865 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
866 }
867
868 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
869
870 /* Update the NAND controller state */
871 hnand->State = HAL_NAND_STATE_READY;
872
873 /* Get tick */
874 tickstart = HAL_GetTick();
875
876 /* Read status until NAND is ready */
877 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
878 {
879 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
880 {
881 /* Process unlocked */
882 __HAL_UNLOCK(hnand);
883
884 return HAL_TIMEOUT;
885 }
886 }
887
888 /* Process unlocked */
889 __HAL_UNLOCK(hnand);
890
891 return HAL_OK;
892}
893
894/**
895 * @brief NAND memory read status
896 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
897 * the configuration information for NAND module.
898 * @retval NAND status
899 */
900uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
901{
902 uint32_t data = 0;
903 uint32_t deviceaddress = 0;
904
905 /* Identify the device address */
906 if(hnand->Init.NandBank == FMC_NAND_BANK2)
907 {
908 deviceaddress = NAND_DEVICE1;
909 }
910 else
911 {
912 deviceaddress = NAND_DEVICE2;
913 }
914
915 /* Send Read status operation command */
916 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
917
918 /* Read status register data */
919 data = *(__IO uint8_t *)deviceaddress;
920
921 /* Return the status */
922 if((data & NAND_ERROR) == NAND_ERROR)
923 {
924 return NAND_ERROR;
925 }
926 else if((data & NAND_READY) == NAND_READY)
927 {
928 return NAND_READY;
929 }
930
931 return NAND_BUSY;
932}
933
934/**
935 * @brief Increment the NAND memory address
936 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
937 * the configuration information for NAND module.
938 * @param pAddress: pointer to NAND address structure
939 * @retval The new status of the increment address operation. It can be:
940 * - NAND_VALID_ADDRESS: When the new address is valid address
941 * - NAND_INVALID_ADDRESS: When the new address is invalid address
942 */
943uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
944{
945 uint32_t status = NAND_VALID_ADDRESS;
946
947 /* Increment page address */
948 pAddress->Page++;
949
950 /* Check NAND address is valid */
951 if(pAddress->Page == hnand->Info.BlockSize)
952 {
953 pAddress->Page = 0;
954 pAddress->Block++;
955
956 if(pAddress->Block == hnand->Info.ZoneSize)
957 {
958 pAddress->Block = 0;
959 pAddress->Zone++;
960
961 if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
962 {
963 status = NAND_INVALID_ADDRESS;
964 }
965 }
966 }
967
968 return (status);
969}
970/**
971 * @}
972 */
973
974/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
975 * @brief management functions
976 *
977@verbatim
978 ==============================================================================
979 ##### NAND Control functions #####
980 ==============================================================================
981 [..]
982 This subsection provides a set of functions allowing to control dynamically
983 the NAND interface.
984
985@endverbatim
986 * @{
987 */
988
989
990/**
991 * @brief Enables dynamically NAND ECC feature.
992 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
993 * the configuration information for NAND module.
994 * @retval HAL status
995 */
996HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
997{
998 /* Check the NAND controller state */
999 if(hnand->State == HAL_NAND_STATE_BUSY)
1000 {
1001 return HAL_BUSY;
1002 }
1003
1004 /* Update the NAND state */
1005 hnand->State = HAL_NAND_STATE_BUSY;
1006
1007 /* Enable ECC feature */
1008 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
1009
1010 /* Update the NAND state */
1011 hnand->State = HAL_NAND_STATE_READY;
1012
1013 return HAL_OK;
1014}
1015
1016/**
1017 * @brief Disables dynamically FMC_NAND ECC feature.
1018 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1019 * the configuration information for NAND module.
1020 * @retval HAL status
1021 */
1022HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
1023{
1024 /* Check the NAND controller state */
1025 if(hnand->State == HAL_NAND_STATE_BUSY)
1026 {
1027 return HAL_BUSY;
1028 }
1029
1030 /* Update the NAND state */
1031 hnand->State = HAL_NAND_STATE_BUSY;
1032
1033 /* Disable ECC feature */
1034 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
1035
1036 /* Update the NAND state */
1037 hnand->State = HAL_NAND_STATE_READY;
1038
1039 return HAL_OK;
1040}
1041
1042/**
1043 * @brief Disables dynamically NAND ECC feature.
1044 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1045 * the configuration information for NAND module.
1046 * @param ECCval: pointer to ECC value
1047 * @param Timeout: maximum timeout to wait
1048 * @retval HAL status
1049 */
1050HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
1051{
1052 HAL_StatusTypeDef status = HAL_OK;
1053
1054 /* Check the NAND controller state */
1055 if(hnand->State == HAL_NAND_STATE_BUSY)
1056 {
1057 return HAL_BUSY;
1058 }
1059
1060 /* Update the NAND state */
1061 hnand->State = HAL_NAND_STATE_BUSY;
1062
1063 /* Get NAND ECC value */
1064 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1065
1066 /* Update the NAND state */
1067 hnand->State = HAL_NAND_STATE_READY;
1068
1069 return status;
1070}
1071
1072/**
1073 * @}
1074 */
1075
1076
1077/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1078 * @brief Peripheral State functions
1079 *
1080@verbatim
1081 ==============================================================================
1082 ##### NAND State functions #####
1083 ==============================================================================
1084 [..]
1085 This subsection permits to get in run-time the status of the NAND controller
1086 and the data flow.
1087
1088@endverbatim
1089 * @{
1090 */
1091
1092/**
1093 * @brief return the NAND state
1094 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1095 * the configuration information for NAND module.
1096 * @retval HAL state
1097 */
1098HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1099{
1100 return hnand->State;
1101}
1102
1103/**
1104 * @}
1105 */
1106
1107/**
1108 * @}
1109 */
1110
1111/**
1112 * @}
1113 */
1114
1115#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
1116 STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\
1117 STM32F446xx || STM32F469xx || STM32F479xx */
1118#endif /* HAL_NAND_MODULE_ENABLED */
1119
1120/**
1121 * @}
1122 */
1123
1124/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.