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