]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F3/stm32f3xx_hal_nand.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F3 / stm32f3xx_hal_nand.c
1 /**
2 ******************************************************************************
3 * @file stm32f3xx_hal_nand.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 12-Sept-2014
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) 2014 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 "stm32f3xx_hal.h"
87
88 /** @addtogroup STM32F3xx_HAL_Driver
89 * @{
90 */
91
92 /** @defgroup NAND NAND HAL module driver
93 * @brief NAND HAL module driver
94 * @{
95 */
96 #ifdef HAL_NAND_MODULE_ENABLED
97
98 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx)
99
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
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 */
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 == HAL_NULL)
138 {
139 return HAL_ERROR;
140 }
141
142 if(hnand->State == HAL_NAND_STATE_RESET)
143 {
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, hnand->Init.NandBank);
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 */
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 */
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 */
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 */
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 {
227 /* NAND interrupt callback*/
228 HAL_NAND_ITCallback(hnand);
229
230 /* Clear NAND interrupt Rising edge pending bit */
231 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
232 }
233
234 /* Check NAND interrupt Level flag */
235 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
236 {
237 /* NAND interrupt callback*/
238 HAL_NAND_ITCallback(hnand);
239
240 /* Clear NAND interrupt Level pending bit */
241 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
242 }
243
244 /* Check NAND interrupt Falling edge flag */
245 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
246 {
247 /* NAND interrupt callback*/
248 HAL_NAND_ITCallback(hnand);
249
250 /* Clear NAND interrupt Falling edge pending bit */
251 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
252 }
253
254 /* Check NAND interrupt FIFO empty flag */
255 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
256 {
257 /* NAND interrupt callback*/
258 HAL_NAND_ITCallback(hnand);
259
260 /* Clear NAND interrupt FIFO empty pending bit */
261 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
262 }
263
264 }
265
266 /**
267 * @brief NAND interrupt feature callback
268 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
269 * the configuration information for NAND module.
270 * @retval None
271 */
272 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
273 {
274 /* NOTE : This function Should not be modified, when the callback is needed,
275 the HAL_NAND_ITCallback could be implemented in the user file
276 */
277 }
278
279 /**
280 * @}
281 */
282
283 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
284 * @brief Input Output and memory control functions
285 *
286 @verbatim
287 ==============================================================================
288 ##### NAND Input and Output functions #####
289 ==============================================================================
290 [..]
291 This section provides functions allowing to use and control the NAND
292 memory
293
294 @endverbatim
295 * @{
296 */
297
298 /**
299 * @brief Read the NAND memory electronic signature
300 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
301 * the configuration information for NAND module.
302 * @param pNAND_ID: NAND ID structure
303 * @retval HAL status
304 */
305 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
306 {
307 __IO uint32_t data = 0;
308 uint32_t deviceAddress = 0;
309
310 /* Process Locked */
311 __HAL_LOCK(hnand);
312
313 /* Check the NAND controller state */
314 if(hnand->State == HAL_NAND_STATE_BUSY)
315 {
316 return HAL_BUSY;
317 }
318
319 /* Identify the device address */
320 if(hnand->Init.NandBank == FMC_NAND_BANK2)
321 {
322 deviceAddress = NAND_DEVICE1;
323 }
324 else
325 {
326 deviceAddress = NAND_DEVICE2;
327 }
328
329 /* Update the NAND controller state */
330 hnand->State = HAL_NAND_STATE_BUSY;
331
332 /* Send Read ID command sequence */
333 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x90;
334 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
335
336 /* Read the electronic signature from NAND flash */
337 data = *(__IO uint32_t *)deviceAddress;
338
339 /* Return the data read */
340 pNAND_ID->Maker_Id = ADDR_1st_CYCLE(data);
341 pNAND_ID->Device_Id = ADDR_2nd_CYCLE(data);
342 pNAND_ID->Third_Id = ADDR_3rd_CYCLE(data);
343 pNAND_ID->Fourth_Id = ADDR_4th_CYCLE(data);
344
345 /* Update the NAND controller state */
346 hnand->State = HAL_NAND_STATE_READY;
347
348 /* Process unlocked */
349 __HAL_UNLOCK(hnand);
350
351 return HAL_OK;
352 }
353
354 /**
355 * @brief NAND memory reset
356 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
357 * the configuration information for NAND module.
358 * @retval HAL status
359 */
360 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
361 {
362 uint32_t deviceAddress = 0;
363
364 /* Process Locked */
365 __HAL_LOCK(hnand);
366
367 /* Check the NAND controller state */
368 if(hnand->State == HAL_NAND_STATE_BUSY)
369 {
370 return HAL_BUSY;
371 }
372
373 /* Identify the device address */
374 if(hnand->Init.NandBank == FMC_NAND_BANK2)
375 {
376 deviceAddress = NAND_DEVICE1;
377 }
378 else
379 {
380 deviceAddress = NAND_DEVICE2;
381 }
382
383 /* Update the NAND controller state */
384 hnand->State = HAL_NAND_STATE_BUSY;
385
386 /* Send NAND reset command */
387 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
388
389
390 /* Update the NAND controller state */
391 hnand->State = HAL_NAND_STATE_READY;
392
393 /* Process unlocked */
394 __HAL_UNLOCK(hnand);
395
396 return HAL_OK;
397
398 }
399
400
401 /**
402 * @brief Read Page(s) from NAND memory block
403 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
404 * the configuration information for NAND module.
405 * @param pAddress : pointer to NAND address structure
406 * @param pBuffer : pointer to destination read buffer
407 * @param NumPageToRead : number of pages to read from block
408 * @retval HAL status
409 */
410 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
411 {
412 __IO uint32_t index = 0;
413 uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
414
415 /* Process Locked */
416 __HAL_LOCK(hnand);
417
418 /* Check the NAND controller state */
419 if(hnand->State == HAL_NAND_STATE_BUSY)
420 {
421 return HAL_BUSY;
422 }
423
424 /* Identify the device address */
425 if(hnand->Init.NandBank == FMC_NAND_BANK2)
426 {
427 deviceAddress = NAND_DEVICE1;
428 }
429 else
430 {
431 deviceAddress = NAND_DEVICE2;
432 }
433
434 /* Update the NAND controller state */
435 hnand->State = HAL_NAND_STATE_BUSY;
436
437 /* NAND raw address calculation */
438 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
439
440 /* Page(s) read loop */
441 while((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
442 {
443 /* update the buffer size */
444 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
445
446 /* Send read page command sequence */
447 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
448
449 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
450 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);
451 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);
452 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
453
454 /* for 512 and 1 GB devices, 4th cycle is required */
455 if(hnand->Info.BlockNbr >= 1024)
456 {
457 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
458 }
459
460 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x30;
461
462 /* Get Data into Buffer */
463 for(; index < size; index++)
464 {
465 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
466 }
467
468 /* Increment read pages number */
469 numPagesRead++;
470
471 /* Decrement pages to read */
472 NumPageToRead--;
473
474 /* Increment the NAND address */
475 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
476
477 }
478
479 /* Update the NAND controller state */
480 hnand->State = HAL_NAND_STATE_READY;
481
482 /* Process unlocked */
483 __HAL_UNLOCK(hnand);
484
485 return HAL_OK;
486
487 }
488
489 /**
490 * @brief Write Page(s) to NAND memory block
491 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
492 * the configuration information for NAND module.
493 * @param pAddress : pointer to NAND address structure
494 * @param pBuffer : pointer to source buffer to write
495 * @param NumPageToWrite : number of pages to write to block
496 * @retval HAL status
497 */
498 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
499 {
500 __IO uint32_t index = 0;
501 uint32_t timeout = 0;
502 uint32_t deviceAddress = 0, size = 0 , numPagesWritten = 0, nandAddress = 0;
503
504 /* Process Locked */
505 __HAL_LOCK(hnand);
506
507 /* Check the NAND controller state */
508 if(hnand->State == HAL_NAND_STATE_BUSY)
509 {
510 return HAL_BUSY;
511 }
512
513 /* Identify the device address */
514 if(hnand->Init.NandBank == FMC_NAND_BANK2)
515 {
516 deviceAddress = NAND_DEVICE1;
517 }
518 else
519 {
520 deviceAddress = NAND_DEVICE2;
521 }
522
523 /* Update the NAND controller state */
524 hnand->State = HAL_NAND_STATE_BUSY;
525
526 /* NAND raw address calculation */
527 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
528
529 /* Page(s) write loop */
530 while((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
531 {
532 /* update the buffer size */
533 size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
534
535 /* Send write page command sequence */
536 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
537 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x80;
538
539 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
540 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);
541 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);
542 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
543
544 /* for 512 and 1 GB devices, 4th cycle is required */
545 if(hnand->Info.BlockNbr >= 1024)
546 {
547 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
548 }
549
550 /* Write data to memory */
551 for(; index < size; index++)
552 {
553 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
554 }
555
556 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x10;
557
558 /* Read status until NAND is ready */
559 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
560 {
561 /* Check for timeout value */
562 timeout = HAL_GetTick() + NAND_WRITE_TIMEOUT;
563
564 if(HAL_GetTick() >= timeout)
565 {
566 return HAL_TIMEOUT;
567 }
568 }
569
570 /* Increment written pages number */
571 numPagesWritten++;
572
573 /* Decrement pages to write */
574 NumPageToWrite--;
575
576 /* Increment the NAND address */
577 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
578
579 }
580
581 /* Update the NAND controller state */
582 hnand->State = HAL_NAND_STATE_READY;
583
584 /* Process unlocked */
585 __HAL_UNLOCK(hnand);
586
587 return HAL_OK;
588 }
589
590
591 /**
592 * @brief Read Spare area(s) from NAND memory
593 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
594 * the configuration information for NAND module.
595 * @param pAddress : pointer to NAND address structure
596 * @param pBuffer: pointer to source buffer to write
597 * @param NumSpareAreaToRead: Number of spare area to read
598 * @retval HAL status
599 */
600 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
601 {
602 __IO uint32_t index = 0;
603 uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
604
605 /* Process Locked */
606 __HAL_LOCK(hnand);
607
608 /* Check the NAND controller state */
609 if(hnand->State == HAL_NAND_STATE_BUSY)
610 {
611 return HAL_BUSY;
612 }
613
614 /* Identify the device address */
615 if(hnand->Init.NandBank == FMC_NAND_BANK2)
616 {
617 deviceAddress = NAND_DEVICE1;
618 }
619 else
620 {
621 deviceAddress = NAND_DEVICE2;
622 }
623
624 /* Update the NAND controller state */
625 hnand->State = HAL_NAND_STATE_BUSY;
626
627 /* NAND raw address calculation */
628 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
629
630 /* Spare area(s) read loop */
631 while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
632 {
633
634 /* update the buffer size */
635 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
636
637 /* Send read spare area command sequence */
638 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
639
640 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
641 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);
642 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);
643 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
644
645 /* for 512 and 1 GB devices, 4th cycle is required */
646 if(hnand->Info.BlockNbr >= 1024)
647 {
648 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
649 }
650
651 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x30;
652
653 /* Get Data into Buffer */
654 for ( ;index < size; index++)
655 {
656 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
657 }
658
659 /* Increment read spare areas number */
660 numSpareAreaRead++;
661
662 /* Decrement spare areas to read */
663 NumSpareAreaToRead--;
664
665 /* Increment the NAND address */
666 nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
667 }
668
669 /* Update the NAND controller state */
670 hnand->State = HAL_NAND_STATE_READY;
671
672 /* Process unlocked */
673 __HAL_UNLOCK(hnand);
674
675 return HAL_OK;
676 }
677
678 /**
679 * @brief Write Spare area(s) to NAND memory
680 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
681 * the configuration information for NAND module.
682 * @param pAddress : pointer to NAND address structure
683 * @param pBuffer : pointer to source buffer to write
684 * @param NumSpareAreaTowrite : number of spare areas to write to block
685 * @retval HAL status
686 */
687 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
688 {
689 __IO uint32_t index = 0;
690 uint32_t timeout = 0;
691 uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
692
693 /* Process Locked */
694 __HAL_LOCK(hnand);
695
696 /* Check the NAND controller state */
697 if(hnand->State == HAL_NAND_STATE_BUSY)
698 {
699 return HAL_BUSY;
700 }
701
702 /* Identify the device address */
703 if(hnand->Init.NandBank == FMC_NAND_BANK2)
704 {
705 deviceAddress = NAND_DEVICE1;
706 }
707 else
708 {
709 deviceAddress = NAND_DEVICE2;
710 }
711
712 /* Update the FMC_NAND controller state */
713 hnand->State = HAL_NAND_STATE_BUSY;
714
715 /* NAND raw address calculation */
716 nandAddress = ARRAY_ADDRESS(pAddress, hnand);
717
718 /* Spare area(s) write loop */
719 while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
720 {
721 /* update the buffer size */
722 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
723
724 /* Send write Spare area command sequence */
725 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
726 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x80;
727
728 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
729 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(nandAddress);
730 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(nandAddress);
731 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(nandAddress);
732
733 /* for 512 and 1 GB devices, 4th cycle is required */
734 if(hnand->Info.BlockNbr >= 1024)
735 {
736 *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(nandAddress);
737 }
738
739 /* Write data to memory */
740 for(; index < size; index++)
741 {
742 *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
743 }
744
745 *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0x10;
746
747
748 /* Read status until NAND is ready */
749 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
750 {
751 /* Check for timeout value */
752 timeout = HAL_GetTick() + NAND_WRITE_TIMEOUT;
753
754 if(HAL_GetTick() >= timeout)
755 {
756 return HAL_TIMEOUT;
757 }
758 }
759
760 /* Increment written spare areas number */
761 numSpareAreaWritten++;
762
763 /* Decrement spare areas to write */
764 NumSpareAreaTowrite--;
765
766 /* Increment the NAND address */
767 nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));
768
769 }
770
771 /* Update the NAND controller state */
772 hnand->State = HAL_NAND_STATE_READY;
773
774 /* Process unlocked */
775 __HAL_UNLOCK(hnand);
776
777 return HAL_OK;
778 }
779
780 /**
781 * @brief NAND memory Block erase
782 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
783 * the configuration information for NAND module.
784 * @param pAddress : pointer to NAND address structure
785 * @retval HAL status
786 */
787 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
788 {
789 uint32_t DeviceAddress = 0;
790
791 /* Process Locked */
792 __HAL_LOCK(hnand);
793
794 /* Check the NAND controller state */
795 if(hnand->State == HAL_NAND_STATE_BUSY)
796 {
797 return HAL_BUSY;
798 }
799
800 /* Identify the device address */
801 if(hnand->Init.NandBank == FMC_NAND_BANK2)
802 {
803 DeviceAddress = NAND_DEVICE1;
804 }
805 else
806 {
807 DeviceAddress = NAND_DEVICE2;
808 }
809
810 /* Update the NAND controller state */
811 hnand->State = HAL_NAND_STATE_BUSY;
812
813 /* Send Erase block command sequence */
814 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0x60;
815
816 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1st_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
817 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2nd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
818 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3rd_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
819
820 /* for 512 and 1 GB devices, 4th cycle is required */
821 if(hnand->Info.BlockNbr >= 1024)
822 {
823 *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4th_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
824 }
825
826 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0xD0;
827
828 /* Update the NAND controller state */
829 hnand->State = HAL_NAND_STATE_READY;
830
831 /* Process unlocked */
832 __HAL_UNLOCK(hnand);
833
834 return HAL_OK;
835 }
836
837
838 /**
839 * @brief NAND memory read status
840 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
841 * the configuration information for NAND module.
842 * @retval NAND status
843 */
844 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
845 {
846 uint32_t data = 0;
847 uint32_t DeviceAddress = 0;
848
849 /* Identify the device address */
850 if(hnand->Init.NandBank == FMC_NAND_BANK2)
851 {
852 DeviceAddress = NAND_DEVICE1;
853 }
854 else
855 {
856 DeviceAddress = NAND_DEVICE2;
857 }
858
859 /* Send Read status operation command */
860 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = 0x70;
861
862 /* Read status register data */
863 data = *(__IO uint8_t *)DeviceAddress;
864
865 /* Return the status */
866 if((data & NAND_ERROR) == NAND_ERROR)
867 {
868 return NAND_ERROR;
869 }
870 else if((data & NAND_READY) == NAND_READY)
871 {
872 return NAND_READY;
873 }
874
875 return NAND_BUSY;
876
877 }
878
879 /**
880 * @brief Increment the NAND memory address
881 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
882 * the configuration information for NAND module.
883 * @param pAddress: pointer to NAND adress structure
884 * @retval The new status of the increment address operation. It can be:
885 * - NAND_VALID_ADDRESS: When the new address is valid address
886 * - NAND_INVALID_ADDRESS: When the new address is invalid address
887 */
888 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypedef *pAddress)
889 {
890 uint32_t status = NAND_VALID_ADDRESS;
891
892 /* Increment page address */
893 pAddress->Page++;
894
895 /* Check NAND address is valid */
896 if(pAddress->Page == hnand->Info.BlockSize)
897 {
898 pAddress->Page = 0;
899 pAddress->Block++;
900
901 if(pAddress->Block == hnand->Info.ZoneSize)
902 {
903 pAddress->Block = 0;
904 pAddress->Zone++;
905
906 if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
907 {
908 status = NAND_INVALID_ADDRESS;
909 }
910 }
911 }
912
913 return (status);
914 }
915
916
917 /**
918 * @}
919 */
920
921 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
922 * @brief management functions
923 *
924 @verbatim
925 ==============================================================================
926 ##### NAND Control functions #####
927 ==============================================================================
928 [..]
929 This subsection provides a set of functions allowing to control dynamically
930 the NAND interface.
931
932 @endverbatim
933 * @{
934 */
935
936
937 /**
938 * @brief Enables dynamically NAND ECC feature.
939 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
940 * the configuration information for NAND module.
941 * @retval HAL status
942 */
943 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
944 {
945 /* Check the NAND controller state */
946 if(hnand->State == HAL_NAND_STATE_BUSY)
947 {
948 return HAL_BUSY;
949 }
950
951 /* Update the NAND state */
952 hnand->State = HAL_NAND_STATE_BUSY;
953
954 /* Enable ECC feature */
955 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
956
957 /* Update the NAND state */
958 hnand->State = HAL_NAND_STATE_READY;
959
960 return HAL_OK;
961 }
962
963
964 /**
965 * @brief Disables dynamically FMC_NAND ECC feature.
966 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
967 * the configuration information for NAND module.
968 * @retval HAL status
969 */
970 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
971 {
972 /* Check the NAND controller state */
973 if(hnand->State == HAL_NAND_STATE_BUSY)
974 {
975 return HAL_BUSY;
976 }
977
978 /* Update the NAND state */
979 hnand->State = HAL_NAND_STATE_BUSY;
980
981 /* Disable ECC feature */
982 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
983
984 /* Update the NAND state */
985 hnand->State = HAL_NAND_STATE_READY;
986
987 return HAL_OK;
988 }
989
990 /**
991 * @brief Disables dynamically NAND ECC feature.
992 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
993 * the configuration information for NAND module.
994 * @param ECCval: pointer to ECC value
995 * @param Timeout: maximum timeout to wait
996 * @retval HAL status
997 */
998 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
999 {
1000 HAL_StatusTypeDef status = HAL_OK;
1001
1002 /* Check the NAND controller state */
1003 if(hnand->State == HAL_NAND_STATE_BUSY)
1004 {
1005 return HAL_BUSY;
1006 }
1007
1008 /* Update the NAND state */
1009 hnand->State = HAL_NAND_STATE_BUSY;
1010
1011 /* Get NAND ECC value */
1012 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
1013
1014 /* Update the NAND state */
1015 hnand->State = HAL_NAND_STATE_READY;
1016
1017 return status;
1018 }
1019
1020 /**
1021 * @}
1022 */
1023
1024
1025 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
1026 * @brief Peripheral State functions
1027 *
1028 @verbatim
1029 ==============================================================================
1030 ##### NAND State functions #####
1031 ==============================================================================
1032 [..]
1033 This subsection permits to get in run-time the status of the NAND controller
1034 and the data flow.
1035
1036 @endverbatim
1037 * @{
1038 */
1039
1040 /**
1041 * @brief return the NAND state
1042 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
1043 * the configuration information for NAND module.
1044 * @retval HAL state
1045 */
1046 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
1047 {
1048 return hnand->State;
1049 }
1050
1051 /**
1052 * @}
1053 */
1054
1055 /**
1056 * @}
1057 */
1058 #endif /* STM32F302xE || STM32F303xE || STM32F398xx */
1059 #endif /* HAL_NAND_MODULE_ENABLED */
1060
1061 /**
1062 * @}
1063 */
1064
1065 /**
1066 * @}
1067 */
1068
1069 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum