1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_ll_fsmc.c
4   * @author  MCD Application Team
5   * @brief   FSMC Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the Flexible Memory Controller (FSMC) 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                         ##### FSMC peripheral features #####
27   ==============================================================================
28   [..] The Flexible memory controller (FSMC) includes following memory controllers:
29        (+) The NOR/PSRAM memory controller
30        (+) The NAND/PC Card memory controller
31 
32   [..] The FSMC 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 FSMC performs
39        only one access at a time to an external device.
40        The main features of the FSMC 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 "stm32f1xx_hal.h"
58 
59 /** @addtogroup STM32F1xx_HAL_Driver
60   * @{
61   */
62 #if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) \
63     || defined(HAL_SRAM_MODULE_ENABLED)
64 
65 /** @defgroup FSMC_LL  FSMC Low Layer
66   * @brief FSMC driver modules
67   * @{
68   */
69 
70 /* Private typedef -----------------------------------------------------------*/
71 /* Private define ------------------------------------------------------------*/
72 
73 /** @defgroup FSMC_LL_Private_Constants FSMC Low Layer Private Constants
74   * @{
75   */
76 
77 /* ----------------------- FSMC registers bit mask --------------------------- */
78 
79 #if defined(FSMC_BANK1)
80 /* --- BCR Register ---*/
81 /* BCR register clear mask */
82 
83 /* --- BTR Register ---*/
84 /* BTR register clear mask */
85 #define BTR_CLEAR_MASK    ((uint32_t)(FSMC_BTRx_ADDSET | FSMC_BTRx_ADDHLD  |\
86                                       FSMC_BTRx_DATAST | FSMC_BTRx_BUSTURN |\
87                                       FSMC_BTRx_CLKDIV | FSMC_BTRx_DATLAT  |\
88                                       FSMC_BTRx_ACCMOD))
89 
90 /* --- BWTR Register ---*/
91 /* BWTR register clear mask */
92 #if defined(FSMC_BWTRx_BUSTURN)
93 #define BWTR_CLEAR_MASK   ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD  |\
94                                       FSMC_BWTRx_DATAST | FSMC_BWTRx_BUSTURN |\
95                                       FSMC_BWTRx_ACCMOD))
96 #else
97 #define BWTR_CLEAR_MASK   ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD |\
98                                       FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD |\
99                                       FSMC_BWTRx_CLKDIV | FSMC_BWTRx_DATLAT))
100 #endif /* FSMC_BWTRx_BUSTURN */
101 #endif /* FSMC_BANK1 */
102 #if defined(FSMC_BANK3)
103 
104 /* --- PCR Register ---*/
105 /* PCR register clear mask */
106 #define PCR_CLEAR_MASK    ((uint32_t)(FSMC_PCRx_PWAITEN | FSMC_PCRx_PBKEN  | \
107                                       FSMC_PCRx_PTYP    | FSMC_PCRx_PWID   | \
108                                       FSMC_PCRx_ECCEN   | FSMC_PCRx_TCLR   | \
109                                       FSMC_PCRx_TAR     | FSMC_PCRx_ECCPS))
110 /* --- PMEM Register ---*/
111 /* PMEM register clear mask */
112 #define PMEM_CLEAR_MASK   ((uint32_t)(FSMC_PMEMx_MEMSETx  | FSMC_PMEMx_MEMWAITx |\
113                                       FSMC_PMEMx_MEMHOLDx | FSMC_PMEMx_MEMHIZx))
114 
115 /* --- PATT Register ---*/
116 /* PATT register clear mask */
117 #define PATT_CLEAR_MASK   ((uint32_t)(FSMC_PATTx_ATTSETx  | FSMC_PATTx_ATTWAITx |\
118                                       FSMC_PATTx_ATTHOLDx | FSMC_PATTx_ATTHIZx))
119 
120 #endif /* FSMC_BANK3 */
121 #if defined(FSMC_BANK4)
122 /* --- PCR Register ---*/
123 /* PCR register clear mask */
124 #define PCR4_CLEAR_MASK   ((uint32_t)(FSMC_PCR4_PWAITEN | FSMC_PCR4_PBKEN  | \
125                                       FSMC_PCR4_PTYP    | FSMC_PCR4_PWID   | \
126                                       FSMC_PCR4_ECCEN   | FSMC_PCR4_TCLR   | \
127                                       FSMC_PCR4_TAR     | FSMC_PCR4_ECCPS))
128 /* --- PMEM Register ---*/
129 /* PMEM register clear mask */
130 #define PMEM4_CLEAR_MASK  ((uint32_t)(FSMC_PMEM4_MEMSET4  | FSMC_PMEM4_MEMWAIT4 |\
131                                       FSMC_PMEM4_MEMHOLD4 | FSMC_PMEM4_MEMHIZ4))
132 
133 /* --- PATT Register ---*/
134 /* PATT register clear mask */
135 #define PATT4_CLEAR_MASK  ((uint32_t)(FSMC_PATT4_ATTSET4  | FSMC_PATT4_ATTWAIT4 |\
136                                       FSMC_PATT4_ATTHOLD4 | FSMC_PATT4_ATTHIZ4))
137 
138 /* --- PIO4 Register ---*/
139 /* PIO4 register clear mask */
140 #define PIO4_CLEAR_MASK   ((uint32_t)(FSMC_PIO4_IOSET4  | FSMC_PIO4_IOWAIT4 | \
141                                       FSMC_PIO4_IOHOLD4 | FSMC_PIO4_IOHIZ4))
142 
143 #endif /* FSMC_BANK4 */
144 
145 /**
146   * @}
147   */
148 
149 /* Private macro -------------------------------------------------------------*/
150 /* Private variables ---------------------------------------------------------*/
151 /* Private function prototypes -----------------------------------------------*/
152 /* Exported functions --------------------------------------------------------*/
153 
154 /** @defgroup FSMC_LL_Exported_Functions FSMC Low Layer Exported Functions
155   * @{
156   */
157 
158 #if defined(FSMC_BANK1)
159 
160 /** @defgroup FSMC_LL_Exported_Functions_NORSRAM FSMC Low Layer NOR SRAM Exported Functions
161   * @brief  NORSRAM Controller functions
162   *
163   @verbatim
164   ==============================================================================
165                    ##### How to use NORSRAM device driver #####
166   ==============================================================================
167 
168   [..]
169     This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order
170     to run the NORSRAM external devices.
171 
172     (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit()
173     (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init()
174     (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init()
175     (+) FSMC NORSRAM bank extended timing configuration using the function
176         FSMC_NORSRAM_Extended_Timing_Init()
177     (+) FSMC NORSRAM bank enable/disable write operation using the functions
178         FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable()
179 
180 @endverbatim
181   * @{
182   */
183 
184 /** @defgroup FSMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
185   * @brief    Initialization and Configuration functions
186   *
187   @verbatim
188   ==============================================================================
189               ##### Initialization and de_initialization functions #####
190   ==============================================================================
191   [..]
192     This section provides functions allowing to:
193     (+) Initialize and configure the FSMC NORSRAM interface
194     (+) De-initialize the FSMC NORSRAM interface
195     (+) Configure the FSMC clock and associated GPIOs
196 
197 @endverbatim
198   * @{
199   */
200 
201 /**
202   * @brief  Initialize the FSMC_NORSRAM device according to the specified
203   *         control parameters in the FSMC_NORSRAM_InitTypeDef
204   * @param  Device Pointer to NORSRAM device instance
205   * @param  Init Pointer to NORSRAM Initialization structure
206   * @retval HAL status
207   */
FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef * Device,const FSMC_NORSRAM_InitTypeDef * Init)208 HAL_StatusTypeDef  FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device,
209                                      const FSMC_NORSRAM_InitTypeDef *Init)
210 {
211   uint32_t flashaccess;
212   uint32_t btcr_reg;
213   uint32_t mask;
214 
215   /* Check the parameters */
216   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
217   assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank));
218   assert_param(IS_FSMC_MUX(Init->DataAddressMux));
219   assert_param(IS_FSMC_MEMORY(Init->MemoryType));
220   assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
221   assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode));
222   assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity));
223   assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode));
224   assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
225   assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation));
226   assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal));
227   assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode));
228   assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait));
229   assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst));
230   assert_param(IS_FSMC_PAGESIZE(Init->PageSize));
231 
232   /* Disable NORSRAM Device */
233   __FSMC_NORSRAM_DISABLE(Device, Init->NSBank);
234 
235   /* Set NORSRAM device control parameters */
236   if (Init->MemoryType == FSMC_MEMORY_TYPE_NOR)
237   {
238     flashaccess = FSMC_NORSRAM_FLASH_ACCESS_ENABLE;
239   }
240   else
241   {
242     flashaccess = FSMC_NORSRAM_FLASH_ACCESS_DISABLE;
243   }
244 
245   btcr_reg = (flashaccess                   | \
246               Init->DataAddressMux          | \
247               Init->MemoryType              | \
248               Init->MemoryDataWidth         | \
249               Init->BurstAccessMode         | \
250               Init->WaitSignalPolarity      | \
251               Init->WaitSignalActive        | \
252               Init->WriteOperation          | \
253               Init->WaitSignal              | \
254               Init->ExtendedMode            | \
255               Init->AsynchronousWait        | \
256               Init->WriteBurst);
257 
258   btcr_reg |= Init->WrapMode;
259   btcr_reg |= Init->PageSize;
260 
261   mask = (FSMC_BCRx_MBKEN                |
262           FSMC_BCRx_MUXEN                |
263           FSMC_BCRx_MTYP                 |
264           FSMC_BCRx_MWID                 |
265           FSMC_BCRx_FACCEN               |
266           FSMC_BCRx_BURSTEN              |
267           FSMC_BCRx_WAITPOL              |
268           FSMC_BCRx_WAITCFG              |
269           FSMC_BCRx_WREN                 |
270           FSMC_BCRx_WAITEN               |
271           FSMC_BCRx_EXTMOD               |
272           FSMC_BCRx_ASYNCWAIT            |
273           FSMC_BCRx_CBURSTRW);
274 
275   mask |= FSMC_BCRx_WRAPMOD;
276   mask |= 0x00070000U; /* CPSIZE to be defined in CMSIS file */
277 
278   MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg);
279 
280 
281   return HAL_OK;
282 }
283 
284 /**
285   * @brief  DeInitialize the FSMC_NORSRAM peripheral
286   * @param  Device Pointer to NORSRAM device instance
287   * @param  ExDevice Pointer to NORSRAM extended mode device instance
288   * @param  Bank NORSRAM bank number
289   * @retval HAL status
290   */
FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef * Device,FSMC_NORSRAM_EXTENDED_TypeDef * ExDevice,uint32_t Bank)291 HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device,
292                                       FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
293 {
294   /* Check the parameters */
295   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
296   assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
297   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
298 
299   /* Disable the FSMC_NORSRAM device */
300   __FSMC_NORSRAM_DISABLE(Device, Bank);
301 
302   /* De-initialize the FSMC_NORSRAM device */
303   /* FSMC_NORSRAM_BANK1 */
304   if (Bank == FSMC_NORSRAM_BANK1)
305   {
306     Device->BTCR[Bank] = 0x000030DBU;
307   }
308   /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */
309   else
310   {
311     Device->BTCR[Bank] = 0x000030D2U;
312   }
313 
314   Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
315   ExDevice->BWTR[Bank]   = 0x0FFFFFFFU;
316 
317   return HAL_OK;
318 }
319 
320 /**
321   * @brief  Initialize the FSMC_NORSRAM Timing according to the specified
322   *         parameters in the FSMC_NORSRAM_TimingTypeDef
323   * @param  Device Pointer to NORSRAM device instance
324   * @param  Timing Pointer to NORSRAM Timing structure
325   * @param  Bank NORSRAM bank number
326   * @retval HAL status
327   */
FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef * Device,const FSMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)328 HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device,
329                                            const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
330 {
331 
332   /* Check the parameters */
333   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
334   assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
335   assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
336   assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
337   assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
338   assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
339   assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
340   assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
341   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
342 
343   /* Set FSMC_NORSRAM device timing parameters */
344   Device->BTCR[Bank + 1U] =
345     (Timing->AddressSetupTime << FSMC_BTRx_ADDSET_Pos) |
346     (Timing->AddressHoldTime << FSMC_BTRx_ADDHLD_Pos) |
347     (Timing->DataSetupTime << FSMC_BTRx_DATAST_Pos) |
348     (Timing->BusTurnAroundDuration << FSMC_BTRx_BUSTURN_Pos) |
349     ((Timing->CLKDivision - 1U) << FSMC_BTRx_CLKDIV_Pos) |
350     ((Timing->DataLatency - 2U) << FSMC_BTRx_DATLAT_Pos) |
351     Timing->AccessMode;
352 
353   return HAL_OK;
354 }
355 
356 /**
357   * @brief  Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
358   *         parameters in the FSMC_NORSRAM_TimingTypeDef
359   * @param  Device Pointer to NORSRAM device instance
360   * @param  Timing Pointer to NORSRAM Timing structure
361   * @param  Bank NORSRAM bank number
362   * @param  ExtendedMode FSMC Extended Mode
363   *          This parameter can be one of the following values:
364   *            @arg FSMC_EXTENDED_MODE_DISABLE
365   *            @arg FSMC_EXTENDED_MODE_ENABLE
366   * @retval HAL status
367   */
FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef * Device,const FSMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)368 HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device,
369                                                     const FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
370                                                     uint32_t ExtendedMode)
371 {
372   /* Check the parameters */
373   assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
374 
375   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
376   if (ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
377   {
378     /* Check the parameters */
379     assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
380     assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
381     assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
382     assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
383 #if defined(FSMC_BWTRx_BUSTURN)
384     assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
385 #else
386     assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
387     assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
388 #endif /* FSMC_BWTRx_BUSTURN */
389     assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
390     assert_param(IS_FSMC_NORSRAM_BANK(Bank));
391 
392     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
393 #if defined(FSMC_BWTRx_BUSTURN)
394     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
395                                                      ((Timing->AddressHoldTime)        << FSMC_BWTRx_ADDHLD_Pos)  |
396                                                      ((Timing->DataSetupTime)          << FSMC_BWTRx_DATAST_Pos)  |
397                                                      Timing->AccessMode                                          |
398                                                      ((Timing->BusTurnAroundDuration)  << FSMC_BWTRx_BUSTURN_Pos)));
399 #else
400     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
401                                                      ((Timing->AddressHoldTime)        << FSMC_BWTRx_ADDHLD_Pos)  |
402                                                      ((Timing->DataSetupTime)          << FSMC_BWTRx_DATAST_Pos)  |
403                                                      Timing->AccessMode                                          |
404                                                      (((Timing->CLKDivision) - 1U)     << FSMC_BWTRx_CLKDIV_Pos)  |
405                                                      (((Timing->DataLatency) - 2U)     << FSMC_BWTRx_DATLAT_Pos)));
406 #endif /* FSMC_BWTRx_BUSTURN */
407   }
408   else
409   {
410     Device->BWTR[Bank] = 0x0FFFFFFFU;
411   }
412 
413   return HAL_OK;
414 }
415 /**
416   * @}
417   */
418 
419 /** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group2
420   *  @brief   management functions
421   *
422 @verbatim
423   ==============================================================================
424                       ##### FSMC_NORSRAM Control functions #####
425   ==============================================================================
426   [..]
427     This subsection provides a set of functions allowing to control dynamically
428     the FSMC NORSRAM interface.
429 
430 @endverbatim
431   * @{
432   */
433 
434 /**
435   * @brief  Enables dynamically FSMC_NORSRAM write operation.
436   * @param  Device Pointer to NORSRAM device instance
437   * @param  Bank NORSRAM bank number
438   * @retval HAL status
439   */
FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef * Device,uint32_t Bank)440 HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
441 {
442   /* Check the parameters */
443   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
444   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
445 
446   /* Enable write operation */
447   SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
448 
449   return HAL_OK;
450 }
451 
452 /**
453   * @brief  Disables dynamically FSMC_NORSRAM write operation.
454   * @param  Device Pointer to NORSRAM device instance
455   * @param  Bank NORSRAM bank number
456   * @retval HAL status
457   */
FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef * Device,uint32_t Bank)458 HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
459 {
460   /* Check the parameters */
461   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
462   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
463 
464   /* Disable write operation */
465   CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
466 
467   return HAL_OK;
468 }
469 
470 /**
471   * @}
472   */
473 
474 /**
475   * @}
476   */
477 #endif /* FSMC_BANK1 */
478 
479 #if defined(FSMC_BANK3)
480 
481 /** @defgroup FSMC_LL_Exported_Functions_NAND FSMC Low Layer NAND Exported Functions
482   * @brief    NAND Controller functions
483   *
484   @verbatim
485   ==============================================================================
486                     ##### How to use NAND device driver #####
487   ==============================================================================
488   [..]
489     This driver contains a set of APIs to interface with the FSMC NAND banks in order
490     to run the NAND external devices.
491 
492     (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
493     (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
494     (+) FSMC NAND bank common space timing configuration using the function
495         FSMC_NAND_CommonSpace_Timing_Init()
496     (+) FSMC NAND bank attribute space timing configuration using the function
497         FSMC_NAND_AttributeSpace_Timing_Init()
498     (+) FSMC NAND bank enable/disable ECC correction feature using the functions
499         FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
500     (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
501 
502 @endverbatim
503   * @{
504   */
505 
506 /** @defgroup FSMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
507   *  @brief    Initialization and Configuration functions
508   *
509 @verbatim
510   ==============================================================================
511               ##### Initialization and de_initialization functions #####
512   ==============================================================================
513   [..]
514     This section provides functions allowing to:
515     (+) Initialize and configure the FSMC NAND interface
516     (+) De-initialize the FSMC NAND interface
517     (+) Configure the FSMC clock and associated GPIOs
518 
519 @endverbatim
520   * @{
521   */
522 
523 /**
524   * @brief  Initializes the FSMC_NAND device according to the specified
525   *         control parameters in the FSMC_NAND_HandleTypeDef
526   * @param  Device Pointer to NAND device instance
527   * @param  Init Pointer to NAND Initialization structure
528   * @retval HAL status
529   */
FSMC_NAND_Init(FSMC_NAND_TypeDef * Device,const FSMC_NAND_InitTypeDef * Init)530 HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, const FSMC_NAND_InitTypeDef *Init)
531 {
532   /* Check the parameters */
533   assert_param(IS_FSMC_NAND_DEVICE(Device));
534   assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
535   assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
536   assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
537   assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
538   assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
539   assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
540   assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
541 
542   /* Set NAND device control parameters */
543   if (Init->NandBank == FSMC_NAND_BANK2)
544   {
545     /* NAND bank 2 registers configuration */
546     MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
547                                               FSMC_PCR_MEMORY_TYPE_NAND                               |
548                                               Init->MemoryDataWidth                                  |
549                                               Init->EccComputation                                   |
550                                               Init->ECCPageSize                                      |
551                                               ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos)  |
552                                               ((Init->TARSetupTime)  << FSMC_PCRx_TAR_Pos)));
553   }
554   else
555   {
556     /* NAND bank 3 registers configuration */
557     MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
558                                               FSMC_PCR_MEMORY_TYPE_NAND                               |
559                                               Init->MemoryDataWidth                                  |
560                                               Init->EccComputation                                   |
561                                               Init->ECCPageSize                                      |
562                                               ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos)  |
563                                               ((Init->TARSetupTime)  << FSMC_PCRx_TAR_Pos)));
564   }
565 
566   return HAL_OK;
567 }
568 
569 /**
570   * @brief  Initializes the FSMC_NAND Common space Timing according to the specified
571   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
572   * @param  Device Pointer to NAND device instance
573   * @param  Timing Pointer to NAND timing structure
574   * @param  Bank NAND bank number
575   * @retval HAL status
576   */
FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef * Device,const FSMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)577 HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
578                                                     const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
579 {
580   /* Check the parameters */
581   assert_param(IS_FSMC_NAND_DEVICE(Device));
582   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
583   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
584   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
585   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
586   assert_param(IS_FSMC_NAND_BANK(Bank));
587 
588   /* Set FSMC_NAND device timing parameters */
589   if (Bank == FSMC_NAND_BANK2)
590   {
591     /* NAND bank 2 registers configuration */
592     MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
593                                                 ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) |
594                                                 ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) |
595                                                 ((Timing->HiZSetupTime)  << FSMC_PMEMx_MEMHIZx_Pos)));
596   }
597   else
598   {
599     /* NAND bank 3 registers configuration */
600     MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
601                                                 ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) |
602                                                 ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) |
603                                                 ((Timing->HiZSetupTime)  << FSMC_PMEMx_MEMHIZx_Pos)));
604   }
605 
606   return HAL_OK;
607 }
608 
609 /**
610   * @brief  Initializes the FSMC_NAND Attribute space Timing according to the specified
611   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
612   * @param  Device Pointer to NAND device instance
613   * @param  Timing Pointer to NAND timing structure
614   * @param  Bank NAND bank number
615   * @retval HAL status
616   */
FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef * Device,const FSMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)617 HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
618                                                        const FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
619 {
620   /* Check the parameters */
621   assert_param(IS_FSMC_NAND_DEVICE(Device));
622   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
623   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
624   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
625   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
626   assert_param(IS_FSMC_NAND_BANK(Bank));
627 
628   /* Set FSMC_NAND device timing parameters */
629   if (Bank == FSMC_NAND_BANK2)
630   {
631     /* NAND bank 2 registers configuration */
632     MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
633                                                 ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) |
634                                                 ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) |
635                                                 ((Timing->HiZSetupTime)  << FSMC_PATTx_ATTHIZx_Pos)));
636   }
637   else
638   {
639     /* NAND bank 3 registers configuration */
640     MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
641                                                 ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) |
642                                                 ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) |
643                                                 ((Timing->HiZSetupTime)  << FSMC_PATTx_ATTHIZx_Pos)));
644   }
645 
646   return HAL_OK;
647 }
648 
649 /**
650   * @brief  DeInitializes the FSMC_NAND device
651   * @param  Device Pointer to NAND device instance
652   * @param  Bank NAND bank number
653   * @retval HAL status
654   */
FSMC_NAND_DeInit(FSMC_NAND_TypeDef * Device,uint32_t Bank)655 HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
656 {
657   /* Check the parameters */
658   assert_param(IS_FSMC_NAND_DEVICE(Device));
659   assert_param(IS_FSMC_NAND_BANK(Bank));
660 
661   /* Disable the NAND Bank */
662   __FSMC_NAND_DISABLE(Device, Bank);
663 
664   /* De-initialize the NAND Bank */
665   if (Bank == FSMC_NAND_BANK2)
666   {
667     /* Set the FSMC_NAND_BANK2 registers to their reset values */
668     WRITE_REG(Device->PCR2,  0x00000018U);
669     WRITE_REG(Device->SR2,   0x00000040U);
670     WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
671     WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
672   }
673   /* FSMC_Bank3_NAND */
674   else
675   {
676     /* Set the FSMC_NAND_BANK3 registers to their reset values */
677     WRITE_REG(Device->PCR3,  0x00000018U);
678     WRITE_REG(Device->SR3,   0x00000040U);
679     WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
680     WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
681   }
682 
683   return HAL_OK;
684 }
685 
686 /**
687   * @}
688   */
689 
690 /** @defgroup HAL_FSMC_NAND_Group2 Peripheral Control functions
691   *  @brief   management functions
692   *
693 @verbatim
694   ==============================================================================
695                        ##### FSMC_NAND Control functions #####
696   ==============================================================================
697   [..]
698     This subsection provides a set of functions allowing to control dynamically
699     the FSMC NAND interface.
700 
701 @endverbatim
702   * @{
703   */
704 
705 
706 /**
707   * @brief  Enables dynamically FSMC_NAND ECC feature.
708   * @param  Device Pointer to NAND device instance
709   * @param  Bank NAND bank number
710   * @retval HAL status
711   */
FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef * Device,uint32_t Bank)712 HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
713 {
714   /* Check the parameters */
715   assert_param(IS_FSMC_NAND_DEVICE(Device));
716   assert_param(IS_FSMC_NAND_BANK(Bank));
717 
718   /* Enable ECC feature */
719   if (Bank == FSMC_NAND_BANK2)
720   {
721     SET_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
722   }
723   else
724   {
725     SET_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
726   }
727 
728   return HAL_OK;
729 }
730 
731 
732 /**
733   * @brief  Disables dynamically FSMC_NAND ECC feature.
734   * @param  Device Pointer to NAND device instance
735   * @param  Bank NAND bank number
736   * @retval HAL status
737   */
FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef * Device,uint32_t Bank)738 HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
739 {
740   /* Check the parameters */
741   assert_param(IS_FSMC_NAND_DEVICE(Device));
742   assert_param(IS_FSMC_NAND_BANK(Bank));
743 
744   /* Disable ECC feature */
745   if (Bank == FSMC_NAND_BANK2)
746   {
747     CLEAR_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
748   }
749   else
750   {
751     CLEAR_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
752   }
753 
754   return HAL_OK;
755 }
756 
757 /**
758   * @brief  Disables dynamically FSMC_NAND ECC feature.
759   * @param  Device Pointer to NAND device instance
760   * @param  ECCval Pointer to ECC value
761   * @param  Bank NAND bank number
762   * @param  Timeout Timeout wait value
763   * @retval HAL status
764   */
FSMC_NAND_GetECC(const FSMC_NAND_TypeDef * Device,uint32_t * ECCval,uint32_t Bank,uint32_t Timeout)765 HAL_StatusTypeDef FSMC_NAND_GetECC(const FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
766                                    uint32_t Timeout)
767 {
768   uint32_t tickstart;
769 
770   /* Check the parameters */
771   assert_param(IS_FSMC_NAND_DEVICE(Device));
772   assert_param(IS_FSMC_NAND_BANK(Bank));
773 
774   /* Get tick */
775   tickstart = HAL_GetTick();
776 
777   /* Wait until FIFO is empty */
778   while (__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
779   {
780     /* Check for the Timeout */
781     if (Timeout != HAL_MAX_DELAY)
782     {
783       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
784       {
785         return HAL_TIMEOUT;
786       }
787     }
788   }
789 
790   if (Bank == FSMC_NAND_BANK2)
791   {
792     /* Get the ECCR2 register value */
793     *ECCval = (uint32_t)Device->ECCR2;
794   }
795   else
796   {
797     /* Get the ECCR3 register value */
798     *ECCval = (uint32_t)Device->ECCR3;
799   }
800 
801   return HAL_OK;
802 }
803 
804 /**
805   * @}
806   */
807 #endif /* FSMC_BANK3 */
808 
809 #if defined(FSMC_BANK4)
810 
811 /** @addtogroup FSMC_LL_PCCARD
812   * @brief    PCCARD Controller functions
813   *
814   @verbatim
815   ==============================================================================
816                     ##### How to use PCCARD device driver #####
817   ==============================================================================
818   [..]
819     This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
820     to run the PCCARD/compact flash external devices.
821 
822     (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
823     (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
824     (+) FSMC PCCARD bank common space timing configuration using the function
825         FSMC_PCCARD_CommonSpace_Timing_Init()
826     (+) FSMC PCCARD bank attribute space timing configuration using the function
827         FSMC_PCCARD_AttributeSpace_Timing_Init()
828     (+) FSMC PCCARD bank IO space timing configuration using the function
829         FSMC_PCCARD_IOSpace_Timing_Init()
830 @endverbatim
831   * @{
832   */
833 
834 /** @addtogroup FSMC_LL_PCCARD_Private_Functions_Group1
835   *  @brief    Initialization and Configuration functions
836   *
837 @verbatim
838   ==============================================================================
839               ##### Initialization and de_initialization functions #####
840   ==============================================================================
841   [..]
842     This section provides functions allowing to:
843     (+) Initialize and configure the FSMC PCCARD interface
844     (+) De-initialize the FSMC PCCARD interface
845     (+) Configure the FSMC clock and associated GPIOs
846 
847 @endverbatim
848   * @{
849   */
850 
851 /**
852   * @brief  Initializes the FSMC_PCCARD device according to the specified
853   *         control parameters in the FSMC_PCCARD_HandleTypeDef
854   * @param  Device Pointer to PCCARD device instance
855   * @param  Init Pointer to PCCARD Initialization structure
856   * @retval HAL status
857   */
FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef * Device,const FSMC_PCCARD_InitTypeDef * Init)858 HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, const FSMC_PCCARD_InitTypeDef *Init)
859 {
860   /* Check the parameters */
861   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
862 #if defined(FSMC_BANK3)
863   assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
864   assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
865   assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
866 #endif /* FSMC_BANK3 */
867 
868   /* Set FSMC_PCCARD device control parameters */
869   MODIFY_REG(Device->PCR4,
870              (FSMC_PCRx_PTYP                                          |
871               FSMC_PCRx_PWAITEN                                       |
872               FSMC_PCRx_PWID                                          |
873               FSMC_PCRx_TCLR                                          |
874               FSMC_PCRx_TAR),
875              (FSMC_PCR_MEMORY_TYPE_PCCARD                             |
876               Init->Waitfeature                                      |
877               FSMC_NAND_PCC_MEM_BUS_WIDTH_16                          |
878               (Init->TCLRSetupTime << FSMC_PCRx_TCLR_Pos)   |
879               (Init->TARSetupTime  << FSMC_PCRx_TAR_Pos)));
880 
881   return HAL_OK;
882 }
883 
884 /**
885   * @brief  Initializes the FSMC_PCCARD Common space Timing according to the specified
886   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
887   * @param  Device Pointer to PCCARD device instance
888   * @param  Timing Pointer to PCCARD timing structure
889   * @retval HAL status
890   */
FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,const FSMC_NAND_PCC_TimingTypeDef * Timing)891 HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
892                                                       const FSMC_NAND_PCC_TimingTypeDef *Timing)
893 {
894   /* Check the parameters */
895   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
896 #if defined(FSMC_BANK3)
897   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
898   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
899   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
900   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
901 #endif /* FSMC_BANK3 */
902 
903   /* Set PCCARD timing parameters */
904   MODIFY_REG(Device->PMEM4, PMEM_CLEAR_MASK,
905              (Timing->SetupTime                                              |
906               ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos)  |
907               ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos)  |
908               ((Timing->HiZSetupTime)  << FSMC_PMEMx_MEMHIZx_Pos)));
909 
910   return HAL_OK;
911 }
912 
913 /**
914   * @brief  Initializes the FSMC_PCCARD Attribute space Timing according to the specified
915   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
916   * @param  Device Pointer to PCCARD device instance
917   * @param  Timing Pointer to PCCARD timing structure
918   * @retval HAL status
919   */
FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,const FSMC_NAND_PCC_TimingTypeDef * Timing)920 HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
921                                                          const FSMC_NAND_PCC_TimingTypeDef *Timing)
922 {
923   /* Check the parameters */
924   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
925 #if defined(FSMC_BANK3)
926   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
927   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
928   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
929   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
930 #endif /* FSMC_BANK3 */
931 
932   /* Set PCCARD timing parameters */
933   MODIFY_REG(Device->PATT4, PATT_CLEAR_MASK,
934              (Timing->SetupTime                                              |
935               ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos)  |
936               ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos)  |
937               ((Timing->HiZSetupTime)  << FSMC_PATTx_ATTHIZx_Pos)));
938 
939   return HAL_OK;
940 }
941 
942 /**
943   * @brief  Initializes the FSMC_PCCARD IO space Timing according to the specified
944   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
945   * @param  Device Pointer to PCCARD device instance
946   * @param  Timing Pointer to PCCARD timing structure
947   * @retval HAL status
948   */
FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,const FSMC_NAND_PCC_TimingTypeDef * Timing)949 HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
950                                                   const FSMC_NAND_PCC_TimingTypeDef *Timing)
951 {
952   /* Check the parameters */
953   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
954 #if defined(FSMC_BANK3)
955   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
956   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
957   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
958   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
959 #endif /* FSMC_BANK3 */
960 
961   /* Set FSMC_PCCARD device timing parameters */
962   MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK,
963              (Timing->SetupTime                                           |
964               (Timing->WaitSetupTime   << FSMC_PIO4_IOWAIT4_Pos) |
965               (Timing->HoldSetupTime   << FSMC_PIO4_IOHOLD4_Pos) |
966               (Timing->HiZSetupTime    << FSMC_PIO4_IOHIZ4_Pos)));
967 
968   return HAL_OK;
969 }
970 
971 /**
972   * @brief  DeInitializes the FSMC_PCCARD device
973   * @param  Device Pointer to PCCARD device instance
974   * @retval HAL status
975   */
FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef * Device)976 HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
977 {
978   /* Check the parameters */
979   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
980 
981   /* Disable the FSMC_PCCARD device */
982   __FSMC_PCCARD_DISABLE(Device);
983 
984   /* De-initialize the FSMC_PCCARD device */
985   Device->PCR4    = 0x00000018U;
986   Device->SR4     = 0x00000040U;
987   Device->PMEM4   = 0xFCFCFCFCU;
988   Device->PATT4   = 0xFCFCFCFCU;
989   Device->PIO4    = 0xFCFCFCFCU;
990 
991   return HAL_OK;
992 }
993 
994 /**
995   * @}
996   */
997 #endif /* FSMC_BANK4 */
998 
999 
1000 /**
1001   * @}
1002   */
1003 
1004 /**
1005   * @}
1006   */
1007 
1008 #endif /* HAL_NOR_MODULE_ENABLED */
1009 /**
1010   * @}
1011   */
1012 /**
1013   * @}
1014   */
1015