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