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