1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_ll_fmc.c
4   * @author  MCD Application Team
5   * @brief   FMC Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the Flexible Memory Controller (FMC) peripheral memories:
9   *           + Initialization/de-initialization functions
10   *           + Peripheral Control functions
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2019 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### FMC peripheral features #####
27   ==============================================================================
28   [..] The Flexible memory controller (FMC) includes following memory controllers:
29        (+) The NOR/PSRAM memory controller
30      (+) The NAND memory controller
31 
32   [..] The FMC functional block makes the interface with synchronous and asynchronous static
33        memories. Its main purposes are:
34        (+) to translate AHB transactions into the appropriate external device protocol
35        (+) to meet the access time requirements of the external memory devices
36 
37   [..] All external memories share the addresses, data and control signals with the controller.
38        Each external device is accessed by means of a unique Chip Select. The FMC performs
39        only one access at a time to an external device.
40        The main features of the FMC controller are the following:
41         (+) Interface with static-memory mapped devices including:
42            (++) Static random access memory (SRAM)
43            (++) Read-only memory (ROM)
44            (++) NOR Flash memory/OneNAND Flash memory
45            (++) PSRAM (4 memory banks)
46            (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
47                 data
48         (+) Independent Chip Select control for each memory bank
49         (+) Independent configuration for each memory bank
50 
51   @endverbatim
52   ******************************************************************************
53   */
54 
55 /* Includes ------------------------------------------------------------------*/
56 #include "stm32l5xx_hal.h"
57 
58 /** @addtogroup STM32L5xx_HAL_Driver
59   * @{
60   */
61 #if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED)
62 
63 /** @defgroup FMC_LL  FMC Low Layer
64   * @brief FMC driver modules
65   * @{
66   */
67 
68 /* Private typedef -----------------------------------------------------------*/
69 /* Private define ------------------------------------------------------------*/
70 
71 /** @defgroup FMC_LL_Private_Constants FMC Low Layer Private Constants
72   * @{
73   */
74 
75 /* ----------------------- FMC registers bit mask --------------------------- */
76 
77 /* --- BCR Register ---*/
78 /* BCR register clear mask */
79 
80 /* --- BTR Register ---*/
81 /* BTR register clear mask */
82 #define BTR_CLEAR_MASK    ((uint32_t)(FMC_BTRx_ADDSET | FMC_BTRx_ADDHLD  |\
83                                       FMC_BTRx_DATAST | FMC_BTRx_BUSTURN |\
84                                       FMC_BTRx_CLKDIV | FMC_BTRx_DATLAT  |\
85                                       FMC_BTRx_ACCMOD | FMC_BTRx_DATAHLD))
86 
87 /* --- BWTR Register ---*/
88 /* BWTR register clear mask */
89 #define BWTR_CLEAR_MASK   ((uint32_t)(FMC_BWTRx_ADDSET | FMC_BWTRx_ADDHLD  |\
90                                       FMC_BWTRx_DATAST | FMC_BWTRx_BUSTURN |\
91                                       FMC_BWTRx_ACCMOD | FMC_BWTRx_DATAHLD))
92 
93 /* --- PCR Register ---*/
94 /* PCR register clear mask */
95 #define PCR_CLEAR_MASK    ((uint32_t)(FMC_PCR_PWAITEN | FMC_PCR_PBKEN  | \
96                                       FMC_PCR_PTYP    | FMC_PCR_PWID   | \
97                                       FMC_PCR_ECCEN   | FMC_PCR_TCLR   | \
98                                       FMC_PCR_TAR     | FMC_PCR_ECCPS))
99 /* --- PMEM Register ---*/
100 /* PMEM register clear mask */
101 #define PMEM_CLEAR_MASK   ((uint32_t)(FMC_PMEM_MEMSET  | FMC_PMEM_MEMWAIT |\
102                                       FMC_PMEM_MEMHOLD | FMC_PMEM_MEMHIZ))
103 
104 /* --- PATT Register ---*/
105 /* PATT register clear mask */
106 #define PATT_CLEAR_MASK   ((uint32_t)(FMC_PATT_ATTSET  | FMC_PATT_ATTWAIT |\
107                                       FMC_PATT_ATTHOLD | FMC_PATT_ATTHIZ))
108 
109 
110 /**
111   * @}
112   */
113 
114 /* Private macro -------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private function prototypes -----------------------------------------------*/
117 /* Exported functions --------------------------------------------------------*/
118 
119 /** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions
120   * @{
121   */
122 
123 
124 /** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions
125   * @brief  NORSRAM Controller functions
126   *
127   @verbatim
128   ==============================================================================
129                    ##### How to use NORSRAM device driver #####
130   ==============================================================================
131 
132   [..]
133     This driver contains a set of APIs to interface with the FMC NORSRAM banks in order
134     to run the NORSRAM external devices.
135 
136     (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit()
137     (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init()
138     (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init()
139     (+) FMC NORSRAM bank extended timing configuration using the function
140         FMC_NORSRAM_Extended_Timing_Init()
141     (+) FMC NORSRAM bank enable/disable write operation using the functions
142         FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable()
143 
144 @endverbatim
145   * @{
146   */
147 
148 /** @defgroup FMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
149   * @brief    Initialization and Configuration functions
150   *
151   @verbatim
152   ==============================================================================
153               ##### Initialization and de_initialization functions #####
154   ==============================================================================
155   [..]
156     This section provides functions allowing to:
157     (+) Initialize and configure the FMC NORSRAM interface
158     (+) De-initialize the FMC NORSRAM interface
159     (+) Configure the FMC clock and associated GPIOs
160 
161 @endverbatim
162   * @{
163   */
164 
165 /**
166   * @brief  Initialize the FMC_NORSRAM device according to the specified
167   *         control parameters in the FMC_NORSRAM_InitTypeDef
168   * @param  Device Pointer to NORSRAM device instance
169   * @param  Init Pointer to NORSRAM Initialization structure
170   * @retval HAL status
171   */
FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_InitTypeDef * Init)172 HAL_StatusTypeDef  FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device,
173                                     FMC_NORSRAM_InitTypeDef *Init)
174 {
175   uint32_t flashaccess;
176   uint32_t btcr_reg;
177   uint32_t mask;
178 
179   /* Check the parameters */
180   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
181   assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank));
182   assert_param(IS_FMC_MUX(Init->DataAddressMux));
183   assert_param(IS_FMC_MEMORY(Init->MemoryType));
184   assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
185   assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode));
186   assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity));
187   assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
188   assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation));
189   assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal));
190   assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode));
191   assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait));
192   assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst));
193   assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock));
194   assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo));
195   assert_param(IS_FMC_PAGESIZE(Init->PageSize));
196   assert_param(IS_FMC_NBL_SETUPTIME(Init->NBLSetupTime));
197   assert_param(IS_FUNCTIONAL_STATE(Init->MaxChipSelectPulse));
198 
199   /* Disable NORSRAM Device */
200   __FMC_NORSRAM_DISABLE(Device, Init->NSBank);
201 
202   /* Set NORSRAM device control parameters */
203   if (Init->MemoryType == FMC_MEMORY_TYPE_NOR)
204   {
205     flashaccess = FMC_NORSRAM_FLASH_ACCESS_ENABLE;
206   }
207   else
208   {
209     flashaccess = FMC_NORSRAM_FLASH_ACCESS_DISABLE;
210   }
211 
212   btcr_reg = (flashaccess                   | \
213               Init->DataAddressMux          | \
214               Init->MemoryType              | \
215               Init->MemoryDataWidth         | \
216               Init->BurstAccessMode         | \
217               Init->WaitSignalPolarity      | \
218               Init->WaitSignalActive        | \
219               Init->WriteOperation          | \
220               Init->WaitSignal              | \
221               Init->ExtendedMode            | \
222               Init->AsynchronousWait        | \
223               Init->WriteBurst);
224 
225   btcr_reg |= Init->ContinuousClock;
226   btcr_reg |= Init->WriteFifo;
227   btcr_reg |= Init->NBLSetupTime;
228   btcr_reg |= Init->PageSize;
229 
230   mask = (FMC_BCRx_MBKEN                |
231           FMC_BCRx_MUXEN                |
232           FMC_BCRx_MTYP                 |
233           FMC_BCRx_MWID                 |
234           FMC_BCRx_FACCEN               |
235           FMC_BCRx_BURSTEN              |
236           FMC_BCRx_WAITPOL              |
237           FMC_BCRx_WAITCFG              |
238           FMC_BCRx_WREN                 |
239           FMC_BCRx_WAITEN               |
240           FMC_BCRx_EXTMOD               |
241           FMC_BCRx_ASYNCWAIT            |
242           FMC_BCRx_CBURSTRW);
243 
244   mask |= FMC_BCR1_CCLKEN;
245   mask |= FMC_BCR1_WFDIS;
246   mask |= FMC_BCRx_NBLSET;
247   mask |= FMC_BCRx_CPSIZE;
248 
249   MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg);
250 
251   /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
252   if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1))
253   {
254     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN, Init->ContinuousClock);
255   }
256 
257   if (Init->NSBank != FMC_NORSRAM_BANK1)
258   {
259     /* Configure Write FIFO mode when Write Fifo is enabled for bank2..4 */
260     SET_BIT(Device->BTCR[FMC_NORSRAM_BANK1], (uint32_t)(Init->WriteFifo));
261   }
262 
263   /* Check PSRAM chip select counter state */
264   if (Init->MaxChipSelectPulse == ENABLE)
265   {
266     /* Check the parameters */
267     assert_param(IS_FMC_MAX_CHIP_SELECT_PULSE_TIME(Init->MaxChipSelectPulseTime));
268 
269     /* Configure PSRAM chip select counter value */
270     MODIFY_REG(Device->PCSCNTR, FMC_PCSCNTR_CSCOUNT, (uint32_t)(Init->MaxChipSelectPulseTime));
271 
272     /* Enable PSRAM chip select counter for the bank */
273     switch (Init->NSBank)
274     {
275       case FMC_NORSRAM_BANK1 :
276         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
277         break;
278 
279       case FMC_NORSRAM_BANK2 :
280         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
281         break;
282 
283       case FMC_NORSRAM_BANK3 :
284         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
285         break;
286 
287       default :
288         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
289         break;
290     }
291   }
292 
293   return HAL_OK;
294 }
295 
296 /**
297   * @brief  DeInitialize the FMC_NORSRAM peripheral
298   * @param  Device Pointer to NORSRAM device instance
299   * @param  ExDevice Pointer to NORSRAM extended mode device instance
300   * @param  Bank NORSRAM bank number
301   * @retval HAL status
302   */
FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_EXTENDED_TypeDef * ExDevice,uint32_t Bank)303 HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device,
304                                      FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
305 {
306   /* Check the parameters */
307   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
308   assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
309   assert_param(IS_FMC_NORSRAM_BANK(Bank));
310 
311   /* Disable the FMC_NORSRAM device */
312   __FMC_NORSRAM_DISABLE(Device, Bank);
313 
314   /* De-initialize the FMC_NORSRAM device */
315   /* FMC_NORSRAM_BANK1 */
316   if (Bank == FMC_NORSRAM_BANK1)
317   {
318     Device->BTCR[Bank] = 0x000030DBU;
319   }
320   /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
321   else
322   {
323     Device->BTCR[Bank] = 0x000030D2U;
324   }
325 
326   Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
327   ExDevice->BWTR[Bank]   = 0x0FFFFFFFU;
328 
329   /* De-initialize PSRAM chip select counter */
330   switch (Bank)
331   {
332     case FMC_NORSRAM_BANK1 :
333       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
334       break;
335 
336     case FMC_NORSRAM_BANK2 :
337       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
338       break;
339 
340     case FMC_NORSRAM_BANK3 :
341       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
342       break;
343 
344     default :
345       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
346       break;
347   }
348 
349   return HAL_OK;
350 }
351 
352 /**
353   * @brief  Initialize the FMC_NORSRAM Timing according to the specified
354   *         parameters in the FMC_NORSRAM_TimingTypeDef
355   * @param  Device Pointer to NORSRAM device instance
356   * @param  Timing Pointer to NORSRAM Timing structure
357   * @param  Bank NORSRAM bank number
358   * @retval HAL status
359   */
FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)360 HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device,
361                                           FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
362 {
363   uint32_t tmpr;
364 
365   /* Check the parameters */
366   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
367   assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
368   assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
369   assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
370   assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
371   assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
372   assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision));
373   assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency));
374   assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
375   assert_param(IS_FMC_NORSRAM_BANK(Bank));
376 
377   /* Set FMC_NORSRAM device timing parameters */
378   MODIFY_REG(Device->BTCR[Bank + 1U], BTR_CLEAR_MASK, (Timing->AddressSetupTime                                  |
379                                                        ((Timing->AddressHoldTime)        << FMC_BTRx_ADDHLD_Pos)  |
380                                                        ((Timing->DataSetupTime)          << FMC_BTRx_DATAST_Pos)  |
381                                                        ((Timing->DataHoldTime)           << FMC_BTRx_DATAHLD_Pos) |
382                                                        ((Timing->BusTurnAroundDuration)  << FMC_BTRx_BUSTURN_Pos) |
383                                                        (((Timing->CLKDivision) - 1U)     << FMC_BTRx_CLKDIV_Pos)  |
384                                                        (((Timing->DataLatency) - 2U)     << FMC_BTRx_DATLAT_Pos)  |
385                                                        (Timing->AccessMode)));
386 
387   /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
388   if (HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN))
389   {
390     tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FMC_BTRx_CLKDIV_Pos));
391     tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTRx_CLKDIV_Pos);
392     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1 + 1U], FMC_BTRx_CLKDIV, tmpr);
393   }
394 
395   return HAL_OK;
396 }
397 
398 /**
399   * @brief  Initialize the FMC_NORSRAM Extended mode Timing according to the specified
400   *         parameters in the FMC_NORSRAM_TimingTypeDef
401   * @param  Device Pointer to NORSRAM device instance
402   * @param  Timing Pointer to NORSRAM Timing structure
403   * @param  Bank NORSRAM bank number
404   * @param  ExtendedMode FMC Extended Mode
405   *          This parameter can be one of the following values:
406   *            @arg FMC_EXTENDED_MODE_DISABLE
407   *            @arg FMC_EXTENDED_MODE_ENABLE
408   * @retval HAL status
409   */
FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)410 HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device,
411                                                    FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
412                                                    uint32_t ExtendedMode)
413 {
414   /* Check the parameters */
415   assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode));
416 
417   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
418   if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE)
419   {
420     /* Check the parameters */
421     assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device));
422     assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
423     assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
424     assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
425     assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
426     assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
427     assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
428     assert_param(IS_FMC_NORSRAM_BANK(Bank));
429 
430     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
431     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
432                                                      ((Timing->AddressHoldTime)        << FMC_BWTRx_ADDHLD_Pos)  |
433                                                      ((Timing->DataSetupTime)          << FMC_BWTRx_DATAST_Pos)  |
434                                                      ((Timing->DataHoldTime)           << FMC_BWTRx_DATAHLD_Pos) |
435                                                      Timing->AccessMode                                          |
436                                                      ((Timing->BusTurnAroundDuration)  << FMC_BWTRx_BUSTURN_Pos)));
437   }
438   else
439   {
440     Device->BWTR[Bank] = 0x0FFFFFFFU;
441   }
442 
443   return HAL_OK;
444 }
445 /**
446   * @}
447   */
448 
449 /** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2
450   *  @brief   management functions
451   *
452 @verbatim
453   ==============================================================================
454                       ##### FMC_NORSRAM Control functions #####
455   ==============================================================================
456   [..]
457     This subsection provides a set of functions allowing to control dynamically
458     the FMC NORSRAM interface.
459 
460 @endverbatim
461   * @{
462   */
463 
464 /**
465   * @brief  Enables dynamically FMC_NORSRAM write operation.
466   * @param  Device Pointer to NORSRAM device instance
467   * @param  Bank NORSRAM bank number
468   * @retval HAL status
469   */
FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)470 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
471 {
472   /* Check the parameters */
473   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
474   assert_param(IS_FMC_NORSRAM_BANK(Bank));
475 
476   /* Enable write operation */
477   SET_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
478 
479   return HAL_OK;
480 }
481 
482 /**
483   * @brief  Disables dynamically FMC_NORSRAM write operation.
484   * @param  Device Pointer to NORSRAM device instance
485   * @param  Bank NORSRAM bank number
486   * @retval HAL status
487   */
FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)488 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
489 {
490   /* Check the parameters */
491   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
492   assert_param(IS_FMC_NORSRAM_BANK(Bank));
493 
494   /* Disable write operation */
495   CLEAR_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
496 
497   return HAL_OK;
498 }
499 
500 /**
501   * @}
502   */
503 
504 /**
505   * @}
506   */
507 
508 
509 /** @defgroup FMC_LL_Exported_Functions_NAND FMC Low Layer NAND Exported Functions
510   * @brief    NAND Controller functions
511   *
512   @verbatim
513   ==============================================================================
514                     ##### How to use NAND device driver #####
515   ==============================================================================
516   [..]
517     This driver contains a set of APIs to interface with the FMC NAND banks in order
518     to run the NAND external devices.
519 
520     (+) FMC NAND bank reset using the function FMC_NAND_DeInit()
521     (+) FMC NAND bank control configuration using the function FMC_NAND_Init()
522     (+) FMC NAND bank common space timing configuration using the function
523         FMC_NAND_CommonSpace_Timing_Init()
524     (+) FMC NAND bank attribute space timing configuration using the function
525         FMC_NAND_AttributeSpace_Timing_Init()
526     (+) FMC NAND bank enable/disable ECC correction feature using the functions
527         FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable()
528     (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC()
529 
530 @endverbatim
531   * @{
532   */
533 
534 /** @defgroup FMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
535   *  @brief    Initialization and Configuration functions
536   *
537 @verbatim
538   ==============================================================================
539               ##### Initialization and de_initialization functions #####
540   ==============================================================================
541   [..]
542     This section provides functions allowing to:
543     (+) Initialize and configure the FMC NAND interface
544     (+) De-initialize the FMC NAND interface
545     (+) Configure the FMC clock and associated GPIOs
546 
547 @endverbatim
548   * @{
549   */
550 
551 /**
552   * @brief  Initializes the FMC_NAND device according to the specified
553   *         control parameters in the FMC_NAND_HandleTypeDef
554   * @param  Device Pointer to NAND device instance
555   * @param  Init Pointer to NAND Initialization structure
556   * @retval HAL status
557   */
FMC_NAND_Init(FMC_NAND_TypeDef * Device,FMC_NAND_InitTypeDef * Init)558 HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init)
559 {
560   /* Check the parameters */
561   assert_param(IS_FMC_NAND_DEVICE(Device));
562   assert_param(IS_FMC_NAND_BANK(Init->NandBank));
563   assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
564   assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
565   assert_param(IS_FMC_ECC_STATE(Init->EccComputation));
566   assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize));
567   assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
568   assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
569 
570   /* NAND bank 3 registers configuration */
571   MODIFY_REG(Device->PCR, PCR_CLEAR_MASK, (Init->Waitfeature                            |
572                                            FMC_PCR_MEMORY_TYPE_NAND                     |
573                                            Init->MemoryDataWidth                        |
574                                            Init->EccComputation                         |
575                                            Init->ECCPageSize                            |
576                                            ((Init->TCLRSetupTime) << FMC_PCR_TCLR_Pos)  |
577                                            ((Init->TARSetupTime)  << FMC_PCR_TAR_Pos)));
578 
579   return HAL_OK;
580 }
581 
582 /**
583   * @brief  Initializes the FMC_NAND Common space Timing according to the specified
584   *         parameters in the FMC_NAND_PCC_TimingTypeDef
585   * @param  Device Pointer to NAND device instance
586   * @param  Timing Pointer to NAND timing structure
587   * @param  Bank NAND bank number
588   * @retval HAL status
589   */
FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)590 HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device,
591                                                    FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
592 {
593   /* Check the parameters */
594   assert_param(IS_FMC_NAND_DEVICE(Device));
595   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
596   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
597   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
598   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
599   assert_param(IS_FMC_NAND_BANK(Bank));
600 
601   /* Prevent unused argument(s) compilation warning if no assert_param check */
602   UNUSED(Bank);
603 
604   /* NAND bank 3 registers configuration */
605   MODIFY_REG(Device->PMEM, PMEM_CLEAR_MASK, (Timing->SetupTime                                 |
606                                              ((Timing->WaitSetupTime) << FMC_PMEM_MEMWAIT_Pos) |
607                                              ((Timing->HoldSetupTime) << FMC_PMEM_MEMHOLD_Pos) |
608                                              ((Timing->HiZSetupTime)  << FMC_PMEM_MEMHIZ_Pos)));
609 
610   return HAL_OK;
611 }
612 
613 /**
614   * @brief  Initializes the FMC_NAND Attribute space Timing according to the specified
615   *         parameters in the FMC_NAND_PCC_TimingTypeDef
616   * @param  Device Pointer to NAND device instance
617   * @param  Timing Pointer to NAND timing structure
618   * @param  Bank NAND bank number
619   * @retval HAL status
620   */
FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)621 HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device,
622                                                       FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
623 {
624   /* Check the parameters */
625   assert_param(IS_FMC_NAND_DEVICE(Device));
626   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
627   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
628   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
629   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
630   assert_param(IS_FMC_NAND_BANK(Bank));
631 
632   /* Prevent unused argument(s) compilation warning if no assert_param check */
633   UNUSED(Bank);
634 
635   /* NAND bank 3 registers configuration */
636   MODIFY_REG(Device->PATT, PATT_CLEAR_MASK, (Timing->SetupTime                                 |
637                                              ((Timing->WaitSetupTime) << FMC_PATT_ATTWAIT_Pos) |
638                                              ((Timing->HoldSetupTime) << FMC_PATT_ATTHOLD_Pos) |
639                                              ((Timing->HiZSetupTime)  << FMC_PATT_ATTHIZ_Pos)));
640 
641   return HAL_OK;
642 }
643 
644 /**
645   * @brief  DeInitializes the FMC_NAND device
646   * @param  Device Pointer to NAND device instance
647   * @param  Bank NAND bank number
648   * @retval HAL status
649   */
FMC_NAND_DeInit(FMC_NAND_TypeDef * Device,uint32_t Bank)650 HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank)
651 {
652   /* Check the parameters */
653   assert_param(IS_FMC_NAND_DEVICE(Device));
654   assert_param(IS_FMC_NAND_BANK(Bank));
655 
656   /* Disable the NAND Bank */
657   __FMC_NAND_DISABLE(Device, Bank);
658 
659   /* De-initialize the NAND Bank */
660   /* Prevent unused argument(s) compilation warning if no assert_param check */
661   UNUSED(Bank);
662 
663   /* Set the FMC_NAND_BANK3 registers to their reset values */
664   WRITE_REG(Device->PCR,  0x00000018U);
665   WRITE_REG(Device->SR,   0x00000040U);
666   WRITE_REG(Device->PMEM, 0xFCFCFCFCU);
667   WRITE_REG(Device->PATT, 0xFCFCFCFCU);
668 
669   return HAL_OK;
670 }
671 
672 /**
673   * @}
674   */
675 
676 /** @defgroup HAL_FMC_NAND_Group2 Peripheral Control functions
677   *  @brief   management functions
678   *
679 @verbatim
680   ==============================================================================
681                        ##### FMC_NAND Control functions #####
682   ==============================================================================
683   [..]
684     This subsection provides a set of functions allowing to control dynamically
685     the FMC NAND interface.
686 
687 @endverbatim
688   * @{
689   */
690 
691 
692 /**
693   * @brief  Enables dynamically FMC_NAND ECC feature.
694   * @param  Device Pointer to NAND device instance
695   * @param  Bank NAND bank number
696   * @retval HAL status
697   */
FMC_NAND_ECC_Enable(FMC_NAND_TypeDef * Device,uint32_t Bank)698 HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank)
699 {
700   /* Check the parameters */
701   assert_param(IS_FMC_NAND_DEVICE(Device));
702   assert_param(IS_FMC_NAND_BANK(Bank));
703 
704   /* Enable ECC feature */
705   /* Prevent unused argument(s) compilation warning if no assert_param check */
706   UNUSED(Bank);
707 
708   SET_BIT(Device->PCR, FMC_PCR_ECCEN);
709 
710   return HAL_OK;
711 }
712 
713 
714 /**
715   * @brief  Disables dynamically FMC_NAND ECC feature.
716   * @param  Device Pointer to NAND device instance
717   * @param  Bank NAND bank number
718   * @retval HAL status
719   */
FMC_NAND_ECC_Disable(FMC_NAND_TypeDef * Device,uint32_t Bank)720 HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank)
721 {
722   /* Check the parameters */
723   assert_param(IS_FMC_NAND_DEVICE(Device));
724   assert_param(IS_FMC_NAND_BANK(Bank));
725 
726   /* Disable ECC feature */
727   /* Prevent unused argument(s) compilation warning if no assert_param check */
728   UNUSED(Bank);
729 
730   CLEAR_BIT(Device->PCR, FMC_PCR_ECCEN);
731 
732   return HAL_OK;
733 }
734 
735 /**
736   * @brief  Disables dynamically FMC_NAND ECC feature.
737   * @param  Device Pointer to NAND device instance
738   * @param  ECCval Pointer to ECC value
739   * @param  Bank NAND bank number
740   * @param  Timeout Timeout wait value
741   * @retval HAL status
742   */
FMC_NAND_GetECC(FMC_NAND_TypeDef * Device,uint32_t * ECCval,uint32_t Bank,uint32_t Timeout)743 HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
744                                   uint32_t Timeout)
745 {
746   uint32_t tickstart;
747 
748   /* Check the parameters */
749   assert_param(IS_FMC_NAND_DEVICE(Device));
750   assert_param(IS_FMC_NAND_BANK(Bank));
751 
752   /* Get tick */
753   tickstart = HAL_GetTick();
754 
755   /* Wait until FIFO is empty */
756   while (__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET)
757   {
758     /* Check for the Timeout */
759     if (Timeout != HAL_MAX_DELAY)
760     {
761       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
762       {
763         return HAL_TIMEOUT;
764       }
765     }
766   }
767 
768   /* Prevent unused argument(s) compilation warning if no assert_param check */
769   UNUSED(Bank);
770 
771   /* Get the ECCR register value */
772   *ECCval = (uint32_t)Device->ECCR;
773 
774   return HAL_OK;
775 }
776 
777 /**
778   * @}
779   */
780 
781 
782 
783 /**
784   * @}
785   */
786 
787 /**
788   * @}
789   */
790 
791 #endif /* HAL_NOR_MODULE_ENABLED */
792 /**
793   * @}
794   */
795 /**
796   * @}
797   */
798