1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_fmc.c
4   * @author  MCD Application Team
5   * @version V1.5.1
6   * @date    22-May-2015
7   * @brief   This file provides firmware functions to manage the following
8   *          functionalities of the FMC peripheral:
9   *           + Interface with SRAM, PSRAM, NOR and OneNAND memories
10   *           + Interface with NAND memories
11   *           + Interface with 16-bit PC Card compatible memories
12   *           + Interface with SDRAM memories
13   *           + Interrupts and flags management
14   *
15   ******************************************************************************
16   * @attention
17   *
18   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
19   *
20   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
21   * You may not use this file except in compliance with the License.
22   * You may obtain a copy of the License at:
23   *
24   *        http://www.st.com/software_license_agreement_liberty_v2
25   *
26   * Unless required by applicable law or agreed to in writing, software
27   * distributed under the License is distributed on an "AS IS" BASIS,
28   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29   * See the License for the specific language governing permissions and
30   * limitations under the License.
31   *
32   ******************************************************************************
33   */
34 
35 /* Includes ------------------------------------------------------------------*/
36 #include "stm32f4xx_fmc.h"
37 #include "stm32f4xx_rcc.h"
38 
39 /** @addtogroup STM32F4xx_StdPeriph_Driver
40   * @{
41   */
42 
43 /** @defgroup FMC
44   * @brief FMC driver modules
45   * @{
46   */
47 
48 /* Private typedef -----------------------------------------------------------*/
49 const FMC_NORSRAMTimingInitTypeDef FMC_DefaultTimingStruct = {0x0F, /* FMC_AddressSetupTime */
50                                                               0x0F, /* FMC_AddressHoldTime */
51                                                               0xFF, /* FMC_DataSetupTime */
52                                                               0x0F, /* FMC_BusTurnAroundDuration */
53                                                               0x0F, /* FMC_CLKDivision */
54                                                               0x0F, /* FMC_DataLatency */
55                                                               FMC_AccessMode_A /* FMC_AccessMode */
56                                                               };
57 /* --------------------- FMC registers bit mask ---------------------------- */
58 /* FMC BCRx Mask */
59 #define BCR_MBKEN_SET              ((uint32_t)0x00000001)
60 #define BCR_MBKEN_RESET            ((uint32_t)0x000FFFFE)
61 #define BCR_FACCEN_SET             ((uint32_t)0x00000040)
62 
63 /* FMC PCRx Mask */
64 #define PCR_PBKEN_SET              ((uint32_t)0x00000004)
65 #define PCR_PBKEN_RESET            ((uint32_t)0x000FFFFB)
66 #define PCR_ECCEN_SET              ((uint32_t)0x00000040)
67 #define PCR_ECCEN_RESET            ((uint32_t)0x000FFFBF)
68 #define PCR_MEMORYTYPE_NAND        ((uint32_t)0x00000008)
69 
70 /* FMC SDCRx write protection Mask*/
71 #define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF)
72 
73 /* FMC SDCMR Mask*/
74 #define SDCMR_CTB1_RESET           ((uint32_t)0x003FFFEF)
75 #define SDCMR_CTB2_RESET           ((uint32_t)0x003FFFF7)
76 #define SDCMR_CTB1_2_RESET         ((uint32_t)0x003FFFE7)
77 
78 /* Private macro -------------------------------------------------------------*/
79 /* Private variables ---------------------------------------------------------*/
80 /* Private function prototypes -----------------------------------------------*/
81 /* Private functions ---------------------------------------------------------*/
82 
83 /** @defgroup FMC_Private_Functions
84   * @{
85   */
86 
87 /** @defgroup FMC_Group1 NOR/SRAM Controller functions
88   * @brief    NOR/SRAM Controller functions
89   *
90 @verbatim
91  ===============================================================================
92                     ##### NOR and SRAM Controller functions #####
93  ===============================================================================
94 
95  [..] The following sequence should be followed to configure the FMC to interface
96       with SRAM, PSRAM, NOR or OneNAND memory connected to the NOR/SRAM Bank:
97 
98    (#) Enable the clock for the FMC and associated GPIOs using the following functions:
99           RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
100           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
101 
102    (#) FMC pins configuration
103        (++) Connect the involved FMC pins to AF12 using the following function
104             GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FMC);
105        (++) Configure these FMC pins in alternate function mode by calling the function
106             GPIO_Init();
107 
108    (#) Declare a FMC_NORSRAMInitTypeDef structure, for example:
109           FMC_NORSRAMInitTypeDef  FMC_NORSRAMInitStructure;
110       and fill the FMC_NORSRAMInitStructure variable with the allowed values of
111       the structure member.
112 
113    (#) Initialize the NOR/SRAM Controller by calling the function
114           FMC_NORSRAMInit(&FMC_NORSRAMInitStructure);
115 
116    (#) Then enable the NOR/SRAM Bank, for example:
117           FMC_NORSRAMCmd(FMC_Bank1_NORSRAM2, ENABLE);
118 
119    (#) At this stage you can read/write from/to the memory connected to the NOR/SRAM Bank.
120 
121 @endverbatim
122   * @{
123   */
124 
125 /**
126   * @brief  De-initializes the FMC NOR/SRAM Banks registers to their default
127   *   reset values.
128   * @param  FMC_Bank: specifies the FMC Bank to be used
129   *          This parameter can be one of the following values:
130   *            @arg FMC_Bank1_NORSRAM1: FMC Bank1 NOR/SRAM1
131   *            @arg FMC_Bank1_NORSRAM2: FMC Bank1 NOR/SRAM2
132   *            @arg FMC_Bank1_NORSRAM3: FMC Bank1 NOR/SRAM3
133   *            @arg FMC_Bank1_NORSRAM4: FMC Bank1 NOR/SRAM4
134   * @retval None
135   */
FMC_NORSRAMDeInit(uint32_t FMC_Bank)136 void FMC_NORSRAMDeInit(uint32_t FMC_Bank)
137 {
138   /* Check the parameter */
139   assert_param(IS_FMC_NORSRAM_BANK(FMC_Bank));
140 
141   /* FMC_Bank1_NORSRAM1 */
142   if(FMC_Bank == FMC_Bank1_NORSRAM1)
143   {
144     FMC_Bank1->BTCR[FMC_Bank] = 0x000030DB;
145   }
146   /* FMC_Bank1_NORSRAM2,  FMC_Bank1_NORSRAM3 or FMC_Bank1_NORSRAM4 */
147   else
148   {
149     FMC_Bank1->BTCR[FMC_Bank] = 0x000030D2;
150   }
151   FMC_Bank1->BTCR[FMC_Bank + 1] = 0x0FFFFFFF;
152   FMC_Bank1E->BWTR[FMC_Bank] = 0x0FFFFFFF;
153 }
154 
155 /**
156   * @brief  Initializes the FMC NOR/SRAM Banks according to the specified
157   *         parameters in the FMC_NORSRAMInitStruct.
158   * @param  FMC_NORSRAMInitStruct : pointer to a FMC_NORSRAMInitTypeDef structure
159   *         that contains the configuration information for the FMC NOR/SRAM
160   *         specified Banks.
161   * @retval None
162   */
FMC_NORSRAMInit(FMC_NORSRAMInitTypeDef * FMC_NORSRAMInitStruct)163 void FMC_NORSRAMInit(FMC_NORSRAMInitTypeDef* FMC_NORSRAMInitStruct)
164 {
165   uint32_t tmpr = 0, tmpbcr = 0;
166 
167   /* Check the parameters */
168   assert_param(IS_FMC_NORSRAM_BANK(FMC_NORSRAMInitStruct->FMC_Bank));
169   assert_param(IS_FMC_MUX(FMC_NORSRAMInitStruct->FMC_DataAddressMux));
170   assert_param(IS_FMC_MEMORY(FMC_NORSRAMInitStruct->FMC_MemoryType));
171   assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(FMC_NORSRAMInitStruct->FMC_MemoryDataWidth));
172   assert_param(IS_FMC_BURSTMODE(FMC_NORSRAMInitStruct->FMC_BurstAccessMode));
173   assert_param(IS_FMC_WAIT_POLARITY(FMC_NORSRAMInitStruct->FMC_WaitSignalPolarity));
174   assert_param(IS_FMC_WRAP_MODE(FMC_NORSRAMInitStruct->FMC_WrapMode));
175   assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(FMC_NORSRAMInitStruct->FMC_WaitSignalActive));
176   assert_param(IS_FMC_WRITE_OPERATION(FMC_NORSRAMInitStruct->FMC_WriteOperation));
177   assert_param(IS_FMC_WAITE_SIGNAL(FMC_NORSRAMInitStruct->FMC_WaitSignal));
178   assert_param(IS_FMC_EXTENDED_MODE(FMC_NORSRAMInitStruct->FMC_ExtendedMode));
179   assert_param(IS_FMC_ASYNWAIT(FMC_NORSRAMInitStruct->FMC_AsynchronousWait));
180   assert_param(IS_FMC_WRITE_BURST(FMC_NORSRAMInitStruct->FMC_WriteBurst));
181   assert_param(IS_FMC_CONTINOUS_CLOCK(FMC_NORSRAMInitStruct->FMC_ContinousClock));
182   assert_param(IS_FMC_ADDRESS_SETUP_TIME(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AddressSetupTime));
183   assert_param(IS_FMC_ADDRESS_HOLD_TIME(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AddressHoldTime));
184   assert_param(IS_FMC_DATASETUP_TIME(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_DataSetupTime));
185   assert_param(IS_FMC_TURNAROUND_TIME(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_BusTurnAroundDuration));
186   assert_param(IS_FMC_CLK_DIV(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_CLKDivision));
187   assert_param(IS_FMC_DATA_LATENCY(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_DataLatency));
188   assert_param(IS_FMC_ACCESS_MODE(FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AccessMode));
189 
190   /* Get the BTCR register value */
191   tmpbcr = FMC_Bank1->BTCR[FMC_NORSRAMInitStruct->FMC_Bank];
192 
193   /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WRAPMOD, WAITCFG, WREN,
194            WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW and CCLKEN bits */
195   tmpbcr &= ((uint32_t)~(FMC_BCR1_MBKEN   | FMC_BCR1_MUXEN    | FMC_BCR1_MTYP     | \
196                          FMC_BCR1_MWID     | FMC_BCR1_FACCEN   | FMC_BCR1_BURSTEN  | \
197                          FMC_BCR1_WAITPOL  | FMC_BCR1_WRAPMOD  | FMC_BCR1_WAITCFG  | \
198                          FMC_BCR1_WREN     | FMC_BCR1_WAITEN   | FMC_BCR1_EXTMOD   | \
199                          FMC_BCR1_ASYNCWAIT| FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN));
200 
201   /* NOR/SRAM Bank control register configuration */
202   tmpbcr |=  (uint32_t)FMC_NORSRAMInitStruct->FMC_DataAddressMux |
203                        FMC_NORSRAMInitStruct->FMC_MemoryType |
204                        FMC_NORSRAMInitStruct->FMC_MemoryDataWidth |
205                        FMC_NORSRAMInitStruct->FMC_BurstAccessMode |
206                        FMC_NORSRAMInitStruct->FMC_WaitSignalPolarity |
207                        FMC_NORSRAMInitStruct->FMC_WrapMode |
208                        FMC_NORSRAMInitStruct->FMC_WaitSignalActive |
209                        FMC_NORSRAMInitStruct->FMC_WriteOperation |
210                        FMC_NORSRAMInitStruct->FMC_WaitSignal |
211                        FMC_NORSRAMInitStruct->FMC_ExtendedMode |
212                        FMC_NORSRAMInitStruct->FMC_AsynchronousWait |
213                        FMC_NORSRAMInitStruct->FMC_WriteBurst |
214                        FMC_NORSRAMInitStruct->FMC_ContinousClock;
215 
216   FMC_Bank1->BTCR[FMC_NORSRAMInitStruct->FMC_Bank] = tmpbcr;
217 
218   if(FMC_NORSRAMInitStruct->FMC_MemoryType == FMC_MemoryType_NOR)
219   {
220     FMC_Bank1->BTCR[FMC_NORSRAMInitStruct->FMC_Bank] |= (uint32_t)BCR_FACCEN_SET;
221   }
222 
223   /* Configure Continuous clock feature when bank2..4 is used */
224   if((FMC_NORSRAMInitStruct->FMC_ContinousClock == FMC_CClock_SyncAsync) && (FMC_NORSRAMInitStruct->FMC_Bank != FMC_Bank1_NORSRAM1))
225   {
226     tmpr = (uint32_t)((FMC_Bank1->BTCR[FMC_Bank1_NORSRAM1+1]) & ~(((uint32_t)0x0F) << 20));
227 
228     FMC_Bank1->BTCR[FMC_Bank1_NORSRAM1]  |= FMC_NORSRAMInitStruct->FMC_ContinousClock;
229     FMC_Bank1->BTCR[FMC_Bank1_NORSRAM1]  |= FMC_BurstAccessMode_Enable;
230     FMC_Bank1->BTCR[FMC_Bank1_NORSRAM1+1] = (uint32_t)(tmpr | (((FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_CLKDivision)-1) << 20));
231   }
232 
233   /* NOR/SRAM Bank timing register configuration */
234   FMC_Bank1->BTCR[FMC_NORSRAMInitStruct->FMC_Bank+1] =
235             (uint32_t)FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AddressSetupTime |
236                       (FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AddressHoldTime << 4) |
237                       (FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_DataSetupTime << 8) |
238                       (FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_BusTurnAroundDuration << 16) |
239                       ((FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_CLKDivision) << 20) |
240                       ((FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_DataLatency) << 24) |
241                       FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct->FMC_AccessMode;
242 
243   /* NOR/SRAM Bank timing register for write configuration, if extended mode is used */
244   if(FMC_NORSRAMInitStruct->FMC_ExtendedMode == FMC_ExtendedMode_Enable)
245   {
246     assert_param(IS_FMC_ADDRESS_SETUP_TIME(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AddressSetupTime));
247     assert_param(IS_FMC_ADDRESS_HOLD_TIME(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AddressHoldTime));
248     assert_param(IS_FMC_DATASETUP_TIME(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_DataSetupTime));
249     assert_param(IS_FMC_CLK_DIV(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_CLKDivision));
250     assert_param(IS_FMC_DATA_LATENCY(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_DataLatency));
251     assert_param(IS_FMC_ACCESS_MODE(FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AccessMode));
252 
253     FMC_Bank1E->BWTR[FMC_NORSRAMInitStruct->FMC_Bank] =
254                (uint32_t)FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AddressSetupTime |
255                          (FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AddressHoldTime << 4 )|
256                          (FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_DataSetupTime << 8) |
257                          ((FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_CLKDivision) << 20) |
258                          ((FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_DataLatency) << 24) |
259                          FMC_NORSRAMInitStruct->FMC_WriteTimingStruct->FMC_AccessMode;
260   }
261   else
262   {
263     FMC_Bank1E->BWTR[FMC_NORSRAMInitStruct->FMC_Bank] = 0x0FFFFFFF;
264   }
265 
266 }
267 
268 /**
269   * @brief  Fills each FMC_NORSRAMInitStruct member with its default value.
270   * @param  FMC_NORSRAMInitStruct: pointer to a FMC_NORSRAMInitTypeDef structure
271   *         which will be initialized.
272   * @retval None
273   */
FMC_NORSRAMStructInit(FMC_NORSRAMInitTypeDef * FMC_NORSRAMInitStruct)274 void FMC_NORSRAMStructInit(FMC_NORSRAMInitTypeDef* FMC_NORSRAMInitStruct)
275 {
276   /* Reset NOR/SRAM Init structure parameters values */
277   FMC_NORSRAMInitStruct->FMC_Bank = FMC_Bank1_NORSRAM1;
278   FMC_NORSRAMInitStruct->FMC_DataAddressMux = FMC_DataAddressMux_Enable;
279   FMC_NORSRAMInitStruct->FMC_MemoryType = FMC_MemoryType_SRAM;
280   FMC_NORSRAMInitStruct->FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_16b;
281   FMC_NORSRAMInitStruct->FMC_BurstAccessMode = FMC_BurstAccessMode_Disable;
282   FMC_NORSRAMInitStruct->FMC_AsynchronousWait = FMC_AsynchronousWait_Disable;
283   FMC_NORSRAMInitStruct->FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low;
284   FMC_NORSRAMInitStruct->FMC_WrapMode = FMC_WrapMode_Disable;
285   FMC_NORSRAMInitStruct->FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState;
286   FMC_NORSRAMInitStruct->FMC_WriteOperation = FMC_WriteOperation_Enable;
287   FMC_NORSRAMInitStruct->FMC_WaitSignal = FMC_WaitSignal_Enable;
288   FMC_NORSRAMInitStruct->FMC_ExtendedMode = FMC_ExtendedMode_Disable;
289   FMC_NORSRAMInitStruct->FMC_WriteBurst = FMC_WriteBurst_Disable;
290   FMC_NORSRAMInitStruct->FMC_ContinousClock = FMC_CClock_SyncOnly;
291 
292   FMC_NORSRAMInitStruct->FMC_ReadWriteTimingStruct = (FMC_NORSRAMTimingInitTypeDef*)&FMC_DefaultTimingStruct;
293   FMC_NORSRAMInitStruct->FMC_WriteTimingStruct = (FMC_NORSRAMTimingInitTypeDef*)&FMC_DefaultTimingStruct;
294 }
295 
296 /**
297   * @brief  Enables or disables the specified NOR/SRAM Memory Bank.
298   * @param  FMC_Bank: specifies the FMC Bank to be used
299   *          This parameter can be one of the following values:
300   *            @arg FMC_Bank1_NORSRAM1: FMC Bank1 NOR/SRAM1
301   *            @arg FMC_Bank1_NORSRAM2: FMC Bank1 NOR/SRAM2
302   *            @arg FMC_Bank1_NORSRAM3: FMC Bank1 NOR/SRAM3
303   *            @arg FMC_Bank1_NORSRAM4: FMC Bank1 NOR/SRAM4
304   * @param  NewState: new state of the FMC_Bank. This parameter can be: ENABLE or DISABLE.
305   * @retval None
306   */
FMC_NORSRAMCmd(uint32_t FMC_Bank,FunctionalState NewState)307 void FMC_NORSRAMCmd(uint32_t FMC_Bank, FunctionalState NewState)
308 {
309   assert_param(IS_FMC_NORSRAM_BANK(FMC_Bank));
310   assert_param(IS_FUNCTIONAL_STATE(NewState));
311 
312   if (NewState != DISABLE)
313   {
314     /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */
315     FMC_Bank1->BTCR[FMC_Bank] |= BCR_MBKEN_SET;
316   }
317   else
318   {
319     /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */
320     FMC_Bank1->BTCR[FMC_Bank] &= BCR_MBKEN_RESET;
321   }
322 }
323 /**
324   * @}
325   */
326 
327 /** @defgroup FMC_Group2 NAND Controller functions
328   * @brief    NAND Controller functions
329   *
330 @verbatim
331  ===============================================================================
332                     ##### NAND Controller functions #####
333  ===============================================================================
334 
335  [..]  The following sequence should be followed to configure the FMC to interface
336        with 8-bit or 16-bit NAND memory connected to the NAND Bank:
337 
338   (#) Enable the clock for the FMC and associated GPIOs using the following functions:
339       (++)  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
340       (++)  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
341 
342   (#) FMC pins configuration
343       (++) Connect the involved FMC pins to AF12 using the following function
344            GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FMC);
345       (++) Configure these FMC pins in alternate function mode by calling the function
346            GPIO_Init();
347 
348   (#) Declare a FMC_NANDInitTypeDef structure, for example:
349       FMC_NANDInitTypeDef  FMC_NANDInitStructure;
350       and fill the FMC_NANDInitStructure variable with the allowed values of
351       the structure member.
352 
353   (#) Initialize the NAND Controller by calling the function
354       FMC_NANDInit(&FMC_NANDInitStructure);
355 
356   (#) Then enable the NAND Bank, for example:
357       FMC_NANDCmd(FMC_Bank3_NAND, ENABLE);
358 
359   (#) At this stage you can read/write from/to the memory connected to the NAND Bank.
360 
361  [..]
362   (@) To enable the Error Correction Code (ECC), you have to use the function
363       FMC_NANDECCCmd(FMC_Bank3_NAND, ENABLE);
364  [..]
365   (@) and to get the current ECC value you have to use the function
366       ECCval = FMC_GetECC(FMC_Bank3_NAND);
367 
368 @endverbatim
369   * @{
370   */
371 
372 /**
373   * @brief  De-initializes the FMC NAND Banks registers to their default reset values.
374   * @param  FMC_Bank: specifies the FMC Bank to be used
375   *          This parameter can be one of the following values:
376   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
377   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
378   * @retval None
379   */
FMC_NANDDeInit(uint32_t FMC_Bank)380 void FMC_NANDDeInit(uint32_t FMC_Bank)
381 {
382   /* Check the parameter */
383   assert_param(IS_FMC_NAND_BANK(FMC_Bank));
384 
385   if(FMC_Bank == FMC_Bank2_NAND)
386   {
387     /* Set the FMC_Bank2 registers to their reset values */
388     FMC_Bank2->PCR2 = 0x00000018;
389     FMC_Bank2->SR2 = 0x00000040;
390     FMC_Bank2->PMEM2 = 0xFCFCFCFC;
391     FMC_Bank2->PATT2 = 0xFCFCFCFC;
392   }
393   /* FMC_Bank3_NAND */
394   else
395   {
396     /* Set the FMC_Bank3 registers to their reset values */
397     FMC_Bank3->PCR3 = 0x00000018;
398     FMC_Bank3->SR3 = 0x00000040;
399     FMC_Bank3->PMEM3 = 0xFCFCFCFC;
400     FMC_Bank3->PATT3 = 0xFCFCFCFC;
401   }
402 }
403 
404 /**
405   * @brief  Initializes the FMC NAND Banks according to the specified parameters
406   *         in the FMC_NANDInitStruct.
407   * @param  FMC_NANDInitStruct : pointer to a FMC_NANDInitTypeDef structure that
408   *         contains the configuration information for the FMC NAND specified Banks.
409   * @retval None
410   */
FMC_NANDInit(FMC_NANDInitTypeDef * FMC_NANDInitStruct)411 void FMC_NANDInit(FMC_NANDInitTypeDef* FMC_NANDInitStruct)
412 {
413   uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000;
414 
415   /* Check the parameters */
416   assert_param(IS_FMC_NAND_BANK(FMC_NANDInitStruct->FMC_Bank));
417   assert_param(IS_FMC_WAIT_FEATURE(FMC_NANDInitStruct->FMC_Waitfeature));
418   assert_param(IS_FMC_NAND_MEMORY_WIDTH(FMC_NANDInitStruct->FMC_MemoryDataWidth));
419   assert_param(IS_FMC_ECC_STATE(FMC_NANDInitStruct->FMC_ECC));
420   assert_param(IS_FMC_ECCPAGE_SIZE(FMC_NANDInitStruct->FMC_ECCPageSize));
421   assert_param(IS_FMC_TCLR_TIME(FMC_NANDInitStruct->FMC_TCLRSetupTime));
422   assert_param(IS_FMC_TAR_TIME(FMC_NANDInitStruct->FMC_TARSetupTime));
423   assert_param(IS_FMC_SETUP_TIME(FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime));
424   assert_param(IS_FMC_WAIT_TIME(FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime));
425   assert_param(IS_FMC_HOLD_TIME(FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime));
426   assert_param(IS_FMC_HIZ_TIME(FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime));
427   assert_param(IS_FMC_SETUP_TIME(FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime));
428   assert_param(IS_FMC_WAIT_TIME(FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime));
429   assert_param(IS_FMC_HOLD_TIME(FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime));
430   assert_param(IS_FMC_HIZ_TIME(FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime));
431 
432   if(FMC_NANDInitStruct->FMC_Bank == FMC_Bank2_NAND)
433   {
434     /* Get the NAND bank 2 register value */
435     tmppcr = FMC_Bank2->PCR2;
436   }
437   else
438   {
439     /* Get the NAND bank 3 register value */
440     tmppcr = FMC_Bank3->PCR3;
441   }
442 
443   /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */
444   tmppcr &= ((uint32_t)~(FMC_PCR2_PWAITEN  | FMC_PCR2_PBKEN | FMC_PCR2_PTYP | \
445                        FMC_PCR2_PWID | FMC_PCR2_ECCEN | FMC_PCR2_TCLR | \
446                        FMC_PCR2_TAR | FMC_PCR2_ECCPS));
447 
448   /* Set the tmppcr value according to FMC_NANDInitStruct parameters */
449   tmppcr |= (uint32_t)FMC_NANDInitStruct->FMC_Waitfeature |
450                       PCR_MEMORYTYPE_NAND |
451                       FMC_NANDInitStruct->FMC_MemoryDataWidth |
452                       FMC_NANDInitStruct->FMC_ECC |
453                       FMC_NANDInitStruct->FMC_ECCPageSize |
454                       (FMC_NANDInitStruct->FMC_TCLRSetupTime << 9 )|
455                       (FMC_NANDInitStruct->FMC_TARSetupTime << 13);
456 
457   if(FMC_NANDInitStruct->FMC_Bank == FMC_Bank2_NAND)
458   {
459     /* Get the NAND bank 2 register value */
460     tmppmem = FMC_Bank2->PMEM2;
461   }
462   else
463   {
464     /* Get the NAND bank 3 register value */
465     tmppmem = FMC_Bank3->PMEM3;
466   }
467 
468   /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */
469   tmppmem &= ((uint32_t)~(FMC_PMEM2_MEMSET2  | FMC_PMEM2_MEMWAIT2 | FMC_PMEM2_MEMHOLD2 | \
470                           FMC_PMEM2_MEMHIZ2));
471 
472   /* Set tmppmem value according to FMC_CommonSpaceTimingStructure parameters */
473   tmppmem |= (uint32_t)FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime |
474                        (FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime << 8) |
475                        (FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime << 16)|
476                        (FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime << 24);
477 
478   if(FMC_NANDInitStruct->FMC_Bank == FMC_Bank2_NAND)
479   {
480     /* Get the NAND bank 2 register value */
481     tmppatt = FMC_Bank2->PATT2;
482   }
483   else
484   {
485     /* Get the NAND bank 3 register value */
486     tmppatt = FMC_Bank3->PATT3;
487   }
488 
489   /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */
490   tmppatt &= ((uint32_t)~(FMC_PATT2_ATTSET2  | FMC_PATT2_ATTWAIT2 | FMC_PATT2_ATTHOLD2 | \
491                        FMC_PATT2_ATTHIZ2));
492 
493   /* Set tmppatt value according to FMC_AttributeSpaceTimingStructure parameters */
494   tmppatt |= (uint32_t)FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime |
495                       (FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime << 8) |
496                       (FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime << 16)|
497                       (FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime << 24);
498 
499   if(FMC_NANDInitStruct->FMC_Bank == FMC_Bank2_NAND)
500   {
501     /* FMC_Bank2_NAND registers configuration */
502     FMC_Bank2->PCR2 = tmppcr;
503     FMC_Bank2->PMEM2 = tmppmem;
504     FMC_Bank2->PATT2 = tmppatt;
505   }
506   else
507   {
508     /* FMC_Bank3_NAND registers configuration */
509     FMC_Bank3->PCR3 = tmppcr;
510     FMC_Bank3->PMEM3 = tmppmem;
511     FMC_Bank3->PATT3 = tmppatt;
512   }
513 }
514 
515 
516 /**
517   * @brief  Fills each FMC_NANDInitStruct member with its default value.
518   * @param  FMC_NANDInitStruct: pointer to a FMC_NANDInitTypeDef structure which
519   *         will be initialized.
520   * @retval None
521   */
FMC_NANDStructInit(FMC_NANDInitTypeDef * FMC_NANDInitStruct)522 void FMC_NANDStructInit(FMC_NANDInitTypeDef* FMC_NANDInitStruct)
523 {
524   /* Reset NAND Init structure parameters values */
525   FMC_NANDInitStruct->FMC_Bank = FMC_Bank2_NAND;
526   FMC_NANDInitStruct->FMC_Waitfeature = FMC_Waitfeature_Disable;
527   FMC_NANDInitStruct->FMC_MemoryDataWidth = FMC_NAND_MemoryDataWidth_16b;
528   FMC_NANDInitStruct->FMC_ECC = FMC_ECC_Disable;
529   FMC_NANDInitStruct->FMC_ECCPageSize = FMC_ECCPageSize_256Bytes;
530   FMC_NANDInitStruct->FMC_TCLRSetupTime = 0x0;
531   FMC_NANDInitStruct->FMC_TARSetupTime = 0x0;
532   FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime = 252;
533   FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime = 252;
534   FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime = 252;
535   FMC_NANDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime = 252;
536   FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime = 252;
537   FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime = 252;
538   FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime = 252;
539   FMC_NANDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime = 252;
540 }
541 
542 /**
543   * @brief  Enables or disables the specified NAND Memory Bank.
544   * @param  FMC_Bank: specifies the FMC Bank to be used
545   *          This parameter can be one of the following values:
546   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
547   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
548   * @param  NewState: new state of the FMC_Bank. This parameter can be: ENABLE or DISABLE.
549   * @retval None
550   */
FMC_NANDCmd(uint32_t FMC_Bank,FunctionalState NewState)551 void FMC_NANDCmd(uint32_t FMC_Bank, FunctionalState NewState)
552 {
553   assert_param(IS_FMC_NAND_BANK(FMC_Bank));
554   assert_param(IS_FUNCTIONAL_STATE(NewState));
555 
556   if (NewState != DISABLE)
557   {
558     /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */
559     if(FMC_Bank == FMC_Bank2_NAND)
560     {
561       FMC_Bank2->PCR2 |= PCR_PBKEN_SET;
562     }
563     else
564     {
565       FMC_Bank3->PCR3 |= PCR_PBKEN_SET;
566     }
567   }
568   else
569   {
570     /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */
571     if(FMC_Bank == FMC_Bank2_NAND)
572     {
573       FMC_Bank2->PCR2 &= PCR_PBKEN_RESET;
574     }
575     else
576     {
577       FMC_Bank3->PCR3 &= PCR_PBKEN_RESET;
578     }
579   }
580 }
581 /**
582   * @brief  Enables or disables the FMC NAND ECC feature.
583   * @param  FMC_Bank: specifies the FMC Bank to be used
584   *          This parameter can be one of the following values:
585   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
586   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
587   * @param  NewState: new state of the FMC NAND ECC feature.
588   *          This parameter can be: ENABLE or DISABLE.
589   * @retval None
590   */
FMC_NANDECCCmd(uint32_t FMC_Bank,FunctionalState NewState)591 void FMC_NANDECCCmd(uint32_t FMC_Bank, FunctionalState NewState)
592 {
593   assert_param(IS_FMC_NAND_BANK(FMC_Bank));
594   assert_param(IS_FUNCTIONAL_STATE(NewState));
595 
596   if (NewState != DISABLE)
597   {
598     /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */
599     if(FMC_Bank == FMC_Bank2_NAND)
600     {
601       FMC_Bank2->PCR2 |= PCR_ECCEN_SET;
602     }
603     else
604     {
605       FMC_Bank3->PCR3 |= PCR_ECCEN_SET;
606     }
607   }
608   else
609   {
610     /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */
611     if(FMC_Bank == FMC_Bank2_NAND)
612     {
613       FMC_Bank2->PCR2 &= PCR_ECCEN_RESET;
614     }
615     else
616     {
617       FMC_Bank3->PCR3 &= PCR_ECCEN_RESET;
618     }
619   }
620 }
621 
622 /**
623   * @brief  Returns the error correction code register value.
624   * @param  FMC_Bank: specifies the FMC Bank to be used
625   *          This parameter can be one of the following values:
626   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
627   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
628   * @retval The Error Correction Code (ECC) value.
629   */
FMC_GetECC(uint32_t FMC_Bank)630 uint32_t FMC_GetECC(uint32_t FMC_Bank)
631 {
632   uint32_t eccval = 0x00000000;
633 
634   if(FMC_Bank == FMC_Bank2_NAND)
635   {
636     /* Get the ECCR2 register value */
637     eccval = FMC_Bank2->ECCR2;
638   }
639   else
640   {
641     /* Get the ECCR3 register value */
642     eccval = FMC_Bank3->ECCR3;
643   }
644   /* Return the error correction code value */
645   return(eccval);
646 }
647 /**
648   * @}
649   */
650 
651 /** @defgroup FMC_Group3 PCCARD Controller functions
652   * @brief    PCCARD Controller functions
653   *
654 @verbatim
655  ===============================================================================
656                     ##### PCCARD Controller functions #####
657  ===============================================================================
658 
659  [..]  he following sequence should be followed to configure the FMC to interface
660        with 16-bit PC Card compatible memory connected to the PCCARD Bank:
661 
662   (#)  Enable the clock for the FMC and associated GPIOs using the following functions:
663        (++)  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
664        (++)  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
665 
666   (#) FMC pins configuration
667        (++) Connect the involved FMC pins to AF12 using the following function
668             GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FMC);
669        (++) Configure these FMC pins in alternate function mode by calling the function
670             GPIO_Init();
671 
672   (#) Declare a FMC_PCCARDInitTypeDef structure, for example:
673       FMC_PCCARDInitTypeDef  FMC_PCCARDInitStructure;
674       and fill the FMC_PCCARDInitStructure variable with the allowed values of
675       the structure member.
676 
677   (#) Initialize the PCCARD Controller by calling the function
678       FMC_PCCARDInit(&FMC_PCCARDInitStructure);
679 
680   (#) Then enable the PCCARD Bank:
681       FMC_PCCARDCmd(ENABLE);
682 
683   (#) At this stage you can read/write from/to the memory connected to the PCCARD Bank.
684 
685 @endverbatim
686   * @{
687   */
688 
689 /**
690   * @brief  De-initializes the FMC PCCARD Bank registers to their default reset values.
691   * @param  None
692   * @retval None
693   */
FMC_PCCARDDeInit(void)694 void FMC_PCCARDDeInit(void)
695 {
696   /* Set the FMC_Bank4 registers to their reset values */
697   FMC_Bank4->PCR4 = 0x00000018;
698   FMC_Bank4->SR4 = 0x00000000;
699   FMC_Bank4->PMEM4 = 0xFCFCFCFC;
700   FMC_Bank4->PATT4 = 0xFCFCFCFC;
701   FMC_Bank4->PIO4 = 0xFCFCFCFC;
702 }
703 
704 /**
705   * @brief  Initializes the FMC PCCARD Bank according to the specified parameters
706   *         in the FMC_PCCARDInitStruct.
707   * @param  FMC_PCCARDInitStruct : pointer to a FMC_PCCARDInitTypeDef structure
708   *         that contains the configuration information for the FMC PCCARD Bank.
709   * @retval None
710   */
FMC_PCCARDInit(FMC_PCCARDInitTypeDef * FMC_PCCARDInitStruct)711 void FMC_PCCARDInit(FMC_PCCARDInitTypeDef* FMC_PCCARDInitStruct)
712 {
713   /* temporary registers */
714   uint32_t tmppcr = 0, tmpmem = 0, tmppatt = 0, tmppio = 0;
715 
716   /* Check the parameters */
717   assert_param(IS_FMC_WAIT_FEATURE(FMC_PCCARDInitStruct->FMC_Waitfeature));
718   assert_param(IS_FMC_TCLR_TIME(FMC_PCCARDInitStruct->FMC_TCLRSetupTime));
719   assert_param(IS_FMC_TAR_TIME(FMC_PCCARDInitStruct->FMC_TARSetupTime));
720 
721   assert_param(IS_FMC_SETUP_TIME(FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime));
722   assert_param(IS_FMC_WAIT_TIME(FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime));
723   assert_param(IS_FMC_HOLD_TIME(FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime));
724   assert_param(IS_FMC_HIZ_TIME(FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime));
725 
726   assert_param(IS_FMC_SETUP_TIME(FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime));
727   assert_param(IS_FMC_WAIT_TIME(FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime));
728   assert_param(IS_FMC_HOLD_TIME(FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime));
729   assert_param(IS_FMC_HIZ_TIME(FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime));
730   assert_param(IS_FMC_SETUP_TIME(FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_SetupTime));
731   assert_param(IS_FMC_WAIT_TIME(FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_WaitSetupTime));
732   assert_param(IS_FMC_HOLD_TIME(FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HoldSetupTime));
733   assert_param(IS_FMC_HIZ_TIME(FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HiZSetupTime));
734 
735   /* Get PCCARD control register value */
736   tmppcr = FMC_Bank4->PCR4;
737 
738   /* Clear TAR, TCLR, PWAITEN and PWID bits */
739   tmppcr &= ((uint32_t)~(FMC_PCR4_TAR  | FMC_PCR4_TCLR | FMC_PCR4_PWAITEN | \
740                          FMC_PCR4_PWID));
741 
742   /* Set the PCR4 register value according to FMC_PCCARDInitStruct parameters */
743   tmppcr |= (uint32_t)FMC_PCCARDInitStruct->FMC_Waitfeature |
744                       FMC_NAND_MemoryDataWidth_16b |
745                       (FMC_PCCARDInitStruct->FMC_TCLRSetupTime << 9) |
746                       (FMC_PCCARDInitStruct->FMC_TARSetupTime << 13);
747 
748   FMC_Bank4->PCR4 = tmppcr;
749 
750   /* Get PCCARD common space timing register value */
751   tmpmem = FMC_Bank4->PMEM4;
752 
753   /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */
754   tmpmem &= ((uint32_t)~(FMC_PMEM4_MEMSET4  | FMC_PMEM4_MEMWAIT4 | FMC_PMEM4_MEMHOLD4 | \
755                          FMC_PMEM4_MEMHIZ4));
756 
757   /* Set PMEM4 register value according to FMC_CommonSpaceTimingStructure parameters */
758   tmpmem |= (uint32_t)FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime |
759                       (FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime << 8) |
760                       (FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime << 16)|
761                       (FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime << 24);
762 
763   FMC_Bank4->PMEM4 = tmpmem;
764 
765   /* Get PCCARD timing parameters */
766   tmppatt = FMC_Bank4->PATT4;
767 
768   /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */
769   tmppatt &= ((uint32_t)~(FMC_PATT4_ATTSET4  | FMC_PATT4_ATTWAIT4 | FMC_PATT4_ATTHOLD4 | \
770                           FMC_PATT4_ATTHIZ4));
771 
772   /* Set PATT4 register value according to FMC_AttributeSpaceTimingStructure parameters */
773   tmppatt |= (uint32_t)FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime |
774                        (FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime << 8) |
775                        (FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime << 16)|
776                        (FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime << 24);
777 
778   FMC_Bank4->PATT4 = tmppatt;
779 
780   /* Get FMC_PCCARD device timing parameters */
781   tmppio = FMC_Bank4->PIO4;
782 
783   /* Clear IOSET4, IOWAIT4, IOHOLD4 and IOHIZ4 bits */
784   tmppio &= ((uint32_t)~(FMC_PIO4_IOSET4  | FMC_PIO4_IOWAIT4 | FMC_PIO4_IOHOLD4 | \
785                          FMC_PIO4_IOHIZ4));
786 
787   /* Set PIO4 register value according to FMC_IOSpaceTimingStructure parameters */
788   tmppio |= (uint32_t)FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_SetupTime |
789                       (FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_WaitSetupTime << 8) |
790                       (FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HoldSetupTime << 16)|
791                       (FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HiZSetupTime << 24);
792 
793   FMC_Bank4->PIO4 = tmppio;
794 }
795 
796 /**
797   * @brief  Fills each FMC_PCCARDInitStruct member with its default value.
798   * @param  FMC_PCCARDInitStruct: pointer to a FMC_PCCARDInitTypeDef structure
799   *         which will be initialized.
800   * @retval None
801   */
FMC_PCCARDStructInit(FMC_PCCARDInitTypeDef * FMC_PCCARDInitStruct)802 void FMC_PCCARDStructInit(FMC_PCCARDInitTypeDef* FMC_PCCARDInitStruct)
803 {
804   /* Reset PCCARD Init structure parameters values */
805   FMC_PCCARDInitStruct->FMC_Waitfeature = FMC_Waitfeature_Disable;
806   FMC_PCCARDInitStruct->FMC_TCLRSetupTime = 0;
807   FMC_PCCARDInitStruct->FMC_TARSetupTime = 0;
808   FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_SetupTime = 252;
809   FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime = 252;
810   FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime = 252;
811   FMC_PCCARDInitStruct->FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime = 252;
812   FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_SetupTime = 252;
813   FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime = 252;
814   FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime = 252;
815   FMC_PCCARDInitStruct->FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime = 252;
816   FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_SetupTime = 252;
817   FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_WaitSetupTime = 252;
818   FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HoldSetupTime = 252;
819   FMC_PCCARDInitStruct->FMC_IOSpaceTimingStruct->FMC_HiZSetupTime = 252;
820 }
821 
822 /**
823   * @brief  Enables or disables the PCCARD Memory Bank.
824   * @param  NewState: new state of the PCCARD Memory Bank.
825   *          This parameter can be: ENABLE or DISABLE.
826   * @retval None
827   */
FMC_PCCARDCmd(FunctionalState NewState)828 void FMC_PCCARDCmd(FunctionalState NewState)
829 {
830   assert_param(IS_FUNCTIONAL_STATE(NewState));
831 
832   if (NewState != DISABLE)
833   {
834     /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */
835     FMC_Bank4->PCR4 |= PCR_PBKEN_SET;
836   }
837   else
838   {
839     /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */
840     FMC_Bank4->PCR4 &= PCR_PBKEN_RESET;
841   }
842 }
843 
844 /**
845   * @}
846   */
847 
848 /** @defgroup FMC_Group4  SDRAM Controller functions
849   * @brief    SDRAM Controller functions
850   *
851 @verbatim
852  ===============================================================================
853                      ##### SDRAM Controller functions #####
854  ===============================================================================
855 
856  [..]  The following sequence should be followed to configure the FMC to interface
857        with SDRAM memory connected to the SDRAM Bank 1 or SDRAM bank 2:
858 
859   (#) Enable the clock for the FMC and associated GPIOs using the following functions:
860       (++) RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
861       (++) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
862 
863   (#) FMC pins configuration
864       (++) Connect the involved FMC pins to AF12 using the following function
865            GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FMC);
866       (++) Configure these FMC pins in alternate function mode by calling the function
867            GPIO_Init();
868 
869   (#) Declare a FMC_SDRAMInitTypeDef structure, for example:
870        FMC_SDRAMInitTypeDef  FMC_SDRAMInitStructure;
871       and fill the FMC_SDRAMInitStructure variable with the allowed values of
872       the structure member.
873 
874   (#) Initialize the SDRAM Controller by calling the function
875           FMC_SDRAMInit(&FMC_SDRAMInitStructure);
876 
877   (#) Declare a FMC_SDRAMCommandTypeDef structure, for example:
878         FMC_SDRAMCommandTypeDef  FMC_SDRAMCommandStructure;
879       and fill the FMC_SDRAMCommandStructure variable with the allowed values of
880       the structure member.
881 
882   (#) Configure the SDCMR register with the desired command parameters by calling
883       the function FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
884 
885   (#) At this stage, the SDRAM memory is ready for any valid command.
886 
887 @endverbatim
888   * @{
889   */
890 
891 /**
892   * @brief  De-initializes the FMC SDRAM Banks registers to their default
893   *         reset values.
894   * @param  FMC_Bank: specifies the FMC Bank to be used
895   *          This parameter can be one of the following values:
896   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
897   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
898   * @retval None
899   */
FMC_SDRAMDeInit(uint32_t FMC_Bank)900 void FMC_SDRAMDeInit(uint32_t FMC_Bank)
901 {
902   /* Check the parameter */
903   assert_param(IS_FMC_SDRAM_BANK(FMC_Bank));
904 
905   FMC_Bank5_6->SDCR[FMC_Bank] = 0x000002D0;
906   FMC_Bank5_6->SDTR[FMC_Bank] = 0x0FFFFFFF;
907   FMC_Bank5_6->SDCMR = 0x00000000;
908   FMC_Bank5_6->SDRTR = 0x00000000;
909   FMC_Bank5_6->SDSR = 0x00000000;
910 }
911 
912 /**
913   * @brief  Initializes the FMC SDRAM Banks according to the specified
914   *         parameters in the FMC_SDRAMInitStruct.
915   * @param  FMC_SDRAMInitStruct : pointer to a FMC_SDRAMInitTypeDef structure
916   *         that contains the configuration information for the FMC SDRAM
917   *         specified Banks.
918   * @retval None
919   */
FMC_SDRAMInit(FMC_SDRAMInitTypeDef * FMC_SDRAMInitStruct)920 void FMC_SDRAMInit(FMC_SDRAMInitTypeDef* FMC_SDRAMInitStruct)
921 {
922   /* temporary registers */
923   uint32_t tmpr1 = 0, tmpr2 = 0, tmpr3 = 0, tmpr4 = 0;
924 
925   /* Check the parameters */
926 
927   /* Control parameters */
928   assert_param(IS_FMC_SDRAM_BANK(FMC_SDRAMInitStruct->FMC_Bank));
929   assert_param(IS_FMC_COLUMNBITS_NUMBER(FMC_SDRAMInitStruct->FMC_ColumnBitsNumber));
930   assert_param(IS_FMC_ROWBITS_NUMBER(FMC_SDRAMInitStruct->FMC_RowBitsNumber));
931   assert_param(IS_FMC_SDMEMORY_WIDTH(FMC_SDRAMInitStruct->FMC_SDMemoryDataWidth));
932   assert_param(IS_FMC_INTERNALBANK_NUMBER(FMC_SDRAMInitStruct->FMC_InternalBankNumber));
933   assert_param(IS_FMC_CAS_LATENCY(FMC_SDRAMInitStruct->FMC_CASLatency));
934   assert_param(IS_FMC_WRITE_PROTECTION(FMC_SDRAMInitStruct->FMC_WriteProtection));
935   assert_param(IS_FMC_SDCLOCK_PERIOD(FMC_SDRAMInitStruct->FMC_SDClockPeriod));
936   assert_param(IS_FMC_READ_BURST(FMC_SDRAMInitStruct->FMC_ReadBurst));
937   assert_param(IS_FMC_READPIPE_DELAY(FMC_SDRAMInitStruct->FMC_ReadPipeDelay));
938 
939   /* Timing parameters */
940   assert_param(IS_FMC_LOADTOACTIVE_DELAY(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_LoadToActiveDelay));
941   assert_param(IS_FMC_EXITSELFREFRESH_DELAY(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_ExitSelfRefreshDelay));
942   assert_param(IS_FMC_SELFREFRESH_TIME(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_SelfRefreshTime));
943   assert_param(IS_FMC_ROWCYCLE_DELAY(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RowCycleDelay));
944   assert_param(IS_FMC_WRITE_RECOVERY_TIME(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_WriteRecoveryTime));
945   assert_param(IS_FMC_RP_DELAY(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RPDelay));
946   assert_param(IS_FMC_RCD_DELAY(FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RCDDelay));
947 
948   /* Get SDRAM register value */
949   tmpr1 = FMC_Bank5_6->SDCR[FMC_SDRAMInitStruct->FMC_Bank];
950 
951   /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
952   tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \
953                         FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \
954                         FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
955 
956   /* SDRAM bank control register configuration */
957   tmpr1 |=   (uint32_t)FMC_SDRAMInitStruct->FMC_ColumnBitsNumber |
958                        FMC_SDRAMInitStruct->FMC_RowBitsNumber |
959                        FMC_SDRAMInitStruct->FMC_SDMemoryDataWidth |
960                        FMC_SDRAMInitStruct->FMC_InternalBankNumber |
961                        FMC_SDRAMInitStruct->FMC_CASLatency |
962                        FMC_SDRAMInitStruct->FMC_WriteProtection |
963                        FMC_SDRAMInitStruct->FMC_SDClockPeriod |
964                        FMC_SDRAMInitStruct->FMC_ReadBurst |
965                        FMC_SDRAMInitStruct->FMC_ReadPipeDelay;
966 
967   if(FMC_SDRAMInitStruct->FMC_Bank == FMC_Bank1_SDRAM )
968   {
969     FMC_Bank5_6->SDCR[FMC_SDRAMInitStruct->FMC_Bank] = tmpr1;
970   }
971   else   /* SDCR2 "don't care" bits configuration */
972   {
973     /* Get SDCR register value */
974     tmpr3 = FMC_Bank5_6->SDCR[FMC_Bank1_SDRAM];
975 
976     /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
977     tmpr3 &= ((uint32_t)~(FMC_SDCR1_NC  | FMC_SDCR1_NR | FMC_SDCR1_MWID | \
978                           FMC_SDCR1_NB  | FMC_SDCR1_CAS | FMC_SDCR1_WP | \
979                           FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
980 
981     tmpr3 |= (uint32_t)FMC_SDRAMInitStruct->FMC_SDClockPeriod |
982                        FMC_SDRAMInitStruct->FMC_ReadBurst |
983                        FMC_SDRAMInitStruct->FMC_ReadPipeDelay;
984 
985     FMC_Bank5_6->SDCR[FMC_Bank1_SDRAM] = tmpr3;
986     FMC_Bank5_6->SDCR[FMC_SDRAMInitStruct->FMC_Bank] = tmpr1;
987   }
988   /* SDRAM bank timing register configuration */
989   if(FMC_SDRAMInitStruct->FMC_Bank == FMC_Bank1_SDRAM )
990   {
991     /* Get SDTR register value */
992     tmpr2 = FMC_Bank5_6->SDTR[FMC_SDRAMInitStruct->FMC_Bank];
993 
994     /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
995     tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \
996                           FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \
997                           FMC_SDTR1_TRCD));
998 
999     tmpr2 |=   (uint32_t)((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_LoadToActiveDelay)-1) |
1000                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_ExitSelfRefreshDelay)-1) << 4) |
1001                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_SelfRefreshTime)-1) << 8) |
1002                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RowCycleDelay)-1) << 12) |
1003                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_WriteRecoveryTime)-1) << 16) |
1004                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RPDelay)-1) << 20) |
1005                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RCDDelay)-1) << 24);
1006 
1007             FMC_Bank5_6->SDTR[FMC_SDRAMInitStruct->FMC_Bank] = tmpr2;
1008   }
1009   else   /* SDTR "don't care bits configuration */
1010   {
1011     /* Get SDTR register value */
1012     tmpr2 = FMC_Bank5_6->SDTR[FMC_SDRAMInitStruct->FMC_Bank];
1013 
1014     /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
1015     tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \
1016                           FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \
1017                           FMC_SDTR1_TRCD));
1018 
1019     tmpr2 |=   (uint32_t)((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_LoadToActiveDelay)-1) |
1020                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_ExitSelfRefreshDelay)-1) << 4) |
1021                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_SelfRefreshTime)-1) << 8) |
1022                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_WriteRecoveryTime)-1) << 16);
1023 
1024     /* Get SDTR register value */
1025     tmpr4 = FMC_Bank5_6->SDTR[FMC_Bank1_SDRAM];
1026 
1027     /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
1028     tmpr4 &= ((uint32_t)~(FMC_SDTR1_TMRD  | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \
1029                           FMC_SDTR1_TRC  | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \
1030                           FMC_SDTR1_TRCD));
1031 
1032     tmpr4 |=   (uint32_t)(((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RowCycleDelay)-1) << 12) |
1033                           (((FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RPDelay)-1) << 20);
1034 
1035             FMC_Bank5_6->SDTR[FMC_Bank1_SDRAM] = tmpr4;
1036             FMC_Bank5_6->SDTR[FMC_SDRAMInitStruct->FMC_Bank] = tmpr2;
1037   }
1038 
1039 }
1040 
1041 /**
1042   * @brief  Fills each FMC_SDRAMInitStruct member with its default value.
1043   * @param  FMC_SDRAMInitStruct: pointer to a FMC_SDRAMInitTypeDef structure
1044   *         which will be initialized.
1045   * @retval None
1046   */
FMC_SDRAMStructInit(FMC_SDRAMInitTypeDef * FMC_SDRAMInitStruct)1047 void FMC_SDRAMStructInit(FMC_SDRAMInitTypeDef* FMC_SDRAMInitStruct)
1048 {
1049   /* Reset SDRAM Init structure parameters values */
1050   FMC_SDRAMInitStruct->FMC_Bank = FMC_Bank1_SDRAM;
1051   FMC_SDRAMInitStruct->FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
1052   FMC_SDRAMInitStruct->FMC_RowBitsNumber = FMC_RowBits_Number_11b;
1053   FMC_SDRAMInitStruct->FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;
1054   FMC_SDRAMInitStruct->FMC_InternalBankNumber = FMC_InternalBank_Number_4;
1055   FMC_SDRAMInitStruct->FMC_CASLatency = FMC_CAS_Latency_1;
1056   FMC_SDRAMInitStruct->FMC_WriteProtection = FMC_Write_Protection_Enable;
1057   FMC_SDRAMInitStruct->FMC_SDClockPeriod = FMC_SDClock_Disable;
1058   FMC_SDRAMInitStruct->FMC_ReadBurst = FMC_Read_Burst_Disable;
1059   FMC_SDRAMInitStruct->FMC_ReadPipeDelay = FMC_ReadPipe_Delay_0;
1060 
1061   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_LoadToActiveDelay = 16;
1062   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_ExitSelfRefreshDelay = 16;
1063   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_SelfRefreshTime = 16;
1064   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RowCycleDelay = 16;
1065   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_WriteRecoveryTime = 16;
1066   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RPDelay = 16;
1067   FMC_SDRAMInitStruct->FMC_SDRAMTimingStruct->FMC_RCDDelay = 16;
1068 
1069 }
1070 
1071 /**
1072   * @brief  Configures the SDRAM memory command issued when the device is accessed.
1073   * @param  FMC_SDRAMCommandStruct: pointer to a FMC_SDRAMCommandTypeDef structure
1074   *         which will be configured.
1075   * @retval None
1076   */
FMC_SDRAMCmdConfig(FMC_SDRAMCommandTypeDef * FMC_SDRAMCommandStruct)1077 void FMC_SDRAMCmdConfig(FMC_SDRAMCommandTypeDef* FMC_SDRAMCommandStruct)
1078 {
1079   uint32_t tmpr = 0x0;
1080 
1081   /* check parameters */
1082   assert_param(IS_FMC_COMMAND_MODE(FMC_SDRAMCommandStruct->FMC_CommandMode));
1083   assert_param(IS_FMC_COMMAND_TARGET(FMC_SDRAMCommandStruct->FMC_CommandTarget));
1084   assert_param(IS_FMC_AUTOREFRESH_NUMBER(FMC_SDRAMCommandStruct->FMC_AutoRefreshNumber));
1085   assert_param(IS_FMC_MODE_REGISTER(FMC_SDRAMCommandStruct->FMC_ModeRegisterDefinition));
1086 
1087   tmpr =   (uint32_t)(FMC_SDRAMCommandStruct->FMC_CommandMode |
1088                       FMC_SDRAMCommandStruct->FMC_CommandTarget |
1089                      (((FMC_SDRAMCommandStruct->FMC_AutoRefreshNumber)-1)<<5) |
1090                      ((FMC_SDRAMCommandStruct->FMC_ModeRegisterDefinition)<<9));
1091 
1092   FMC_Bank5_6->SDCMR = tmpr;
1093 
1094 }
1095 
1096 
1097 /**
1098   * @brief  Returns the indicated FMC SDRAM bank mode status.
1099   * @param  SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be
1100   *                     FMC_Bank1_SDRAM or FMC_Bank2_SDRAM.
1101   * @retval The FMC SDRAM bank mode status
1102   */
FMC_GetModeStatus(uint32_t SDRAM_Bank)1103 uint32_t FMC_GetModeStatus(uint32_t SDRAM_Bank)
1104 {
1105   uint32_t tmpreg = 0;
1106 
1107   /* Check the parameter */
1108   assert_param(IS_FMC_SDRAM_BANK(SDRAM_Bank));
1109 
1110   /* Get the busy flag status */
1111   if(SDRAM_Bank == FMC_Bank1_SDRAM)
1112   {
1113     tmpreg = (uint32_t)(FMC_Bank5_6->SDSR & FMC_SDSR_MODES1);
1114   }
1115   else
1116   {
1117     tmpreg = ((uint32_t)(FMC_Bank5_6->SDSR & FMC_SDSR_MODES2) >> 2);
1118   }
1119 
1120   /* Return the mode status */
1121   return tmpreg;
1122 }
1123 
1124 /**
1125   * @brief  defines the SDRAM Memory Refresh rate.
1126   * @param  FMC_Count: specifies the Refresh timer count.
1127   * @retval None
1128   */
FMC_SetRefreshCount(uint32_t FMC_Count)1129 void FMC_SetRefreshCount(uint32_t FMC_Count)
1130 {
1131   /* check the parameters */
1132   assert_param(IS_FMC_REFRESH_COUNT(FMC_Count));
1133 
1134   FMC_Bank5_6->SDRTR |= (FMC_Count<<1);
1135 
1136 }
1137 
1138 /**
1139   * @brief  Sets the Number of consecutive SDRAM Memory auto Refresh commands.
1140   * @param  FMC_Number: specifies the auto Refresh number.
1141   * @retval None
1142   */
FMC_SetAutoRefresh_Number(uint32_t FMC_Number)1143 void FMC_SetAutoRefresh_Number(uint32_t FMC_Number)
1144 {
1145   /* check the parameters */
1146   assert_param(IS_FMC_AUTOREFRESH_NUMBER(FMC_Number));
1147 
1148   FMC_Bank5_6->SDCMR |= (FMC_Number << 5);
1149 }
1150 
1151 /**
1152   * @brief  Enables or disables write protection to the specified FMC SDRAM Bank.
1153   * @param  SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be
1154   *                     FMC_Bank1_SDRAM or FMC_Bank2_SDRAM.
1155   * @param  NewState: new state of the write protection flag.
1156   *          This parameter can be: ENABLE or DISABLE.
1157   * @retval None
1158   */
FMC_SDRAMWriteProtectionConfig(uint32_t SDRAM_Bank,FunctionalState NewState)1159 void FMC_SDRAMWriteProtectionConfig(uint32_t SDRAM_Bank, FunctionalState NewState)
1160 {
1161   /* Check the parameter */
1162   assert_param(IS_FUNCTIONAL_STATE(NewState));
1163   assert_param(IS_FMC_SDRAM_BANK(SDRAM_Bank));
1164 
1165   if (NewState != DISABLE)
1166   {
1167     FMC_Bank5_6->SDCR[SDRAM_Bank] |= FMC_Write_Protection_Enable;
1168   }
1169   else
1170   {
1171     FMC_Bank5_6->SDCR[SDRAM_Bank] &= SDCR_WriteProtection_RESET;
1172   }
1173 
1174 }
1175 
1176 /**
1177   * @}
1178   */
1179 
1180 /** @defgroup FMC_Group5  Interrupts and flags management functions
1181   * @brief    Interrupts and flags management functions
1182   *
1183 @verbatim
1184  ===============================================================================
1185              ##### Interrupts and flags management functions #####
1186  ===============================================================================
1187 
1188 @endverbatim
1189   * @{
1190   */
1191 
1192 /**
1193   * @brief  Enables or disables the specified FMC interrupts.
1194   * @param  FMC_Bank: specifies the FMC Bank to be used
1195   *          This parameter can be one of the following values:
1196   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
1197   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
1198   *            @arg FMC_Bank4_PCCARD: FMC Bank4 PCCARD
1199   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
1200   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
1201   * @param  FMC_IT: specifies the FMC interrupt sources to be enabled or disabled.
1202   *          This parameter can be any combination of the following values:
1203   *            @arg FMC_IT_RisingEdge: Rising edge detection interrupt.
1204   *            @arg FMC_IT_Level: Level edge detection interrupt.
1205   *            @arg FMC_IT_FallingEdge: Falling edge detection interrupt.
1206   *            @arg FMC_IT_Refresh: Refresh error detection interrupt.
1207   * @param  NewState: new state of the specified FMC interrupts.
1208   *          This parameter can be: ENABLE or DISABLE.
1209   * @retval None
1210   */
FMC_ITConfig(uint32_t FMC_Bank,uint32_t FMC_IT,FunctionalState NewState)1211 void FMC_ITConfig(uint32_t FMC_Bank, uint32_t FMC_IT, FunctionalState NewState)
1212 {
1213   assert_param(IS_FMC_IT_BANK(FMC_Bank));
1214   assert_param(IS_FMC_IT(FMC_IT));
1215   assert_param(IS_FUNCTIONAL_STATE(NewState));
1216 
1217   if (NewState != DISABLE)
1218   {
1219     /* Enable the selected FMC_Bank2 interrupts */
1220     if(FMC_Bank == FMC_Bank2_NAND)
1221     {
1222       FMC_Bank2->SR2 |= FMC_IT;
1223     }
1224     /* Enable the selected FMC_Bank3 interrupts */
1225     else if (FMC_Bank == FMC_Bank3_NAND)
1226     {
1227       FMC_Bank3->SR3 |= FMC_IT;
1228     }
1229     /* Enable the selected FMC_Bank4 interrupts */
1230     else if (FMC_Bank == FMC_Bank4_PCCARD)
1231     {
1232       FMC_Bank4->SR4 |= FMC_IT;
1233     }
1234     /* Enable the selected FMC_Bank5_6 interrupt */
1235     else
1236     {
1237       /* Enables the interrupt if the refresh error flag is set */
1238       FMC_Bank5_6->SDRTR |= FMC_IT;
1239     }
1240   }
1241   else
1242   {
1243     /* Disable the selected FMC_Bank2 interrupts */
1244     if(FMC_Bank == FMC_Bank2_NAND)
1245     {
1246 
1247       FMC_Bank2->SR2 &= (uint32_t)~FMC_IT;
1248     }
1249     /* Disable the selected FMC_Bank3 interrupts */
1250     else if (FMC_Bank == FMC_Bank3_NAND)
1251     {
1252       FMC_Bank3->SR3 &= (uint32_t)~FMC_IT;
1253     }
1254     /* Disable the selected FMC_Bank4 interrupts */
1255     else if(FMC_Bank == FMC_Bank4_PCCARD)
1256     {
1257       FMC_Bank4->SR4 &= (uint32_t)~FMC_IT;
1258     }
1259     /* Disable the selected FMC_Bank5_6 interrupt */
1260     else
1261     {
1262       /* Disables the interrupt if the refresh error flag is not set */
1263       FMC_Bank5_6->SDRTR &= (uint32_t)~FMC_IT;
1264     }
1265   }
1266 }
1267 
1268 /**
1269   * @brief  Checks whether the specified FMC flag is set or not.
1270   * @param  FMC_Bank: specifies the FMC Bank to be used
1271   *          This parameter can be one of the following values:
1272   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
1273   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
1274   *            @arg FMC_Bank4_PCCARD: FMC Bank4 PCCARD
1275   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
1276   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
1277   *            @arg FMC_Bank1_SDRAM | FMC_Bank2_SDRAM: FMC Bank1 or Bank2 SDRAM
1278   * @param  FMC_FLAG: specifies the flag to check.
1279   *          This parameter can be one of the following values:
1280   *            @arg FMC_FLAG_RisingEdge: Rising edge detection Flag.
1281   *            @arg FMC_FLAG_Level: Level detection Flag.
1282   *            @arg FMC_FLAG_FallingEdge: Falling edge detection Flag.
1283   *            @arg FMC_FLAG_FEMPT: Fifo empty Flag.
1284   *            @arg FMC_FLAG_Refresh: Refresh error Flag.
1285   *            @arg FMC_FLAG_Busy: Busy status Flag.
1286   * @retval The new state of FMC_FLAG (SET or RESET).
1287   */
FMC_GetFlagStatus(uint32_t FMC_Bank,uint32_t FMC_FLAG)1288 FlagStatus FMC_GetFlagStatus(uint32_t FMC_Bank, uint32_t FMC_FLAG)
1289 {
1290   FlagStatus bitstatus = RESET;
1291   uint32_t tmpsr = 0x00000000;
1292 
1293   /* Check the parameters */
1294   assert_param(IS_FMC_GETFLAG_BANK(FMC_Bank));
1295   assert_param(IS_FMC_GET_FLAG(FMC_FLAG));
1296 
1297   if(FMC_Bank == FMC_Bank2_NAND)
1298   {
1299     tmpsr = FMC_Bank2->SR2;
1300   }
1301   else if(FMC_Bank == FMC_Bank3_NAND)
1302   {
1303     tmpsr = FMC_Bank3->SR3;
1304   }
1305   else if(FMC_Bank == FMC_Bank4_PCCARD)
1306   {
1307     tmpsr = FMC_Bank4->SR4;
1308   }
1309   else
1310   {
1311     tmpsr = FMC_Bank5_6->SDSR;
1312   }
1313 
1314   /* Get the flag status */
1315   if ((tmpsr & FMC_FLAG) != FMC_FLAG )
1316   {
1317     bitstatus = RESET;
1318   }
1319   else
1320   {
1321     bitstatus = SET;
1322   }
1323   /* Return the flag status */
1324   return bitstatus;
1325 }
1326 
1327 /**
1328   * @brief  Clears the FMC's pending flags.
1329   * @param  FMC_Bank: specifies the FMC Bank to be used
1330   *          This parameter can be one of the following values:
1331   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
1332   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
1333   *            @arg FMC_Bank4_PCCARD: FMC Bank4 PCCARD
1334   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
1335   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
1336   * @param  FMC_FLAG: specifies the flag to clear.
1337   *          This parameter can be any combination of the following values:
1338   *            @arg FMC_FLAG_RisingEdge: Rising edge detection Flag.
1339   *            @arg FMC_FLAG_Level: Level detection Flag.
1340   *            @arg FMC_FLAG_FallingEdge: Falling edge detection Flag.
1341   *            @arg FMC_FLAG_Refresh: Refresh error Flag.
1342   * @retval None
1343   */
FMC_ClearFlag(uint32_t FMC_Bank,uint32_t FMC_FLAG)1344 void FMC_ClearFlag(uint32_t FMC_Bank, uint32_t FMC_FLAG)
1345 {
1346  /* Check the parameters */
1347   assert_param(IS_FMC_GETFLAG_BANK(FMC_Bank));
1348   assert_param(IS_FMC_CLEAR_FLAG(FMC_FLAG)) ;
1349 
1350   if(FMC_Bank == FMC_Bank2_NAND)
1351   {
1352     FMC_Bank2->SR2 &= (~FMC_FLAG);
1353   }
1354   else if(FMC_Bank == FMC_Bank3_NAND)
1355   {
1356     FMC_Bank3->SR3 &= (~FMC_FLAG);
1357   }
1358   else if(FMC_Bank == FMC_Bank4_PCCARD)
1359   {
1360     FMC_Bank4->SR4 &= (~FMC_FLAG);
1361   }
1362   /* FMC_Bank5_6 SDRAM*/
1363   else
1364   {
1365     FMC_Bank5_6->SDRTR &= (~FMC_FLAG);
1366   }
1367 
1368 }
1369 
1370 /**
1371   * @brief  Checks whether the specified FMC interrupt has occurred or not.
1372   * @param  FMC_Bank: specifies the FMC Bank to be used
1373   *          This parameter can be one of the following values:
1374   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
1375   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
1376   *            @arg FMC_Bank4_PCCARD: FMC Bank4 PCCARD
1377   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
1378   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
1379   * @param  FMC_IT: specifies the FMC interrupt source to check.
1380   *          This parameter can be one of the following values:
1381   *            @arg FMC_IT_RisingEdge: Rising edge detection interrupt.
1382   *            @arg FMC_IT_Level: Level edge detection interrupt.
1383   *            @arg FMC_IT_FallingEdge: Falling edge detection interrupt.
1384   *            @arg FMC_IT_Refresh: Refresh error detection interrupt.
1385   * @retval The new state of FMC_IT (SET or RESET).
1386   */
FMC_GetITStatus(uint32_t FMC_Bank,uint32_t FMC_IT)1387 ITStatus FMC_GetITStatus(uint32_t FMC_Bank, uint32_t FMC_IT)
1388 {
1389   ITStatus bitstatus = RESET;
1390   uint32_t tmpsr = 0x0;
1391   uint32_t tmpsr2 = 0x0;
1392   uint32_t itstatus = 0x0;
1393   uint32_t itenable = 0x0;
1394 
1395   /* Check the parameters */
1396   assert_param(IS_FMC_IT_BANK(FMC_Bank));
1397   assert_param(IS_FMC_GET_IT(FMC_IT));
1398 
1399   if(FMC_Bank == FMC_Bank2_NAND)
1400   {
1401     tmpsr = FMC_Bank2->SR2;
1402   }
1403   else if(FMC_Bank == FMC_Bank3_NAND)
1404   {
1405     tmpsr = FMC_Bank3->SR3;
1406   }
1407   else if(FMC_Bank == FMC_Bank4_PCCARD)
1408   {
1409     tmpsr = FMC_Bank4->SR4;
1410   }
1411   /* FMC_Bank5_6 SDRAM*/
1412   else
1413   {
1414     tmpsr = FMC_Bank5_6->SDRTR;
1415     tmpsr2 = FMC_Bank5_6->SDSR;
1416   }
1417 
1418   /* get the IT enable bit status*/
1419   itenable = tmpsr & FMC_IT;
1420 
1421   /* get the corresponding IT Flag status*/
1422   if((FMC_Bank == FMC_Bank1_SDRAM) || (FMC_Bank == FMC_Bank2_SDRAM))
1423   {
1424     itstatus = tmpsr2 & FMC_SDSR_RE;
1425   }
1426   else
1427   {
1428     itstatus = tmpsr & (FMC_IT >> 3);
1429   }
1430 
1431   if ((itstatus != (uint32_t)RESET)  && (itenable != (uint32_t)RESET))
1432   {
1433     bitstatus = SET;
1434   }
1435   else
1436   {
1437     bitstatus = RESET;
1438   }
1439   return bitstatus;
1440 }
1441 
1442 /**
1443   * @brief  Clears the FMC's interrupt pending bits.
1444   * @param  FMC_Bank: specifies the FMC Bank to be used
1445   *          This parameter can be one of the following values:
1446   *            @arg FMC_Bank2_NAND: FMC Bank2 NAND
1447   *            @arg FMC_Bank3_NAND: FMC Bank3 NAND
1448   *            @arg FMC_Bank4_PCCARD: FMC Bank4 PCCARD
1449   *            @arg FMC_Bank1_SDRAM: FMC Bank1 SDRAM
1450   *            @arg FMC_Bank2_SDRAM: FMC Bank2 SDRAM
1451   * @param  FMC_IT: specifies the interrupt pending bit to clear.
1452   *          This parameter can be any combination of the following values:
1453   *            @arg FMC_IT_RisingEdge: Rising edge detection interrupt.
1454   *            @arg FMC_IT_Level: Level edge detection interrupt.
1455   *            @arg FMC_IT_FallingEdge: Falling edge detection interrupt.
1456   *            @arg FMC_IT_Refresh: Refresh error detection interrupt.
1457   * @retval None
1458   */
FMC_ClearITPendingBit(uint32_t FMC_Bank,uint32_t FMC_IT)1459 void FMC_ClearITPendingBit(uint32_t FMC_Bank, uint32_t FMC_IT)
1460 {
1461   /* Check the parameters */
1462   assert_param(IS_FMC_IT_BANK(FMC_Bank));
1463   assert_param(IS_FMC_IT(FMC_IT));
1464 
1465   if(FMC_Bank == FMC_Bank2_NAND)
1466   {
1467     FMC_Bank2->SR2 &= ~(FMC_IT >> 3);
1468   }
1469   else if(FMC_Bank == FMC_Bank3_NAND)
1470   {
1471     FMC_Bank3->SR3 &= ~(FMC_IT >> 3);
1472   }
1473   else if(FMC_Bank == FMC_Bank4_PCCARD)
1474   {
1475     FMC_Bank4->SR4 &= ~(FMC_IT >> 3);
1476   }
1477   /* FMC_Bank5_6 SDRAM*/
1478   else
1479   {
1480     FMC_Bank5_6->SDRTR |= FMC_SDRTR_CRE;
1481   }
1482 }
1483 
1484 /**
1485   * @}
1486   */
1487 
1488 /**
1489   * @}
1490   */
1491 
1492 /**
1493   * @}
1494   */
1495 
1496 /**
1497   * @}
1498   */
1499 
1500 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1501