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