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,FSMC_NORSRAM_InitTypeDef * Init)195 HAL_StatusTypeDef  FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device,
196                                     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,FSMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)312 HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device,
313                                           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   MODIFY_REG(Device->BTCR[Bank + 1U], BTR_CLEAR_MASK, (Timing->AddressSetupTime                                  |
329                                                        ((Timing->AddressHoldTime)        << FSMC_BTR1_ADDHLD_Pos)  |
330                                                        ((Timing->DataSetupTime)          << FSMC_BTR1_DATAST_Pos)  |
331                                                        ((Timing->BusTurnAroundDuration)  << FSMC_BTR1_BUSTURN_Pos) |
332                                                        (((Timing->CLKDivision) - 1U)     << FSMC_BTR1_CLKDIV_Pos)  |
333                                                        (((Timing->DataLatency) - 2U)     << FSMC_BTR1_DATLAT_Pos)  |
334                                                        (Timing->AccessMode)));
335 
336   return HAL_OK;
337 }
338 
339 /**
340   * @brief  Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
341   *         parameters in the FSMC_NORSRAM_TimingTypeDef
342   * @param  Device Pointer to NORSRAM device instance
343   * @param  Timing Pointer to NORSRAM Timing structure
344   * @param  Bank NORSRAM bank number
345   * @param  ExtendedMode FSMC Extended Mode
346   *          This parameter can be one of the following values:
347   *            @arg FSMC_EXTENDED_MODE_DISABLE
348   *            @arg FSMC_EXTENDED_MODE_ENABLE
349   * @retval HAL status
350   */
FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef * Device,FSMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)351 HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device,
352                                                    FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
353                                                    uint32_t ExtendedMode)
354 {
355   /* Check the parameters */
356   assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
357 
358   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
359   if (ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
360   {
361     /* Check the parameters */
362     assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
363     assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
364     assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
365     assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
366     assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
367     assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
368     assert_param(IS_FSMC_NORSRAM_BANK(Bank));
369 
370     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
371     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
372                                                      ((Timing->AddressHoldTime)        << FSMC_BWTR1_ADDHLD_Pos)  |
373                                                      ((Timing->DataSetupTime)          << FSMC_BWTR1_DATAST_Pos)  |
374                                                      Timing->AccessMode                                          |
375                                                      ((Timing->BusTurnAroundDuration)  << FSMC_BWTR1_BUSTURN_Pos)));
376   }
377   else
378   {
379     Device->BWTR[Bank] = 0x0FFFFFFFU;
380   }
381 
382   return HAL_OK;
383 }
384 /**
385   * @}
386   */
387 
388 /** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group2
389   *  @brief   management functions
390   *
391 @verbatim
392   ==============================================================================
393                       ##### FSMC_NORSRAM Control functions #####
394   ==============================================================================
395   [..]
396     This subsection provides a set of functions allowing to control dynamically
397     the FSMC NORSRAM interface.
398 
399 @endverbatim
400   * @{
401   */
402 
403 /**
404   * @brief  Enables dynamically FSMC_NORSRAM write operation.
405   * @param  Device Pointer to NORSRAM device instance
406   * @param  Bank NORSRAM bank number
407   * @retval HAL status
408   */
FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef * Device,uint32_t Bank)409 HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
410 {
411   /* Check the parameters */
412   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
413   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
414 
415   /* Enable write operation */
416   SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
417 
418   return HAL_OK;
419 }
420 
421 /**
422   * @brief  Disables dynamically FSMC_NORSRAM write operation.
423   * @param  Device Pointer to NORSRAM device instance
424   * @param  Bank NORSRAM bank number
425   * @retval HAL status
426   */
FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef * Device,uint32_t Bank)427 HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
428 {
429   /* Check the parameters */
430   assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
431   assert_param(IS_FSMC_NORSRAM_BANK(Bank));
432 
433   /* Disable write operation */
434   CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
435 
436   return HAL_OK;
437 }
438 
439 /**
440   * @}
441   */
442 
443 /**
444   * @}
445   */
446 
447 
448 /** @defgroup FSMC_LL_Exported_Functions_NAND FSMC Low Layer NAND Exported Functions
449   * @brief    NAND Controller functions
450   *
451   @verbatim
452   ==============================================================================
453                     ##### How to use NAND device driver #####
454   ==============================================================================
455   [..]
456     This driver contains a set of APIs to interface with the FSMC NAND banks in order
457     to run the NAND external devices.
458 
459     (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
460     (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
461     (+) FSMC NAND bank common space timing configuration using the function
462         FSMC_NAND_CommonSpace_Timing_Init()
463     (+) FSMC NAND bank attribute space timing configuration using the function
464         FSMC_NAND_AttributeSpace_Timing_Init()
465     (+) FSMC NAND bank enable/disable ECC correction feature using the functions
466         FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
467     (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
468 
469 @endverbatim
470   * @{
471   */
472 
473 /** @defgroup FSMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
474   *  @brief    Initialization and Configuration functions
475   *
476 @verbatim
477   ==============================================================================
478               ##### Initialization and de_initialization functions #####
479   ==============================================================================
480   [..]
481     This section provides functions allowing to:
482     (+) Initialize and configure the FSMC NAND interface
483     (+) De-initialize the FSMC NAND interface
484     (+) Configure the FSMC clock and associated GPIOs
485 
486 @endverbatim
487   * @{
488   */
489 
490 /**
491   * @brief  Initializes the FSMC_NAND device according to the specified
492   *         control parameters in the FSMC_NAND_HandleTypeDef
493   * @param  Device Pointer to NAND device instance
494   * @param  Init Pointer to NAND Initialization structure
495   * @retval HAL status
496   */
FSMC_NAND_Init(FSMC_NAND_TypeDef * Device,FSMC_NAND_InitTypeDef * Init)497 HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init)
498 {
499   /* Check the parameters */
500   assert_param(IS_FSMC_NAND_DEVICE(Device));
501   assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
502   assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
503   assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
504   assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
505   assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
506   assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
507   assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
508 
509   /* Set NAND device control parameters */
510   if (Init->NandBank == FSMC_NAND_BANK2)
511   {
512     /* NAND bank 2 registers configuration */
513     MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
514                                               FSMC_PCR_MEMORY_TYPE_NAND                               |
515                                               Init->MemoryDataWidth                                  |
516                                               Init->EccComputation                                   |
517                                               Init->ECCPageSize                                      |
518                                               ((Init->TCLRSetupTime) << FSMC_PCR3_TCLR_Pos)  |
519                                               ((Init->TARSetupTime)  << FSMC_PCR3_TAR_Pos)));
520   }
521   else
522   {
523     /* NAND bank 3 registers configuration */
524     MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature                                      |
525                                               FSMC_PCR_MEMORY_TYPE_NAND                               |
526                                               Init->MemoryDataWidth                                  |
527                                               Init->EccComputation                                   |
528                                               Init->ECCPageSize                                      |
529                                               ((Init->TCLRSetupTime) << FSMC_PCR3_TCLR_Pos)  |
530                                               ((Init->TARSetupTime)  << FSMC_PCR3_TAR_Pos)));
531   }
532 
533   return HAL_OK;
534 }
535 
536 /**
537   * @brief  Initializes the FSMC_NAND Common space Timing according to the specified
538   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
539   * @param  Device Pointer to NAND device instance
540   * @param  Timing Pointer to NAND timing structure
541   * @param  Bank NAND bank number
542   * @retval HAL status
543   */
FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef * Device,FSMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)544 HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
545                                                    FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
546 {
547   /* Check the parameters */
548   assert_param(IS_FSMC_NAND_DEVICE(Device));
549   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
550   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
551   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
552   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
553   assert_param(IS_FSMC_NAND_BANK(Bank));
554 
555   /* Set FSMC_NAND device timing parameters */
556   if (Bank == FSMC_NAND_BANK2)
557   {
558     /* NAND bank 2 registers configuration */
559     MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
560                                                 ((Timing->WaitSetupTime) << FSMC_PMEM3_MEMWAIT3_Pos) |
561                                                 ((Timing->HoldSetupTime) << FSMC_PMEM3_MEMHOLD3_Pos) |
562                                                 ((Timing->HiZSetupTime)  << FSMC_PMEM3_MEMHIZ3_Pos)));
563   }
564   else
565   {
566     /* NAND bank 3 registers configuration */
567     MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime                                             |
568                                                 ((Timing->WaitSetupTime) << FSMC_PMEM3_MEMWAIT3_Pos) |
569                                                 ((Timing->HoldSetupTime) << FSMC_PMEM3_MEMHOLD3_Pos) |
570                                                 ((Timing->HiZSetupTime)  << FSMC_PMEM3_MEMHIZ3_Pos)));
571   }
572 
573   return HAL_OK;
574 }
575 
576 /**
577   * @brief  Initializes the FSMC_NAND Attribute space Timing according to the specified
578   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
579   * @param  Device Pointer to NAND device instance
580   * @param  Timing Pointer to NAND timing structure
581   * @param  Bank NAND bank number
582   * @retval HAL status
583   */
FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef * Device,FSMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)584 HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device,
585                                                       FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
586 {
587   /* Check the parameters */
588   assert_param(IS_FSMC_NAND_DEVICE(Device));
589   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
590   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
591   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
592   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
593   assert_param(IS_FSMC_NAND_BANK(Bank));
594 
595   /* Set FSMC_NAND device timing parameters */
596   if (Bank == FSMC_NAND_BANK2)
597   {
598     /* NAND bank 2 registers configuration */
599     MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
600                                                 ((Timing->WaitSetupTime) << FSMC_PATT3_ATTWAIT3_Pos) |
601                                                 ((Timing->HoldSetupTime) << FSMC_PATT3_ATTHOLD3_Pos) |
602                                                 ((Timing->HiZSetupTime)  << FSMC_PATT3_ATTHIZ3_Pos)));
603   }
604   else
605   {
606     /* NAND bank 3 registers configuration */
607     MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime                                             |
608                                                 ((Timing->WaitSetupTime) << FSMC_PATT3_ATTWAIT3_Pos) |
609                                                 ((Timing->HoldSetupTime) << FSMC_PATT3_ATTHOLD3_Pos) |
610                                                 ((Timing->HiZSetupTime)  << FSMC_PATT3_ATTHIZ3_Pos)));
611   }
612 
613   return HAL_OK;
614 }
615 
616 /**
617   * @brief  DeInitializes the FSMC_NAND device
618   * @param  Device Pointer to NAND device instance
619   * @param  Bank NAND bank number
620   * @retval HAL status
621   */
FSMC_NAND_DeInit(FSMC_NAND_TypeDef * Device,uint32_t Bank)622 HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
623 {
624   /* Check the parameters */
625   assert_param(IS_FSMC_NAND_DEVICE(Device));
626   assert_param(IS_FSMC_NAND_BANK(Bank));
627 
628   /* Disable the NAND Bank */
629   __FSMC_NAND_DISABLE(Device, Bank);
630 
631   /* De-initialize the NAND Bank */
632   if (Bank == FSMC_NAND_BANK2)
633   {
634     /* Set the FSMC_NAND_BANK2 registers to their reset values */
635     WRITE_REG(Device->PCR2,  0x00000018U);
636     WRITE_REG(Device->SR2,   0x00000040U);
637     WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
638     WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
639   }
640   /* FSMC_Bank3_NAND */
641   else
642   {
643     /* Set the FSMC_NAND_BANK3 registers to their reset values */
644     WRITE_REG(Device->PCR3,  0x00000018U);
645     WRITE_REG(Device->SR3,   0x00000040U);
646     WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
647     WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
648   }
649 
650   return HAL_OK;
651 }
652 
653 /**
654   * @}
655   */
656 
657 /** @defgroup HAL_FSMC_NAND_Group2 Peripheral Control functions
658   *  @brief   management functions
659   *
660 @verbatim
661   ==============================================================================
662                        ##### FSMC_NAND Control functions #####
663   ==============================================================================
664   [..]
665     This subsection provides a set of functions allowing to control dynamically
666     the FSMC NAND interface.
667 
668 @endverbatim
669   * @{
670   */
671 
672 
673 /**
674   * @brief  Enables dynamically FSMC_NAND ECC feature.
675   * @param  Device Pointer to NAND device instance
676   * @param  Bank NAND bank number
677   * @retval HAL status
678   */
FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef * Device,uint32_t Bank)679 HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
680 {
681   /* Check the parameters */
682   assert_param(IS_FSMC_NAND_DEVICE(Device));
683   assert_param(IS_FSMC_NAND_BANK(Bank));
684 
685   /* Enable ECC feature */
686   if (Bank == FSMC_NAND_BANK2)
687   {
688     SET_BIT(Device->PCR2, FSMC_PCR3_ECCEN);
689   }
690   else
691   {
692     SET_BIT(Device->PCR3, FSMC_PCR3_ECCEN);
693   }
694 
695   return HAL_OK;
696 }
697 
698 
699 /**
700   * @brief  Disables dynamically FSMC_NAND ECC feature.
701   * @param  Device Pointer to NAND device instance
702   * @param  Bank NAND bank number
703   * @retval HAL status
704   */
FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef * Device,uint32_t Bank)705 HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
706 {
707   /* Check the parameters */
708   assert_param(IS_FSMC_NAND_DEVICE(Device));
709   assert_param(IS_FSMC_NAND_BANK(Bank));
710 
711   /* Disable ECC feature */
712   if (Bank == FSMC_NAND_BANK2)
713   {
714     CLEAR_BIT(Device->PCR2, FSMC_PCR3_ECCEN);
715   }
716   else
717   {
718     CLEAR_BIT(Device->PCR3, FSMC_PCR3_ECCEN);
719   }
720 
721   return HAL_OK;
722 }
723 
724 /**
725   * @brief  Disables dynamically FSMC_NAND ECC feature.
726   * @param  Device Pointer to NAND device instance
727   * @param  ECCval Pointer to ECC value
728   * @param  Bank NAND bank number
729   * @param  Timeout Timeout wait value
730   * @retval HAL status
731   */
FSMC_NAND_GetECC(FSMC_NAND_TypeDef * Device,uint32_t * ECCval,uint32_t Bank,uint32_t Timeout)732 HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
733                                   uint32_t Timeout)
734 {
735   uint32_t tickstart;
736 
737   /* Check the parameters */
738   assert_param(IS_FSMC_NAND_DEVICE(Device));
739   assert_param(IS_FSMC_NAND_BANK(Bank));
740 
741   /* Get tick */
742   tickstart = HAL_GetTick();
743 
744   /* Wait until FIFO is empty */
745   while (__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
746   {
747     /* Check for the Timeout */
748     if (Timeout != HAL_MAX_DELAY)
749     {
750       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
751       {
752         return HAL_TIMEOUT;
753       }
754     }
755   }
756 
757   if (Bank == FSMC_NAND_BANK2)
758   {
759     /* Get the ECCR2 register value */
760     *ECCval = (uint32_t)Device->ECCR2;
761   }
762   else
763   {
764     /* Get the ECCR3 register value */
765     *ECCval = (uint32_t)Device->ECCR3;
766   }
767 
768   return HAL_OK;
769 }
770 
771 /**
772   * @}
773   */
774 
775 
776 /** @addtogroup FSMC_LL_PCCARD
777   * @brief    PCCARD Controller functions
778   *
779   @verbatim
780   ==============================================================================
781                     ##### How to use PCCARD device driver #####
782   ==============================================================================
783   [..]
784     This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
785     to run the PCCARD/compact flash external devices.
786 
787     (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
788     (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
789     (+) FSMC PCCARD bank common space timing configuration using the function
790         FSMC_PCCARD_CommonSpace_Timing_Init()
791     (+) FSMC PCCARD bank attribute space timing configuration using the function
792         FSMC_PCCARD_AttributeSpace_Timing_Init()
793     (+) FSMC PCCARD bank IO space timing configuration using the function
794         FSMC_PCCARD_IOSpace_Timing_Init()
795 @endverbatim
796   * @{
797   */
798 
799 /** @addtogroup FSMC_LL_PCCARD_Private_Functions_Group1
800   *  @brief    Initialization and Configuration functions
801   *
802 @verbatim
803   ==============================================================================
804               ##### Initialization and de_initialization functions #####
805   ==============================================================================
806   [..]
807     This section provides functions allowing to:
808     (+) Initialize and configure the FSMC PCCARD interface
809     (+) De-initialize the FSMC PCCARD interface
810     (+) Configure the FSMC clock and associated GPIOs
811 
812 @endverbatim
813   * @{
814   */
815 
816 /**
817   * @brief  Initializes the FSMC_PCCARD device according to the specified
818   *         control parameters in the FSMC_PCCARD_HandleTypeDef
819   * @param  Device Pointer to PCCARD device instance
820   * @param  Init Pointer to PCCARD Initialization structure
821   * @retval HAL status
822   */
FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef * Device,FSMC_PCCARD_InitTypeDef * Init)823 HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init)
824 {
825   /* Check the parameters */
826   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
827 #if defined(FSMC_BANK3)
828   assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
829   assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
830   assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
831 #endif /* FSMC_BANK3 */
832 
833   /* Set FSMC_PCCARD device control parameters */
834   MODIFY_REG(Device->PCR4,
835              (FSMC_PCR4_PTYP                                          |
836               FSMC_PCR4_PWAITEN                                       |
837               FSMC_PCR4_PWID                                          |
838               FSMC_PCR4_TCLR                                          |
839               FSMC_PCR4_TAR),
840              (FSMC_PCR_MEMORY_TYPE_PCCARD                             |
841               Init->Waitfeature                                      |
842               FSMC_NAND_PCC_MEM_BUS_WIDTH_16                          |
843               (Init->TCLRSetupTime << FSMC_PCR4_TCLR_Pos)   |
844               (Init->TARSetupTime  << FSMC_PCR4_TAR_Pos)));
845 
846   return HAL_OK;
847 }
848 
849 /**
850   * @brief  Initializes the FSMC_PCCARD Common space Timing according to the specified
851   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
852   * @param  Device Pointer to PCCARD device instance
853   * @param  Timing Pointer to PCCARD timing structure
854   * @retval HAL status
855   */
FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,FSMC_NAND_PCC_TimingTypeDef * Timing)856 HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
857                                                               FSMC_NAND_PCC_TimingTypeDef *Timing)
858 {
859   /* Check the parameters */
860   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
861 #if defined(FSMC_BANK3)
862   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
863   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
864   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
865   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
866 #endif /* FSMC_BANK3 */
867 
868   /* Set PCCARD timing parameters */
869   MODIFY_REG(Device->PMEM4, PMEM4_CLEAR_MASK,
870              (Timing->SetupTime                                              |
871               ((Timing->WaitSetupTime) << FSMC_PMEM4_MEMWAIT4_Pos)  |
872               ((Timing->HoldSetupTime) << FSMC_PMEM4_MEMHOLD4_Pos)  |
873               ((Timing->HiZSetupTime)  << FSMC_PMEM4_MEMHIZ4_Pos)));
874 
875   return HAL_OK;
876 }
877 
878 /**
879   * @brief  Initializes the FSMC_PCCARD Attribute space Timing according to the specified
880   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
881   * @param  Device Pointer to PCCARD device instance
882   * @param  Timing Pointer to PCCARD timing structure
883   * @retval HAL status
884   */
FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,FSMC_NAND_PCC_TimingTypeDef * Timing)885 HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
886                                                                  FSMC_NAND_PCC_TimingTypeDef *Timing)
887 {
888   /* Check the parameters */
889   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
890 #if defined(FSMC_BANK3)
891   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
892   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
893   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
894   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
895 #endif /* FSMC_BANK3 */
896 
897   /* Set PCCARD timing parameters */
898   MODIFY_REG(Device->PATT4, PATT4_CLEAR_MASK,
899              (Timing->SetupTime                                              |
900               ((Timing->WaitSetupTime) << FSMC_PATT4_ATTWAIT4_Pos)  |
901               ((Timing->HoldSetupTime) << FSMC_PATT4_ATTHOLD4_Pos)  |
902               ((Timing->HiZSetupTime)  << FSMC_PATT4_ATTHIZ4_Pos)));
903 
904   return HAL_OK;
905 }
906 
907 /**
908   * @brief  Initializes the FSMC_PCCARD IO space Timing according to the specified
909   *         parameters in the FSMC_NAND_PCC_TimingTypeDef
910   * @param  Device Pointer to PCCARD device instance
911   * @param  Timing Pointer to PCCARD timing structure
912   * @retval HAL status
913   */
FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef * Device,FSMC_NAND_PCC_TimingTypeDef * Timing)914 HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device,
915                                                           FSMC_NAND_PCC_TimingTypeDef *Timing)
916 {
917   /* Check the parameters */
918   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
919 #if defined(FSMC_BANK3)
920   assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
921   assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
922   assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
923   assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
924 #endif /* FSMC_BANK3 */
925 
926   /* Set FSMC_PCCARD device timing parameters */
927   MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK,
928              (Timing->SetupTime                                           |
929               (Timing->WaitSetupTime   << FSMC_PIO4_IOWAIT4_Pos) |
930               (Timing->HoldSetupTime   << FSMC_PIO4_IOHOLD4_Pos) |
931               (Timing->HiZSetupTime    << FSMC_PIO4_IOHIZ4_Pos)));
932 
933   return HAL_OK;
934 }
935 
936 /**
937   * @brief  DeInitializes the FSMC_PCCARD device
938   * @param  Device Pointer to PCCARD device instance
939   * @retval HAL status
940   */
FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef * Device)941 HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
942 {
943   /* Check the parameters */
944   assert_param(IS_FSMC_PCCARD_DEVICE(Device));
945 
946   /* Disable the FSMC_PCCARD device */
947   __FSMC_PCCARD_DISABLE(Device);
948 
949   /* De-initialize the FSMC_PCCARD device */
950   Device->PCR4    = 0x00000018U;
951   Device->SR4     = 0x00000040U;
952   Device->PMEM4   = 0xFCFCFCFCU;
953   Device->PATT4   = 0xFCFCFCFCU;
954   Device->PIO4    = 0xFCFCFCFCU;
955 
956   return HAL_OK;
957 }
958 
959 /**
960   * @}
961   */
962 
963 
964 /**
965   * @}
966   */
967 
968 /**
969   * @}
970   */
971 
972 #endif /* HAL_NOR_MODULE_ENABLED */
973 /**
974   * @}
975   */
976 /**
977   * @}
978   */
979