1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_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) 2016 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/PC Card memory controller
31 
32   [..] The FMC functional block makes the interface with synchronous and asynchronous static
33        memories and 16-bit PC memory cards. 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            (++) 16-bit PC Card compatible devices
47            (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
48                 data
49         (+) Independent Chip Select control for each memory bank
50         (+) Independent configuration for each memory bank
51 
52   @endverbatim
53   ******************************************************************************
54   */
55 
56 /* Includes ------------------------------------------------------------------*/
57 #include "stm32f3xx_hal.h"
58 
59 /** @addtogroup STM32F3xx_HAL_Driver
60   * @{
61   */
62 #if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_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))
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_ACCMOD))
93 #endif /* FMC_BANK1 */
94 #if defined(FMC_BANK3)
95 
96 /* --- PCR Register ---*/
97 /* PCR register clear mask */
98 #define PCR_CLEAR_MASK    ((uint32_t)(FMC_PCRx_PWAITEN | FMC_PCRx_PBKEN  | \
99                                       FMC_PCRx_PTYP    | FMC_PCRx_PWID   | \
100                                       FMC_PCRx_ECCEN   | FMC_PCRx_TCLR   | \
101                                       FMC_PCRx_TAR     | FMC_PCRx_ECCPS))
102 /* --- PMEM Register ---*/
103 /* PMEM register clear mask */
104 #define PMEM_CLEAR_MASK   ((uint32_t)(FMC_PMEMx_MEMSETx  | FMC_PMEMx_MEMWAITx |\
105                                       FMC_PMEMx_MEMHOLDx | FMC_PMEMx_MEMHIZx))
106 
107 /* --- PATT Register ---*/
108 /* PATT register clear mask */
109 #define PATT_CLEAR_MASK   ((uint32_t)(FMC_PATTx_ATTSETx  | FMC_PATTx_ATTWAITx |\
110                                       FMC_PATTx_ATTHOLDx | FMC_PATTx_ATTHIZx))
111 
112 #endif /* FMC_BANK3 */
113 #if defined(FMC_BANK4)
114 /* --- PCR Register ---*/
115 /* PCR register clear mask */
116 #define PCR4_CLEAR_MASK   ((uint32_t)(FMC_PCR4_PWAITEN | FMC_PCR4_PBKEN  | \
117                                       FMC_PCR4_PTYP    | FMC_PCR4_PWID   | \
118                                       FMC_PCR4_ECCEN   | FMC_PCR4_TCLR   | \
119                                       FMC_PCR4_TAR     | FMC_PCR4_ECCPS))
120 /* --- PMEM Register ---*/
121 /* PMEM register clear mask */
122 #define PMEM4_CLEAR_MASK  ((uint32_t)(FMC_PMEM4_MEMSET4  | FMC_PMEM4_MEMWAIT4 |\
123                                       FMC_PMEM4_MEMHOLD4 | FMC_PMEM4_MEMHIZ4))
124 
125 /* --- PATT Register ---*/
126 /* PATT register clear mask */
127 #define PATT4_CLEAR_MASK  ((uint32_t)(FMC_PATT4_ATTSET4  | FMC_PATT4_ATTWAIT4 |\
128                                       FMC_PATT4_ATTHOLD4 | FMC_PATT4_ATTHIZ4))
129 
130 /* --- PIO4 Register ---*/
131 /* PIO4 register clear mask */
132 #define PIO4_CLEAR_MASK   ((uint32_t)(FMC_PIO4_IOSET4  | FMC_PIO4_IOWAIT4 | \
133                                       FMC_PIO4_IOHOLD4 | FMC_PIO4_IOHIZ4))
134 
135 #endif /* FMC_BANK4 */
136 
137 /**
138   * @}
139   */
140 
141 /* Private macro -------------------------------------------------------------*/
142 /* Private variables ---------------------------------------------------------*/
143 /* Private function prototypes -----------------------------------------------*/
144 /* Exported functions --------------------------------------------------------*/
145 
146 /** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions
147   * @{
148   */
149 
150 #if defined(FMC_BANK1)
151 
152 /** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions
153   * @brief  NORSRAM Controller functions
154   *
155   @verbatim
156   ==============================================================================
157                    ##### How to use NORSRAM device driver #####
158   ==============================================================================
159 
160   [..]
161     This driver contains a set of APIs to interface with the FMC NORSRAM banks in order
162     to run the NORSRAM external devices.
163 
164     (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit()
165     (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init()
166     (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init()
167     (+) FMC NORSRAM bank extended timing configuration using the function
168         FMC_NORSRAM_Extended_Timing_Init()
169     (+) FMC NORSRAM bank enable/disable write operation using the functions
170         FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable()
171 
172 @endverbatim
173   * @{
174   */
175 
176 /** @defgroup FMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
177   * @brief    Initialization and Configuration functions
178   *
179   @verbatim
180   ==============================================================================
181               ##### Initialization and de_initialization functions #####
182   ==============================================================================
183   [..]
184     This section provides functions allowing to:
185     (+) Initialize and configure the FMC NORSRAM interface
186     (+) De-initialize the FMC NORSRAM interface
187     (+) Configure the FMC clock and associated GPIOs
188 
189 @endverbatim
190   * @{
191   */
192 
193 /**
194   * @brief  Initialize the FMC_NORSRAM device according to the specified
195   *         control parameters in the FMC_NORSRAM_InitTypeDef
196   * @param  Device Pointer to NORSRAM device instance
197   * @param  Init Pointer to NORSRAM Initialization structure
198   * @retval HAL status
199   */
FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_InitTypeDef * Init)200 HAL_StatusTypeDef  FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device,
201                                     FMC_NORSRAM_InitTypeDef *Init)
202 {
203   uint32_t flashaccess;
204   uint32_t btcr_reg;
205   uint32_t mask;
206 
207   /* Check the parameters */
208   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
209   assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank));
210   assert_param(IS_FMC_MUX(Init->DataAddressMux));
211   assert_param(IS_FMC_MEMORY(Init->MemoryType));
212   assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
213   assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode));
214   assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity));
215   assert_param(IS_FMC_WRAP_MODE(Init->WrapMode));
216   assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
217   assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation));
218   assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal));
219   assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode));
220   assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait));
221   assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst));
222   assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock));
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->WrapMode;
251   btcr_reg |= Init->ContinuousClock;
252 
253   mask = (FMC_BCRx_MBKEN                |
254           FMC_BCRx_MUXEN                |
255           FMC_BCRx_MTYP                 |
256           FMC_BCRx_MWID                 |
257           FMC_BCRx_FACCEN               |
258           FMC_BCRx_BURSTEN              |
259           FMC_BCRx_WAITPOL              |
260           FMC_BCRx_WAITCFG              |
261           FMC_BCRx_WREN                 |
262           FMC_BCRx_WAITEN               |
263           FMC_BCRx_EXTMOD               |
264           FMC_BCRx_ASYNCWAIT            |
265           FMC_BCRx_CBURSTRW);
266 
267   mask |= FMC_BCRx_WRAPMOD;
268   mask |= FMC_BCR1_CCLKEN;
269 
270   MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg);
271 
272   /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
273   if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1))
274   {
275     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN, Init->ContinuousClock);
276   }
277 
278   return HAL_OK;
279 }
280 
281 /**
282   * @brief  DeInitialize the FMC_NORSRAM peripheral
283   * @param  Device Pointer to NORSRAM device instance
284   * @param  ExDevice Pointer to NORSRAM extended mode device instance
285   * @param  Bank NORSRAM bank number
286   * @retval HAL status
287   */
FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_EXTENDED_TypeDef * ExDevice,uint32_t Bank)288 HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device,
289                                      FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
290 {
291   /* Check the parameters */
292   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
293   assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
294   assert_param(IS_FMC_NORSRAM_BANK(Bank));
295 
296   /* Disable the FMC_NORSRAM device */
297   __FMC_NORSRAM_DISABLE(Device, Bank);
298 
299   /* De-initialize the FMC_NORSRAM device */
300   /* FMC_NORSRAM_BANK1 */
301   if (Bank == FMC_NORSRAM_BANK1)
302   {
303     Device->BTCR[Bank] = 0x000030DBU;
304   }
305   /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
306   else
307   {
308     Device->BTCR[Bank] = 0x000030D2U;
309   }
310 
311   Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
312   ExDevice->BWTR[Bank]   = 0x0FFFFFFFU;
313 
314   return HAL_OK;
315 }
316 
317 /**
318   * @brief  Initialize the FMC_NORSRAM Timing according to the specified
319   *         parameters in the FMC_NORSRAM_TimingTypeDef
320   * @param  Device Pointer to NORSRAM device instance
321   * @param  Timing Pointer to NORSRAM Timing structure
322   * @param  Bank NORSRAM bank number
323   * @retval HAL status
324   */
FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)325 HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device,
326                                           FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
327 {
328   uint32_t tmpr;
329 
330   /* Check the parameters */
331   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
332   assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
333   assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
334   assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
335   assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
336   assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision));
337   assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency));
338   assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
339   assert_param(IS_FMC_NORSRAM_BANK(Bank));
340 
341   /* Set FMC_NORSRAM device timing parameters */
342   MODIFY_REG(Device->BTCR[Bank + 1U], BTR_CLEAR_MASK, (Timing->AddressSetupTime                                  |
343                                                        ((Timing->AddressHoldTime)        << FMC_BTRx_ADDHLD_Pos)  |
344                                                        ((Timing->DataSetupTime)          << FMC_BTRx_DATAST_Pos)  |
345                                                        ((Timing->BusTurnAroundDuration)  << FMC_BTRx_BUSTURN_Pos) |
346                                                        (((Timing->CLKDivision) - 1U)     << FMC_BTRx_CLKDIV_Pos)  |
347                                                        (((Timing->DataLatency) - 2U)     << FMC_BTRx_DATLAT_Pos)  |
348                                                        (Timing->AccessMode)));
349 
350   /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
351   if (HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN))
352   {
353     tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FMC_BTRx_CLKDIV_Pos));
354     tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTRx_CLKDIV_Pos);
355     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1 + 1U], FMC_BTRx_CLKDIV, tmpr);
356   }
357 
358   return HAL_OK;
359 }
360 
361 /**
362   * @brief  Initialize the FMC_NORSRAM Extended mode Timing according to the specified
363   *         parameters in the FMC_NORSRAM_TimingTypeDef
364   * @param  Device Pointer to NORSRAM device instance
365   * @param  Timing Pointer to NORSRAM Timing structure
366   * @param  Bank NORSRAM bank number
367   * @param  ExtendedMode FMC Extended Mode
368   *          This parameter can be one of the following values:
369   *            @arg FMC_EXTENDED_MODE_DISABLE
370   *            @arg FMC_EXTENDED_MODE_ENABLE
371   * @retval HAL status
372   */
FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)373 HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device,
374                                                    FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
375                                                    uint32_t ExtendedMode)
376 {
377   /* Check the parameters */
378   assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode));
379 
380   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
381   if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE)
382   {
383     /* Check the parameters */
384     assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device));
385     assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
386     assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
387     assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
388     assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
389     assert_param(IS_FMC_NORSRAM_BANK(Bank));
390 
391     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
392     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
393                                                      ((Timing->AddressHoldTime)        << FMC_BWTRx_ADDHLD_Pos)  |
394                                                      ((Timing->DataSetupTime)          << FMC_BWTRx_DATAST_Pos)  |
395                                                      Timing->AccessMode));
396   }
397   else
398   {
399     Device->BWTR[Bank] = 0x0FFFFFFFU;
400   }
401 
402   return HAL_OK;
403 }
404 /**
405   * @}
406   */
407 
408 /** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2
409   *  @brief   management functions
410   *
411 @verbatim
412   ==============================================================================
413                       ##### FMC_NORSRAM Control functions #####
414   ==============================================================================
415   [..]
416     This subsection provides a set of functions allowing to control dynamically
417     the FMC NORSRAM interface.
418 
419 @endverbatim
420   * @{
421   */
422 
423 /**
424   * @brief  Enables dynamically FMC_NORSRAM write operation.
425   * @param  Device Pointer to NORSRAM device instance
426   * @param  Bank NORSRAM bank number
427   * @retval HAL status
428   */
FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)429 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
430 {
431   /* Check the parameters */
432   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
433   assert_param(IS_FMC_NORSRAM_BANK(Bank));
434 
435   /* Enable write operation */
436   SET_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
437 
438   return HAL_OK;
439 }
440 
441 /**
442   * @brief  Disables dynamically FMC_NORSRAM write operation.
443   * @param  Device Pointer to NORSRAM device instance
444   * @param  Bank NORSRAM bank number
445   * @retval HAL status
446   */
FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)447 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
448 {
449   /* Check the parameters */
450   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
451   assert_param(IS_FMC_NORSRAM_BANK(Bank));
452 
453   /* Disable write operation */
454   CLEAR_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
455 
456   return HAL_OK;
457 }
458 
459 /**
460   * @}
461   */
462 
463 /**
464   * @}
465   */
466 #endif /* FMC_BANK1 */
467 
468 #if defined(FMC_BANK3)
469 
470 /** @defgroup FMC_LL_Exported_Functions_NAND FMC Low Layer NAND Exported Functions
471   * @brief    NAND Controller functions
472   *
473   @verbatim
474   ==============================================================================
475                     ##### How to use NAND device driver #####
476   ==============================================================================
477   [..]
478     This driver contains a set of APIs to interface with the FMC NAND banks in order
479     to run the NAND external devices.
480 
481     (+) FMC NAND bank reset using the function FMC_NAND_DeInit()
482     (+) FMC NAND bank control configuration using the function FMC_NAND_Init()
483     (+) FMC NAND bank common space timing configuration using the function
484         FMC_NAND_CommonSpace_Timing_Init()
485     (+) FMC NAND bank attribute space timing configuration using the function
486         FMC_NAND_AttributeSpace_Timing_Init()
487     (+) FMC NAND bank enable/disable ECC correction feature using the functions
488         FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable()
489     (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC()
490 
491 @endverbatim
492   * @{
493   */
494 
495 /** @defgroup FMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
496   *  @brief    Initialization and Configuration functions
497   *
498 @verbatim
499   ==============================================================================
500               ##### Initialization and de_initialization functions #####
501   ==============================================================================
502   [..]
503     This section provides functions allowing to:
504     (+) Initialize and configure the FMC NAND interface
505     (+) De-initialize the FMC NAND interface
506     (+) Configure the FMC clock and associated GPIOs
507 
508 @endverbatim
509   * @{
510   */
511 
512 /**
513   * @brief  Initializes the FMC_NAND device according to the specified
514   *         control parameters in the FMC_NAND_HandleTypeDef
515   * @param  Device Pointer to NAND device instance
516   * @param  Init Pointer to NAND Initialization structure
517   * @retval HAL status
518   */
FMC_NAND_Init(FMC_NAND_TypeDef * Device,FMC_NAND_InitTypeDef * Init)519 HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init)
520 {
521   /* Check the parameters */
522   assert_param(IS_FMC_NAND_DEVICE(Device));
523   assert_param(IS_FMC_NAND_BANK(Init->NandBank));
524   assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
525   assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
526   assert_param(IS_FMC_ECC_STATE(Init->EccComputation));
527   assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize));
528   assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
529   assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
530 
531   /* Set NAND device control parameters */
532   if (Init->NandBank == FMC_NAND_BANK2)
533   {
534     /* NAND bank 2 registers configuration */
535     MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
536                                               FMC_PCR_MEMORY_TYPE_NAND                               |
537                                               Init->MemoryDataWidth                                  |
538                                               Init->EccComputation                                   |
539                                               Init->ECCPageSize                                      |
540                                               ((Init->TCLRSetupTime) << FMC_PCRx_TCLR_Pos)  |
541                                               ((Init->TARSetupTime)  << FMC_PCRx_TAR_Pos)));
542   }
543   else
544   {
545     /* NAND bank 3 registers configuration */
546     MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
547                                               FMC_PCR_MEMORY_TYPE_NAND                               |
548                                               Init->MemoryDataWidth                                  |
549                                               Init->EccComputation                                   |
550                                               Init->ECCPageSize                                      |
551                                               ((Init->TCLRSetupTime) << FMC_PCRx_TCLR_Pos)  |
552                                               ((Init->TARSetupTime)  << FMC_PCRx_TAR_Pos)));
553   }
554 
555   return HAL_OK;
556 }
557 
558 /**
559   * @brief  Initializes the FMC_NAND Common space Timing according to the specified
560   *         parameters in the FMC_NAND_PCC_TimingTypeDef
561   * @param  Device Pointer to NAND device instance
562   * @param  Timing Pointer to NAND timing structure
563   * @param  Bank NAND bank number
564   * @retval HAL status
565   */
FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)566 HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device,
567                                                    FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
568 {
569   /* Check the parameters */
570   assert_param(IS_FMC_NAND_DEVICE(Device));
571   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
572   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
573   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
574   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
575   assert_param(IS_FMC_NAND_BANK(Bank));
576 
577   /* Set FMC_NAND device timing parameters */
578   if (Bank == FMC_NAND_BANK2)
579   {
580     /* NAND bank 2 registers configuration */
581     MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
582                                                 ((Timing->WaitSetupTime) << FMC_PMEMx_MEMWAITx_Pos) |
583                                                 ((Timing->HoldSetupTime) << FMC_PMEMx_MEMHOLDx_Pos) |
584                                                 ((Timing->HiZSetupTime)  << FMC_PMEMx_MEMHIZx_Pos)));
585   }
586   else
587   {
588     /* NAND bank 3 registers configuration */
589     MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
590                                                 ((Timing->WaitSetupTime) << FMC_PMEMx_MEMWAITx_Pos) |
591                                                 ((Timing->HoldSetupTime) << FMC_PMEMx_MEMHOLDx_Pos) |
592                                                 ((Timing->HiZSetupTime)  << FMC_PMEMx_MEMHIZx_Pos)));
593   }
594 
595   return HAL_OK;
596 }
597 
598 /**
599   * @brief  Initializes the FMC_NAND Attribute space Timing according to the specified
600   *         parameters in the FMC_NAND_PCC_TimingTypeDef
601   * @param  Device Pointer to NAND device instance
602   * @param  Timing Pointer to NAND timing structure
603   * @param  Bank NAND bank number
604   * @retval HAL status
605   */
FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)606 HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device,
607                                                       FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
608 {
609   /* Check the parameters */
610   assert_param(IS_FMC_NAND_DEVICE(Device));
611   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
612   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
613   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
614   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
615   assert_param(IS_FMC_NAND_BANK(Bank));
616 
617   /* Set FMC_NAND device timing parameters */
618   if (Bank == FMC_NAND_BANK2)
619   {
620     /* NAND bank 2 registers configuration */
621     MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
622                                                 ((Timing->WaitSetupTime) << FMC_PATTx_ATTWAITx_Pos) |
623                                                 ((Timing->HoldSetupTime) << FMC_PATTx_ATTHOLDx_Pos) |
624                                                 ((Timing->HiZSetupTime)  << FMC_PATTx_ATTHIZx_Pos)));
625   }
626   else
627   {
628     /* NAND bank 3 registers configuration */
629     MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
630                                                 ((Timing->WaitSetupTime) << FMC_PATTx_ATTWAITx_Pos) |
631                                                 ((Timing->HoldSetupTime) << FMC_PATTx_ATTHOLDx_Pos) |
632                                                 ((Timing->HiZSetupTime)  << FMC_PATTx_ATTHIZx_Pos)));
633   }
634 
635   return HAL_OK;
636 }
637 
638 /**
639   * @brief  DeInitializes the FMC_NAND device
640   * @param  Device Pointer to NAND device instance
641   * @param  Bank NAND bank number
642   * @retval HAL status
643   */
FMC_NAND_DeInit(FMC_NAND_TypeDef * Device,uint32_t Bank)644 HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank)
645 {
646   /* Check the parameters */
647   assert_param(IS_FMC_NAND_DEVICE(Device));
648   assert_param(IS_FMC_NAND_BANK(Bank));
649 
650   /* Disable the NAND Bank */
651   __FMC_NAND_DISABLE(Device, Bank);
652 
653   /* De-initialize the NAND Bank */
654   if (Bank == FMC_NAND_BANK2)
655   {
656     /* Set the FMC_NAND_BANK2 registers to their reset values */
657     WRITE_REG(Device->PCR2,  0x00000018U);
658     WRITE_REG(Device->SR2,   0x00000040U);
659     WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
660     WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
661   }
662   /* FMC_Bank3_NAND */
663   else
664   {
665     /* Set the FMC_NAND_BANK3 registers to their reset values */
666     WRITE_REG(Device->PCR3,  0x00000018U);
667     WRITE_REG(Device->SR3,   0x00000040U);
668     WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
669     WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
670   }
671 
672   return HAL_OK;
673 }
674 
675 /**
676   * @}
677   */
678 
679 /** @defgroup HAL_FMC_NAND_Group2 Peripheral Control functions
680   *  @brief   management functions
681   *
682 @verbatim
683   ==============================================================================
684                        ##### FMC_NAND Control functions #####
685   ==============================================================================
686   [..]
687     This subsection provides a set of functions allowing to control dynamically
688     the FMC NAND interface.
689 
690 @endverbatim
691   * @{
692   */
693 
694 
695 /**
696   * @brief  Enables dynamically FMC_NAND ECC feature.
697   * @param  Device Pointer to NAND device instance
698   * @param  Bank NAND bank number
699   * @retval HAL status
700   */
FMC_NAND_ECC_Enable(FMC_NAND_TypeDef * Device,uint32_t Bank)701 HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank)
702 {
703   /* Check the parameters */
704   assert_param(IS_FMC_NAND_DEVICE(Device));
705   assert_param(IS_FMC_NAND_BANK(Bank));
706 
707   /* Enable ECC feature */
708   if (Bank == FMC_NAND_BANK2)
709   {
710     SET_BIT(Device->PCR2, FMC_PCRx_ECCEN);
711   }
712   else
713   {
714     SET_BIT(Device->PCR3, FMC_PCRx_ECCEN);
715   }
716 
717   return HAL_OK;
718 }
719 
720 
721 /**
722   * @brief  Disables dynamically FMC_NAND ECC feature.
723   * @param  Device Pointer to NAND device instance
724   * @param  Bank NAND bank number
725   * @retval HAL status
726   */
FMC_NAND_ECC_Disable(FMC_NAND_TypeDef * Device,uint32_t Bank)727 HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank)
728 {
729   /* Check the parameters */
730   assert_param(IS_FMC_NAND_DEVICE(Device));
731   assert_param(IS_FMC_NAND_BANK(Bank));
732 
733   /* Disable ECC feature */
734   if (Bank == FMC_NAND_BANK2)
735   {
736     CLEAR_BIT(Device->PCR2, FMC_PCRx_ECCEN);
737   }
738   else
739   {
740     CLEAR_BIT(Device->PCR3, FMC_PCRx_ECCEN);
741   }
742 
743   return HAL_OK;
744 }
745 
746 /**
747   * @brief  Disables dynamically FMC_NAND ECC feature.
748   * @param  Device Pointer to NAND device instance
749   * @param  ECCval Pointer to ECC value
750   * @param  Bank NAND bank number
751   * @param  Timeout Timeout wait value
752   * @retval HAL status
753   */
FMC_NAND_GetECC(FMC_NAND_TypeDef * Device,uint32_t * ECCval,uint32_t Bank,uint32_t Timeout)754 HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
755                                   uint32_t Timeout)
756 {
757   uint32_t tickstart;
758 
759   /* Check the parameters */
760   assert_param(IS_FMC_NAND_DEVICE(Device));
761   assert_param(IS_FMC_NAND_BANK(Bank));
762 
763   /* Get tick */
764   tickstart = HAL_GetTick();
765 
766   /* Wait until FIFO is empty */
767   while (__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET)
768   {
769     /* Check for the Timeout */
770     if (Timeout != HAL_MAX_DELAY)
771     {
772       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
773       {
774         return HAL_TIMEOUT;
775       }
776     }
777   }
778 
779   if (Bank == FMC_NAND_BANK2)
780   {
781     /* Get the ECCR2 register value */
782     *ECCval = (uint32_t)Device->ECCR2;
783   }
784   else
785   {
786     /* Get the ECCR3 register value */
787     *ECCval = (uint32_t)Device->ECCR3;
788   }
789 
790   return HAL_OK;
791 }
792 
793 /**
794   * @}
795   */
796 #endif /* FMC_BANK3 */
797 
798 #if defined(FMC_BANK4)
799 
800 /** @addtogroup FMC_LL_PCCARD
801   * @brief    PCCARD Controller functions
802   *
803   @verbatim
804   ==============================================================================
805                     ##### How to use PCCARD device driver #####
806   ==============================================================================
807   [..]
808     This driver contains a set of APIs to interface with the FMC PCCARD bank in order
809     to run the PCCARD/compact flash external devices.
810 
811     (+) FMC PCCARD bank reset using the function FMC_PCCARD_DeInit()
812     (+) FMC PCCARD bank control configuration using the function FMC_PCCARD_Init()
813     (+) FMC PCCARD bank common space timing configuration using the function
814         FMC_PCCARD_CommonSpace_Timing_Init()
815     (+) FMC PCCARD bank attribute space timing configuration using the function
816         FMC_PCCARD_AttributeSpace_Timing_Init()
817     (+) FMC PCCARD bank IO space timing configuration using the function
818         FMC_PCCARD_IOSpace_Timing_Init()
819 @endverbatim
820   * @{
821   */
822 
823 /** @addtogroup FMC_LL_PCCARD_Private_Functions_Group1
824   *  @brief    Initialization and Configuration functions
825   *
826 @verbatim
827   ==============================================================================
828               ##### Initialization and de_initialization functions #####
829   ==============================================================================
830   [..]
831     This section provides functions allowing to:
832     (+) Initialize and configure the FMC PCCARD interface
833     (+) De-initialize the FMC PCCARD interface
834     (+) Configure the FMC clock and associated GPIOs
835 
836 @endverbatim
837   * @{
838   */
839 
840 /**
841   * @brief  Initializes the FMC_PCCARD device according to the specified
842   *         control parameters in the FMC_PCCARD_HandleTypeDef
843   * @param  Device Pointer to PCCARD device instance
844   * @param  Init Pointer to PCCARD Initialization structure
845   * @retval HAL status
846   */
FMC_PCCARD_Init(FMC_PCCARD_TypeDef * Device,FMC_PCCARD_InitTypeDef * Init)847 HAL_StatusTypeDef FMC_PCCARD_Init(FMC_PCCARD_TypeDef *Device, FMC_PCCARD_InitTypeDef *Init)
848 {
849   /* Check the parameters */
850   assert_param(IS_FMC_PCCARD_DEVICE(Device));
851 #if defined(FMC_BANK3)
852   assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
853   assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
854   assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
855 #endif /* FMC_BANK3 */
856 
857   /* Set FMC_PCCARD device control parameters */
858   MODIFY_REG(Device->PCR4,
859              (FMC_PCR4_PTYP                                          |
860               FMC_PCR4_PWAITEN                                       |
861               FMC_PCR4_PWID                                          |
862               FMC_PCR4_TCLR                                          |
863               FMC_PCR4_TAR),
864              (FMC_PCR_MEMORY_TYPE_PCCARD                             |
865               Init->Waitfeature                                      |
866               FMC_NAND_PCC_MEM_BUS_WIDTH_16                          |
867               (Init->TCLRSetupTime << FMC_PCR4_TCLR_Pos)   |
868               (Init->TARSetupTime  << FMC_PCR4_TAR_Pos)));
869 
870   return HAL_OK;
871 }
872 
873 /**
874   * @brief  Initializes the FMC_PCCARD Common space Timing according to the specified
875   *         parameters in the FMC_NAND_PCC_TimingTypeDef
876   * @param  Device Pointer to PCCARD device instance
877   * @param  Timing Pointer to PCCARD timing structure
878   * @retval HAL status
879   */
FMC_PCCARD_CommonSpace_Timing_Init(FMC_PCCARD_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing)880 HAL_StatusTypeDef FMC_PCCARD_CommonSpace_Timing_Init(FMC_PCCARD_TypeDef *Device,
881                                                               FMC_NAND_PCC_TimingTypeDef *Timing)
882 {
883   /* Check the parameters */
884   assert_param(IS_FMC_PCCARD_DEVICE(Device));
885 #if defined(FMC_BANK3)
886   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
887   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
888   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
889   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
890 #endif /* FMC_BANK3 */
891 
892   /* Set PCCARD timing parameters */
893   MODIFY_REG(Device->PMEM4, PMEM4_CLEAR_MASK,
894              (Timing->SetupTime                                              |
895               ((Timing->WaitSetupTime) << FMC_PMEM4_MEMWAIT4_Pos)  |
896               ((Timing->HoldSetupTime) << FMC_PMEM4_MEMHOLD4_Pos)  |
897               ((Timing->HiZSetupTime)  << FMC_PMEM4_MEMHIZ4_Pos)));
898 
899   return HAL_OK;
900 }
901 
902 /**
903   * @brief  Initializes the FMC_PCCARD Attribute space Timing according to the specified
904   *         parameters in the FMC_NAND_PCC_TimingTypeDef
905   * @param  Device Pointer to PCCARD device instance
906   * @param  Timing Pointer to PCCARD timing structure
907   * @retval HAL status
908   */
FMC_PCCARD_AttributeSpace_Timing_Init(FMC_PCCARD_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing)909 HAL_StatusTypeDef FMC_PCCARD_AttributeSpace_Timing_Init(FMC_PCCARD_TypeDef *Device,
910                                                                  FMC_NAND_PCC_TimingTypeDef *Timing)
911 {
912   /* Check the parameters */
913   assert_param(IS_FMC_PCCARD_DEVICE(Device));
914 #if defined(FMC_BANK3)
915   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
916   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
917   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
918   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
919 #endif /* FMC_BANK3 */
920 
921   /* Set PCCARD timing parameters */
922   MODIFY_REG(Device->PATT4, PATT4_CLEAR_MASK,
923              (Timing->SetupTime                                              |
924               ((Timing->WaitSetupTime) << FMC_PATT4_ATTWAIT4_Pos)  |
925               ((Timing->HoldSetupTime) << FMC_PATT4_ATTHOLD4_Pos)  |
926               ((Timing->HiZSetupTime)  << FMC_PATT4_ATTHIZ4_Pos)));
927 
928   return HAL_OK;
929 }
930 
931 /**
932   * @brief  Initializes the FMC_PCCARD IO space Timing according to the specified
933   *         parameters in the FMC_NAND_PCC_TimingTypeDef
934   * @param  Device Pointer to PCCARD device instance
935   * @param  Timing Pointer to PCCARD timing structure
936   * @retval HAL status
937   */
FMC_PCCARD_IOSpace_Timing_Init(FMC_PCCARD_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing)938 HAL_StatusTypeDef FMC_PCCARD_IOSpace_Timing_Init(FMC_PCCARD_TypeDef *Device,
939                                                           FMC_NAND_PCC_TimingTypeDef *Timing)
940 {
941   /* Check the parameters */
942   assert_param(IS_FMC_PCCARD_DEVICE(Device));
943 #if defined(FMC_BANK3)
944   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
945   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
946   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
947   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
948 #endif /* FMC_BANK3 */
949 
950   /* Set FMC_PCCARD device timing parameters */
951   MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK,
952              (Timing->SetupTime                                           |
953               (Timing->WaitSetupTime   << FMC_PIO4_IOWAIT4_Pos) |
954               (Timing->HoldSetupTime   << FMC_PIO4_IOHOLD4_Pos) |
955               (Timing->HiZSetupTime    << FMC_PIO4_IOHIZ4_Pos)));
956 
957   return HAL_OK;
958 }
959 
960 /**
961   * @brief  DeInitializes the FMC_PCCARD device
962   * @param  Device Pointer to PCCARD device instance
963   * @retval HAL status
964   */
FMC_PCCARD_DeInit(FMC_PCCARD_TypeDef * Device)965 HAL_StatusTypeDef FMC_PCCARD_DeInit(FMC_PCCARD_TypeDef *Device)
966 {
967   /* Check the parameters */
968   assert_param(IS_FMC_PCCARD_DEVICE(Device));
969 
970   /* Disable the FMC_PCCARD device */
971   __FMC_PCCARD_DISABLE(Device);
972 
973   /* De-initialize the FMC_PCCARD device */
974   Device->PCR4    = 0x00000018U;
975   Device->SR4     = 0x00000040U;
976   Device->PMEM4   = 0xFCFCFCFCU;
977   Device->PATT4   = 0xFCFCFCFCU;
978   Device->PIO4    = 0xFCFCFCFCU;
979 
980   return HAL_OK;
981 }
982 
983 /**
984   * @}
985   */
986 #endif /* FMC_BANK4 */
987 
988 
989 /**
990   * @}
991   */
992 
993 /**
994   * @}
995   */
996 
997 #endif /* HAL_NOR_MODULE_ENABLED */
998 /**
999   * @}
1000   */
1001 /**
1002   * @}
1003   */
1004