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