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