summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2016-05-22 14:21:03 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2016-05-22 14:21:03 +0300
commit8eea37e61e919819e6ef51d8a1c1bd04cfd0892a (patch)
tree416eb32745cc0992681362c7636316773c89c7e6
Initial commit of code, that initializes the two on-board SDRAM chips. Includes simple memory test program.HEADmaster
Note, that there turns out to be a bug in low-level HAL driver, so this commit includes corrected stm32f4xx_ll_fmc.c
-rw-r--r--fmc.c438
-rw-r--r--fmc.h76
-rw-r--r--gpio.c95
-rw-r--r--gpio.h72
-rw-r--r--main.c445
-rw-r--r--mxconstants.h58
-rw-r--r--stm32-sdram.c106
-rw-r--r--stm32-sdram.h43
-rw-r--r--stm32f4xx_hal_conf.h448
-rw-r--r--stm32f4xx_hal_msp.c81
-rw-r--r--stm32f4xx_it.c167
-rw-r--r--stm32f4xx_it.h62
-rw-r--r--stm32f4xx_ll_fmc.c1738
13 files changed, 3829 insertions, 0 deletions
diff --git a/fmc.c b/fmc.c
new file mode 100644
index 0000000..bd03269
--- /dev/null
+++ b/fmc.c
@@ -0,0 +1,438 @@
+/**
+ ******************************************************************************
+ * File Name : FMC.c
+ * Description : This file provides code for the configuration
+ * of the FMC peripheral.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "fmc.h"
+
+#include "gpio.h"
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+SDRAM_HandleTypeDef hsdram1;
+SDRAM_HandleTypeDef hsdram2;
+
+/* FMC initialization function */
+//-----------------------------------------------------------------------------
+void MX_FMC_Init(void)
+//-----------------------------------------------------------------------------
+{
+ // timing parameters
+ FMC_SDRAM_TimingTypeDef SdramTiming;
+
+ //
+ // following settings are for -75E speed grade memory chip
+ // clocked at only 90 MHz instead of the rated 133 MHz
+ //
+
+ SdramTiming.LoadToActiveDelay = 2; // tMRD
+
+ SdramTiming.ExitSelfRefreshDelay = 7; // 67 ns @ 90 MHz is 6.03 cycles, so in theory 6
+ // can be used here, but let's be on the safe side
+
+ SdramTiming.SelfRefreshTime = 5; // should be >= tRAS (5 cycles)
+
+ SdramTiming.RowCycleDelay = 8; // tRC
+
+ SdramTiming.WriteRecoveryTime = 4; // must be >= tRAS - tRCD (5 - 2 = 3 cycles),
+ // and >= tRC - tRCD - tRP (8 - 2 - 2 = 4 cycles)
+
+ SdramTiming.RPDelay = 2; // tRP
+
+ SdramTiming.RCDDelay = 2; // tRCD
+
+
+ //
+ // configure the first bank
+ //
+
+
+ // memory type
+ hsdram1.Instance = FMC_SDRAM_DEVICE;
+
+ // bank
+ hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
+
+ // settings for IS42S32160F
+ hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
+ hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
+ hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
+ hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
+ hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
+
+ // write protection not needed
+ hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
+
+ // memory clock is 90 MHz (HCLK / 2)
+ hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
+
+ // read burst not needed
+ hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
+
+ // additional pipeline stages not neeed
+ hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
+
+ // call HAL layer
+ HAL_SDRAM_Init(&hsdram1, &SdramTiming);
+
+
+ //
+ // configure the second bank
+ //
+
+
+ // memory type
+ hsdram2.Instance = FMC_SDRAM_DEVICE;
+
+ // bank number
+ hsdram2.Init.SDBank = FMC_SDRAM_BANK2;
+
+ // settings for IS42S32160F
+ hsdram2.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
+ hsdram2.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
+ hsdram2.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
+ hsdram2.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
+ hsdram2.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
+
+ // write protection not needed
+ hsdram2.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
+
+ // memory clock is 90 MHz (HCLK / 2)
+ hsdram2.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
+
+ // read burst not needed
+ hsdram2.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
+
+ // additional pipeline stages not neeed
+ hsdram2.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
+
+ // call HAL layer
+ HAL_SDRAM_Init(&hsdram2, &SdramTiming);
+
+}
+
+static int FMC_Initialized = 0;
+
+static void HAL_FMC_MspInit(void){
+ /* USER CODE BEGIN FMC_MspInit 0 */
+
+ /* USER CODE END FMC_MspInit 0 */
+ GPIO_InitTypeDef GPIO_InitStruct;
+ if (FMC_Initialized) {
+ return;
+ }
+ FMC_Initialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FMC_CLK_ENABLE();
+
+ /** FMC GPIO Configuration
+ PI9 ------> FMC_D30
+ PI10 ------> FMC_D31
+ PF0 ------> FMC_A0
+ PF1 ------> FMC_A1
+ PF2 ------> FMC_A2
+ PF3 ------> FMC_A3
+ PF4 ------> FMC_A4
+ PF5 ------> FMC_A5
+ PC0 ------> FMC_SDNWE
+ PC2 ------> FMC_SDNE0
+ PC3 ------> FMC_SDCKE0
+ PF11 ------> FMC_SDNRAS
+ PF12 ------> FMC_A6
+ PF13 ------> FMC_A7
+ PF14 ------> FMC_A8
+ PF15 ------> FMC_A9
+ PG0 ------> FMC_A10
+ PG1 ------> FMC_A11
+ PE7 ------> FMC_D4
+ PE8 ------> FMC_D5
+ PE9 ------> FMC_D6
+ PE10 ------> FMC_D7
+ PE11 ------> FMC_D8
+ PE12 ------> FMC_D9
+ PE13 ------> FMC_D10
+ PE14 ------> FMC_D11
+ PE15 ------> FMC_D12
+ PH8 ------> FMC_D16
+ PH9 ------> FMC_D17
+ PH10 ------> FMC_D18
+ PH11 ------> FMC_D19
+ PH12 ------> FMC_D20
+ PD8 ------> FMC_D13
+ PD9 ------> FMC_D14
+ PD10 ------> FMC_D15
+ PD14 ------> FMC_D0
+ PD15 ------> FMC_D1
+ PG2 ------> FMC_A12
+ PG4 ------> FMC_BA0
+ PG5 ------> FMC_BA1
+ PG8 ------> FMC_SDCLK
+ PH13 ------> FMC_D21
+ PH14 ------> FMC_D22
+ PH15 ------> FMC_D23
+ PI0 ------> FMC_D24
+ PI1 ------> FMC_D25
+ PI2 ------> FMC_D26
+ PI3 ------> FMC_D27
+ PD0 ------> FMC_D2
+ PD1 ------> FMC_D3
+ PG15 ------> FMC_SDNCAS
+ PB5 ------> FMC_SDCKE1
+ PB6 ------> FMC_SDNE1
+ PE0 ------> FMC_NBL0
+ PE1 ------> FMC_NBL1
+ PI4 ------> FMC_NBL2
+ PI5 ------> FMC_NBL3
+ PI6 ------> FMC_D28
+ PI7 ------> FMC_D29
+ */
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
+ |GPIO_PIN_6|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12
+ |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
+ |GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
+ |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* GPIO_InitStruct */
+ GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN FMC_MspInit 1 */
+
+ /* USER CODE END FMC_MspInit 1 */
+}
+
+void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram){
+ /* USER CODE BEGIN SDRAM_MspInit 0 */
+
+ /* USER CODE END SDRAM_MspInit 0 */
+ HAL_FMC_MspInit();
+ /* USER CODE BEGIN SDRAM_MspInit 1 */
+
+ /* USER CODE END SDRAM_MspInit 1 */
+}
+
+static int FMC_DeInitialized = 0;
+
+static void HAL_FMC_MspDeInit(void){
+ /* USER CODE BEGIN FMC_MspDeInit 0 */
+
+ /* USER CODE END FMC_MspDeInit 0 */
+ if (FMC_DeInitialized) {
+ return;
+ }
+ FMC_DeInitialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FMC_CLK_DISABLE();
+
+ /** FMC GPIO Configuration
+ PI9 ------> FMC_D30
+ PI10 ------> FMC_D31
+ PF0 ------> FMC_A0
+ PF1 ------> FMC_A1
+ PF2 ------> FMC_A2
+ PF3 ------> FMC_A3
+ PF4 ------> FMC_A4
+ PF5 ------> FMC_A5
+ PC0 ------> FMC_SDNWE
+ PC2 ------> FMC_SDNE0
+ PC3 ------> FMC_SDCKE0
+ PF11 ------> FMC_SDNRAS
+ PF12 ------> FMC_A6
+ PF13 ------> FMC_A7
+ PF14 ------> FMC_A8
+ PF15 ------> FMC_A9
+ PG0 ------> FMC_A10
+ PG1 ------> FMC_A11
+ PE7 ------> FMC_D4
+ PE8 ------> FMC_D5
+ PE9 ------> FMC_D6
+ PE10 ------> FMC_D7
+ PE11 ------> FMC_D8
+ PE12 ------> FMC_D9
+ PE13 ------> FMC_D10
+ PE14 ------> FMC_D11
+ PE15 ------> FMC_D12
+ PH8 ------> FMC_D16
+ PH9 ------> FMC_D17
+ PH10 ------> FMC_D18
+ PH11 ------> FMC_D19
+ PH12 ------> FMC_D20
+ PD8 ------> FMC_D13
+ PD9 ------> FMC_D14
+ PD10 ------> FMC_D15
+ PD14 ------> FMC_D0
+ PD15 ------> FMC_D1
+ PG2 ------> FMC_A12
+ PG4 ------> FMC_BA0
+ PG5 ------> FMC_BA1
+ PG8 ------> FMC_SDCLK
+ PH13 ------> FMC_D21
+ PH14 ------> FMC_D22
+ PH15 ------> FMC_D23
+ PI0 ------> FMC_D24
+ PI1 ------> FMC_D25
+ PI2 ------> FMC_D26
+ PI3 ------> FMC_D27
+ PD0 ------> FMC_D2
+ PD1 ------> FMC_D3
+ PG15 ------> FMC_SDNCAS
+ PB5 ------> FMC_SDCKE1
+ PB6 ------> FMC_SDNE1
+ PE0 ------> FMC_NBL0
+ PE1 ------> FMC_NBL1
+ PI4 ------> FMC_NBL2
+ PI5 ------> FMC_NBL3
+ PI6 ------> FMC_D28
+ PI7 ------> FMC_D29
+ */
+
+ HAL_GPIO_DeInit(GPIOI, GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
+ |GPIO_PIN_6|GPIO_PIN_7);
+
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12
+ |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3);
+
+ HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
+ |GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
+
+ HAL_GPIO_DeInit(GPIOH, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
+ |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5|GPIO_PIN_6);
+
+ /* USER CODE BEGIN FMC_MspDeInit 1 */
+
+ /* USER CODE END FMC_MspDeInit 1 */
+}
+
+void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* hsdram){
+ /* USER CODE BEGIN SDRAM_MspDeInit 0 */
+
+ /* USER CODE END SDRAM_MspDeInit 0 */
+ HAL_FMC_MspDeInit();
+ /* USER CODE BEGIN SDRAM_MspDeInit 1 */
+
+ /* USER CODE END SDRAM_MspDeInit 1 */
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fmc.h b/fmc.h
new file mode 100644
index 0000000..7ab5db4
--- /dev/null
+++ b/fmc.h
@@ -0,0 +1,76 @@
+/**
+ ******************************************************************************
+ * File Name : FMC.h
+ * Description : This file provides code for the configuration
+ * of the FMC peripheral.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FMC_H
+#define __FMC_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern SDRAM_HandleTypeDef hsdram1;
+extern SDRAM_HandleTypeDef hsdram2;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_FMC_Init(void);
+void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram);
+void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* hsdram);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__FMC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/gpio.c b/gpio.c
new file mode 100644
index 0000000..d24af2a
--- /dev/null
+++ b/gpio.c
@@ -0,0 +1,95 @@
+/**
+ ******************************************************************************
+ * File Name : gpio.c
+ * Description : This file provides code for the configuration
+ * of all used GPIO pins.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "gpio.h"
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/*----------------------------------------------------------------------------*/
+/* Configure GPIO */
+/*----------------------------------------------------------------------------*/
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/** Configure pins as
+ * Analog
+ * Input
+ * Output
+ * EVENT_OUT
+ * EXTI
+*/
+void MX_GPIO_Init(void)
+{
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOK_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(GPIOK, ARM_LED_BLUE_Pin|ARM_LED_GREEN_Pin|ARM_LED_YELLOW_Pin|ARM_LED_RED_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pins : PKPin PKPin PKPin PKPin */
+ GPIO_InitStruct.Pin = ARM_LED_BLUE_Pin|ARM_LED_GREEN_Pin|ARM_LED_YELLOW_Pin|ARM_LED_RED_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOK, &GPIO_InitStruct);
+
+}
+
+/* USER CODE BEGIN 2 */
+
+/* USER CODE END 2 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/gpio.h b/gpio.h
new file mode 100644
index 0000000..3f68180
--- /dev/null
+++ b/gpio.h
@@ -0,0 +1,72 @@
+/**
+ ******************************************************************************
+ * File Name : gpio.h
+ * Description : This file contains all the functions prototypes for
+ * the gpio
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __gpio_H
+#define __gpio_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_GPIO_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ pinoutConfig_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..b925dbc
--- /dev/null
+++ b/main.c
@@ -0,0 +1,445 @@
+/**
+ ******************************************************************************
+ * File Name : main.c
+ * Description : Main program body
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+#include "stm32f4xx_hal.h"
+#include "gpio.h"
+#include "fmc.h"
+#include "stm32-sdram.h"
+
+
+//-----------------------------------------------------------------------------
+// Prototypes
+//-----------------------------------------------------------------------------
+void SystemClock_Config(void);
+
+int test_sdram_sequential(uint32_t *base_addr);
+int test_sdram_random(uint32_t *base_addr);
+int test_sdrams_interleaved(uint32_t *base_addr1, uint32_t *base_addr2);
+
+uint32_t lfsr_next_32(uint32_t lfsr);
+uint32_t lfsr_next_24(uint32_t lfsr);
+
+
+//-----------------------------------------------------------------------------
+// Locals
+//-----------------------------------------------------------------------------
+static uint32_t lfsr1;
+static uint32_t lfsr2;
+
+
+//-----------------------------------------------------------------------------
+int main(void)
+//-----------------------------------------------------------------------------
+{
+ HAL_Init();
+ SystemClock_Config();
+ MX_GPIO_Init();
+ MX_FMC_Init();
+
+ // run external memory initialization sequence
+ int ok = sdram_init(&hsdram1, &hsdram2);
+
+ // turn on green LED in case of success,
+ // and keep it on as long as we're happy
+ if (ok) HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_GREEN_Pin, GPIO_PIN_SET);
+
+ // set LFSRs to some initial value, LFSRs will produce
+ // pseudo-random 32-bit patterns to test our memories
+ lfsr1 = 0xCCAA5533;
+ lfsr2 = 0xCCAA5533;
+
+ // continuosly test both chips
+ while (ok)
+ {
+ // turn blue led off (testing chips separately)
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_BLUE_Pin, GPIO_PIN_RESET);
+
+ // run sequential write-then-read test for the first chip
+ ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP1);
+ if (!ok) break;
+
+ // run random write-then-read test for the first chip
+ ok = test_sdram_random(SDRAM_BASEADDR_CHIP1);
+ if (!ok) break;
+
+ // run sequential write-then-read test for the second chip
+ ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP2);
+ if (!ok) break;
+
+ // run random write-then-read test for the second chip
+ ok = test_sdram_random(SDRAM_BASEADDR_CHIP2);
+ if (!ok) break;
+
+ // turn blue led on (testing two chips at the same time)
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_BLUE_Pin, GPIO_PIN_SET);
+
+ // run interleaved write-then-read test for both chips at once
+ ok = test_sdrams_interleaved(SDRAM_BASEADDR_CHIP1, SDRAM_BASEADDR_CHIP2);
+ if (!ok) break;
+
+ }
+
+ /* should only get here in case of failure */
+
+ //
+ // turn all leds off
+ //
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_BLUE_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_GREEN_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_RED_Pin, GPIO_PIN_RESET);
+
+ //
+ // repeatedly flash the red led to indicate failure
+ //
+ for (;;)
+ {
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_RED_Pin, GPIO_PIN_RESET);
+ HAL_Delay(100);
+
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_RED_Pin, GPIO_PIN_SET);
+ HAL_Delay(100);
+ }
+
+}
+
+
+//-----------------------------------------------------------------------------
+int test_sdram_sequential(uint32_t *base_addr)
+//-----------------------------------------------------------------------------
+{
+ // memory offset
+ int offset;
+
+ // readback value
+ uint32_t sdram_readback;
+
+
+ /* This test fills entire memory chip with some pseudo-random pattern
+ starting from the very first cell and going in linear fashion. It then
+ reads entire memory and compares read values with what was written. */
+
+
+ // turn on yellow led to indicate, that we're writing
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_SET);
+
+
+ //
+ // Note, that SDRAM_SIZE is in BYTES, and since we write using
+ // 32-bit words, total number of words is SDRAM_SIZE / 4.
+ //
+
+ // fill entire memory with "random" values
+ for (offset=0; offset<(SDRAM_SIZE >> 2); offset++)
+ {
+ // generate next "random" value to write
+ lfsr1 = lfsr_next_32(lfsr1);
+
+ // write to memory
+ base_addr[offset] = lfsr1;
+ }
+
+
+ // turn off yellow led to indicate, that we're going to read
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_RESET);
+
+
+ // read entire memory and compare values
+ for (offset=0; offset<(SDRAM_SIZE >> 2); offset++)
+ {
+ // generate next "random" value (we use the second LFSR to catch up)
+ lfsr2 = lfsr_next_32(lfsr2);
+
+ // read from memory
+ sdram_readback = base_addr[offset];
+
+ // compare and abort test in case of mismatch
+ if (sdram_readback != lfsr2) return 0;
+ }
+
+ // done
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+int test_sdram_random(uint32_t *base_addr)
+//-----------------------------------------------------------------------------
+{
+ // cell counter, memory offset
+ int counter, offset;
+
+ // readback value
+ uint32_t sdram_readback;
+
+
+ /* This test fills entire memory chip with some pseudo-random pattern
+ starting from the very first cell, but then jumping around in pseudo-
+ random fashion to make sure, that SDRAM controller in STM32 handles
+ bank, row and column switching correctly. It then reads entire memory
+ and compares read values with what was written. */
+
+
+ // turn on yellow led to indicate, that we're writing
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_SET);
+
+
+ //
+ // Note, that SDRAM_SIZE is in BYTES, and since we write using
+ // 32-bit words, total number of words is SDRAM_SIZE / 4.
+ //
+
+ // start with the first cell
+ for (counter=0, offset=0; counter<(SDRAM_SIZE >> 2); counter++)
+ {
+ // generate next "random" value to write
+ lfsr1 = lfsr_next_32(lfsr1);
+
+ // write to memory
+ base_addr[offset] = lfsr1;
+
+ // generate next "random" address
+
+ //
+ // Note, that for 64 MB memory with 32-bit data bus we need 24 bits
+ // of address, so we use 24-bit LFSR here. Since LFSR has only 2^^24-1
+ // states, i.e. all possible 24-bit values excluding 0, we have to
+ // manually kick it into some arbitrary state during the first iteration.
+ //
+
+ offset = offset ? lfsr_next_24(offset) : 0x00DEC0DE;
+ }
+
+
+ // turn off yellow led to indicate, that we're going to read
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_RESET);
+
+
+ // read entire memory and compare values
+ for (counter=0, offset=0; counter<(SDRAM_SIZE >> 2); counter++)
+ {
+ // generate next "random" value (we use the second LFSR to catch up)
+ lfsr2 = lfsr_next_32(lfsr2);
+
+ // read from memory
+ sdram_readback = base_addr[offset];
+
+ // compare and abort test in case of mismatch
+ if (sdram_readback != lfsr2) return 0;
+
+ // generate next "random" address
+ offset = offset ? lfsr_next_24(offset) : 0x00DEC0DE;
+ }
+
+ //
+ // we should have walked exactly 2**24 iterations and returned
+ // back to the arbitrary starting address...
+ //
+
+ if (offset != 0x00DEC0DE) return 0;
+
+
+ // done
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+int test_sdrams_interleaved(uint32_t *base_addr1, uint32_t *base_addr2)
+//-----------------------------------------------------------------------------
+{
+ // cell counter, memory offsets
+ int counter, offset1, offset2;
+
+ // readback value
+ uint32_t sdram_readback;
+
+
+ /* Basically this is the same as test_sdram_random() except that it
+ tests both memory chips at the same time. */
+
+
+ // turn on yellow led to indicate, that we're writing
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_SET);
+
+
+ //
+ // Note, that SDRAM_SIZE is in BYTES, and since we write using
+ // 32-bit words, total number of words is SDRAM_SIZE / 4.
+ //
+
+ // start with the first cell
+ for (counter=0, offset1=0, offset2=0; counter<(SDRAM_SIZE >> 2); counter++)
+ {
+ // generate next "random" value to write
+ lfsr1 = lfsr_next_32(lfsr1);
+
+ // write to memory
+ base_addr1[offset1] = lfsr1;
+ base_addr2[offset2] = lfsr1;
+
+ // generate next "random" addresses (use different starting states!)
+
+ offset1 = offset1 ? lfsr_next_24(offset1) : 0x00ABCDEF;
+ offset2 = offset2 ? lfsr_next_24(offset2) : 0x00FEDCBA;
+ }
+
+
+ // turn off yellow led to indicate, that we're going to read
+ HAL_GPIO_WritePin(ARM_LED_GPIO_Port, ARM_LED_YELLOW_Pin, GPIO_PIN_RESET);
+
+
+ // read entire memory and compare values
+ for (counter=0, offset1=0, offset2=0; counter<(SDRAM_SIZE >> 2); counter++)
+ {
+ // generate next "random" value (we use the second LFSR to catch up)
+ lfsr2 = lfsr_next_32(lfsr2);
+
+ // read from the first memory and compare
+ sdram_readback = base_addr1[offset1];
+ if (sdram_readback != lfsr2) return 0;
+
+ // read from the second memory and compare
+ sdram_readback = base_addr2[offset2];
+ if (sdram_readback != lfsr2) return 0;
+
+ // generate next "random" addresses
+ offset1 = offset1 ? lfsr_next_24(offset1) : 0x00ABCDEF;
+ offset2 = offset2 ? lfsr_next_24(offset2) : 0x00FEDCBA;
+ }
+
+ //
+ // we should have walked exactly 2**24 iterations and returned
+ // back to the arbitrary starting address...
+ //
+
+ if (offset1 != 0x00ABCDEF) return 0;
+ if (offset2 != 0x00FEDCBA) return 0;
+
+
+ // done
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+void SystemClock_Config(void)
+//-----------------------------------------------------------------------------
+{
+
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ RCC_OscInitStruct.HSICalibrationValue = 16;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+ RCC_OscInitStruct.PLL.PLLM = 16;
+ RCC_OscInitStruct.PLL.PLLN = 360;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+ RCC_OscInitStruct.PLL.PLLQ = 4;
+ HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+ HAL_PWREx_EnableOverDrive();
+
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
+ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
+
+ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
+
+ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+
+ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+}
+
+
+
+//-----------------------------------------------------------------------------
+uint32_t lfsr_next_32(uint32_t lfsr)
+//-----------------------------------------------------------------------------
+{
+ uint32_t tap = 0;
+
+ tap ^= (lfsr >> 31);
+ tap ^= (lfsr >> 30);
+ tap ^= (lfsr >> 29);
+ tap ^= (lfsr >> 9);
+
+ return (lfsr << 1) | (tap & 1);
+}
+
+
+//-----------------------------------------------------------------------------
+uint32_t lfsr_next_24(uint32_t lfsr)
+//-----------------------------------------------------------------------------
+{
+ unsigned int tap = 0;
+
+ tap ^= (lfsr >> 23);
+ tap ^= (lfsr >> 22);
+ tap ^= (lfsr >> 21);
+ tap ^= (lfsr >> 16);
+
+ return ((lfsr << 1) | (tap & 1)) & 0x00FFFFFF;
+}
+
+
+//-----------------------------------------------------------------------------
+#ifdef USE_FULL_ASSERT
+//-----------------------------------------------------------------------------
+void assert_failed(uint8_t* file, uint32_t line)
+//-----------------------------------------------------------------------------
+{
+}
+//-----------------------------------------------------------------------------
+#endif
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// End-of-File
+//-----------------------------------------------------------------------------
diff --git a/mxconstants.h b/mxconstants.h
new file mode 100644
index 0000000..1af1291
--- /dev/null
+++ b/mxconstants.h
@@ -0,0 +1,58 @@
+/**
+ ******************************************************************************
+ * File Name : mxconstants.h
+ * Description : This file contains the common defines of the application
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private define ------------------------------------------------------------*/
+
+#define ARM_LED_BLUE_Pin GPIO_PIN_4
+#define ARM_LED_GREEN_Pin GPIO_PIN_5
+#define ARM_LED_YELLOW_Pin GPIO_PIN_6
+#define ARM_LED_RED_Pin GPIO_PIN_7
+#define ARM_LED_GPIO_Port GPIOK
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32-sdram.c b/stm32-sdram.c
new file mode 100644
index 0000000..16386e8
--- /dev/null
+++ b/stm32-sdram.c
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// stm32-sdram.c
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+#include "stm32f4xx_hal.h"
+#include "stm32-sdram.h"
+
+
+//-----------------------------------------------------------------------------
+int sdram_init(SDRAM_HandleTypeDef *sdram1, SDRAM_HandleTypeDef *sdram2)
+//-----------------------------------------------------------------------------
+{
+ HAL_StatusTypeDef ok; // status
+ FMC_SDRAM_CommandTypeDef cmd; // command
+
+
+ //
+ // enable clocking
+ //
+ cmd.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
+ cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+ cmd.AutoRefreshNumber = 1;
+ cmd.ModeRegisterDefinition = 0;
+
+ HAL_Delay(1);
+ ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
+ if (ok != HAL_OK) return 0;
+
+ //
+ // precharge all banks
+ //
+ cmd.CommandMode = FMC_SDRAM_CMD_PALL;
+ cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+ cmd.AutoRefreshNumber = 1;
+ cmd.ModeRegisterDefinition = 0;
+
+ HAL_Delay(1);
+ ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
+ if (ok != HAL_OK) return 0;
+
+
+ //
+ // send two auto-refresh commands in a row
+ //
+ cmd.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
+ cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+ cmd.AutoRefreshNumber = 1;
+ cmd.ModeRegisterDefinition = 0;
+
+ ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
+ if (ok != HAL_OK) return 1;
+
+ ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
+ if (ok != HAL_OK) return 1;
+
+
+ //
+ // load mode register
+ //
+ cmd.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
+ cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+ cmd.AutoRefreshNumber = 1;
+ cmd.ModeRegisterDefinition = SDRAM_MODEREG_BURST_LENGTH_1 |
+ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
+ SDRAM_MODEREG_CAS_LATENCY_2 |
+ SDRAM_MODEREG_OPERATING_MODE_STANDARD |
+ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ;
+
+ ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
+ if (ok != HAL_OK) return 1;
+
+
+ //
+ // set number of consequtive auto-refresh commands
+ // and program refresh rate
+ //
+
+ //
+ // RefreshRate = 64 ms / 8192 cyc = 7.8125 us/cyc
+ //
+ // RefreshCycles = 7.8125 us * 90 MHz = 703
+ //
+ // According to the formula on p.1665 of the reference manual,
+ // we also need to subtract 20 from the value, so the target
+ // refresh rate is 703 - 20 = 683.
+ //
+
+ ok = HAL_SDRAM_SetAutoRefreshNumber(sdram1, 8);
+ if (ok != HAL_OK) return 1;
+
+ HAL_SDRAM_ProgramRefreshRate(sdram1, 683);
+ if (ok != HAL_OK) return 1;
+
+
+ // done
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------
+// End-of-File
+//-----------------------------------------------------------------------------
diff --git a/stm32-sdram.h b/stm32-sdram.h
new file mode 100644
index 0000000..2e4361c
--- /dev/null
+++ b/stm32-sdram.h
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// stm32-sdram.h
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Defined Values
+//-----------------------------------------------------------------------------
+
+ /* Base Addresses */
+#define SDRAM_BASEADDR_CHIP1 ((uint32_t *)0xC0000000)
+#define SDRAM_BASEADDR_CHIP2 ((uint32_t *)0xD0000000)
+
+ /* Memory Size */
+#define SDRAM_SIZE 0x4000000 // 64 MBytes (512 Mbits)
+
+ /* Mode Register Bits */
+#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
+
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+
+#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
+
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+
+
+//-----------------------------------------------------------------------------
+// Prototypes
+//-----------------------------------------------------------------------------
+int sdram_init(SDRAM_HandleTypeDef *sdram1, SDRAM_HandleTypeDef *sdram2);
+
+
+//-----------------------------------------------------------------------------
+// End-of-File
+//-----------------------------------------------------------------------------
diff --git a/stm32f4xx_hal_conf.h b/stm32f4xx_hal_conf.h
new file mode 100644
index 0000000..8c6c92e
--- /dev/null
+++ b/stm32f4xx_hal_conf.h
@@ -0,0 +1,448 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf.h
+ * @brief HAL configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "mxconstants.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+//#define HAL_ADC_MODULE_ENABLED
+//#define HAL_CAN_MODULE_ENABLED
+//#define HAL_CRC_MODULE_ENABLED
+//#define HAL_CRYP_MODULE_ENABLED
+//#define HAL_DAC_MODULE_ENABLED
+//#define HAL_DCMI_MODULE_ENABLED
+//#define HAL_DMA2D_MODULE_ENABLED
+//#define HAL_ETH_MODULE_ENABLED
+//#define HAL_NAND_MODULE_ENABLED
+//#define HAL_NOR_MODULE_ENABLED
+//#define HAL_PCCARD_MODULE_ENABLED
+//#define HAL_SRAM_MODULE_ENABLED
+#define HAL_SDRAM_MODULE_ENABLED
+//#define HAL_HASH_MODULE_ENABLED
+//#define HAL_I2C_MODULE_ENABLED
+//#define HAL_I2S_MODULE_ENABLED
+//#define HAL_IWDG_MODULE_ENABLED
+//#define HAL_LTDC_MODULE_ENABLED
+//#define HAL_RNG_MODULE_ENABLED
+//#define HAL_RTC_MODULE_ENABLED
+//#define HAL_SAI_MODULE_ENABLED
+//#define HAL_SD_MODULE_ENABLED
+//#define HAL_SPI_MODULE_ENABLED
+//#define HAL_TIM_MODULE_ENABLED
+//#define HAL_UART_MODULE_ENABLED
+//#define HAL_USART_MODULE_ENABLED
+//#define HAL_IRDA_MODULE_ENABLED
+//#define HAL_SMARTCARD_MODULE_ENABLED
+//#define HAL_WWDG_MODULE_ENABLED
+//#define HAL_PCD_MODULE_ENABLED
+//#define HAL_HCD_MODULE_ENABLED
+//#define HAL_DSI_MODULE_ENABLED
+//#define HAL_QSPI_MODULE_ENABLED
+//#define HAL_QSPI_MODULE_ENABLED
+//#define HAL_CEC_MODULE_ENABLED
+//#define HAL_FMPI2C_MODULE_ENABLED
+//#define HAL_SPDIFRX_MODULE_ENABLED
+//#define HAL_DFSDM_MODULE_ENABLED
+//#define HAL_LPTIM_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848 PHY Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+
+#define PHY_SR ((uint16_t)0x0010U) /*!< PHY status register Offset */
+#define PHY_MICR ((uint16_t)0x0011U) /*!< MII Interrupt Control Register */
+#define PHY_MISR ((uint16_t)0x0012U) /*!< MII Interrupt Status and Misc. Control Register */
+
+#define PHY_LINK_STATUS ((uint16_t)0x0001U) /*!< PHY Link mask */
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+#define PHY_MICR_INT_EN ((uint16_t)0x0002U) /*!< PHY Enable interrupts */
+#define PHY_MICR_INT_OE ((uint16_t)0x0001U) /*!< PHY Enable output interrupt events */
+
+#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020U) /*!< Enable Interrupt on change of link status */
+#define PHY_LINK_INTERRUPT ((uint16_t)0x2000U) /*!< PHY link status interrupt mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32f4xx_hal_msp.c b/stm32f4xx_hal_msp.c
new file mode 100644
index 0000000..bb215f8
--- /dev/null
+++ b/stm32f4xx_hal_msp.c
@@ -0,0 +1,81 @@
+/**
+ ******************************************************************************
+ * File Name : stm32f4xx_hal_msp.c
+ * Description : This file provides code for the MSP Initialization
+ * and de-Initialization codes.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * Initializes the Global MSP.
+ */
+void HAL_MspInit(void)
+{
+ /* USER CODE BEGIN MspInit 0 */
+
+ /* USER CODE END MspInit 0 */
+
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* System interrupt init*/
+ /* MemoryManagement_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
+ /* BusFault_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
+ /* UsageFault_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
+ /* DebugMonitor_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
+ /* SysTick_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+
+ /* USER CODE BEGIN MspInit 1 */
+
+ /* USER CODE END MspInit 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32f4xx_it.c b/stm32f4xx_it.c
new file mode 100644
index 0000000..9613330
--- /dev/null
+++ b/stm32f4xx_it.c
@@ -0,0 +1,167 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_it.c
+ * @brief Interrupt Service Routines.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "stm32f4xx.h"
+#include "stm32f4xx_it.h"
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+
+/******************************************************************************/
+/* Cortex-M4 Processor Interruption and Exception Handlers */
+/******************************************************************************/
+
+/**
+* @brief This function handles Non maskable interrupt.
+*/
+void NMI_Handler(void)
+{
+ /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+ /* USER CODE END NonMaskableInt_IRQn 0 */
+
+ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+
+ /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+* @brief This function handles Hard fault interrupt.
+*/
+void HardFault_Handler(void)
+{
+ /* USER CODE BEGIN HardFault_IRQn 0 */
+
+ /* USER CODE END HardFault_IRQn 0 */
+ while (1)
+ {
+ }
+ /* USER CODE BEGIN HardFault_IRQn 1 */
+
+ /* USER CODE END HardFault_IRQn 1 */
+}
+
+/**
+* @brief This function handles Memory management fault.
+*/
+void MemManage_Handler(void)
+{
+ /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+ /* USER CODE END MemoryManagement_IRQn 0 */
+ while (1)
+ {
+ }
+ /* USER CODE BEGIN MemoryManagement_IRQn 1 */
+
+ /* USER CODE END MemoryManagement_IRQn 1 */
+}
+
+/**
+* @brief This function handles Pre-fetch fault, memory access fault.
+*/
+void BusFault_Handler(void)
+{
+ /* USER CODE BEGIN BusFault_IRQn 0 */
+
+ /* USER CODE END BusFault_IRQn 0 */
+ while (1)
+ {
+ }
+ /* USER CODE BEGIN BusFault_IRQn 1 */
+
+ /* USER CODE END BusFault_IRQn 1 */
+}
+
+/**
+* @brief This function handles Undefined instruction or illegal state.
+*/
+void UsageFault_Handler(void)
+{
+ /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+ /* USER CODE END UsageFault_IRQn 0 */
+ while (1)
+ {
+ }
+ /* USER CODE BEGIN UsageFault_IRQn 1 */
+
+ /* USER CODE END UsageFault_IRQn 1 */
+}
+
+/**
+* @brief This function handles Debug monitor.
+*/
+void DebugMon_Handler(void)
+{
+ /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+ /* USER CODE END DebugMonitor_IRQn 0 */
+ while (1)
+ {
+ }
+ /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+ /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/**
+* @brief This function handles System tick timer.
+*/
+void SysTick_Handler(void)
+{
+ /* USER CODE BEGIN SysTick_IRQn 0 */
+
+ /* USER CODE END SysTick_IRQn 0 */
+ HAL_IncTick();
+ HAL_SYSTICK_IRQHandler();
+ /* USER CODE BEGIN SysTick_IRQn 1 */
+
+ /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32F4xx Peripheral Interrupt Handlers */
+/* Add here the Interrupt Handlers for the used peripherals. */
+/* For the available peripheral interrupt handler names, */
+/* please refer to the startup file (startup_stm32f4xx.s). */
+/******************************************************************************/
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32f4xx_it.h b/stm32f4xx_it.h
new file mode 100644
index 0000000..5ff769a
--- /dev/null
+++ b/stm32f4xx_it.h
@@ -0,0 +1,62 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_it.h
+ * @brief This file contains the headers of the interrupt handlers.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_IT_H
+#define __STM32F4xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void DebugMon_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_IT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm32f4xx_ll_fmc.c b/stm32f4xx_ll_fmc.c
new file mode 100644
index 0000000..91dda06
--- /dev/null
+++ b/stm32f4xx_ll_fmc.c
@@ -0,0 +1,1738 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_ll_fmc.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 22-January-2016
+ * @brief FMC Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Flexible Memory Controller (FMC) peripheral memories:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### FMC peripheral features #####
+ ==============================================================================
+ [..] The Flexible memory controller (FMC) includes three memory controllers:
+ (+) The NOR/PSRAM memory controller
+ (+) The NAND/PC Card memory controller
+ (+) The Synchronous DRAM (SDRAM) controller
+
+ [..] The FMC functional block makes the interface with synchronous and asynchronous static
+ memories, SDRAM memories, and 16-bit PC memory cards. Its main purposes are:
+ (+) to translate AHB transactions into the appropriate external device protocol
+ (+) to meet the access time requirements of the external memory devices
+
+ [..] All external memories share the addresses, data and control signals with the controller.
+ Each external device is accessed by means of a unique Chip Select. The FMC performs
+ only one access at a time to an external device.
+ The main features of the FMC controller are the following:
+ (+) Interface with static-memory mapped devices including:
+ (++) Static random access memory (SRAM)
+ (++) Read-only memory (ROM)
+ (++) NOR Flash memory/OneNAND Flash memory
+ (++) PSRAM (4 memory banks)
+ (++) 16-bit PC Card compatible devices
+ (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
+ data
+ (+) Interface with synchronous DRAM (SDRAM) memories
+ (+) Independent Chip Select control for each memory bank
+ (+) Independent configuration for each memory bank
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup FMC_LL FMC Low Layer
+ * @brief FMC driver modules
+ * @{
+ */
+
+#if defined (HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_SDRAM_MODULE_ENABLED)
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup FMC_LL_Private_Functions
+ * @{
+ */
+
+/** @addtogroup FMC_LL_NORSRAM
+ * @brief NORSRAM Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NORSRAM device driver #####
+ ==============================================================================
+
+ [..]
+ This driver contains a set of APIs to interface with the FMC NORSRAM banks in order
+ to run the NORSRAM external devices.
+
+ (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit()
+ (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init()
+ (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init()
+ (+) FMC NORSRAM bank extended timing configuration using the function
+ FMC_NORSRAM_Extended_Timing_Init()
+ (+) FMC NORSRAM bank enable/disable write operation using the functions
+ FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable()
+
+
+@endverbatim
+ * @{
+ */
+
+/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group1
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FMC NORSRAM interface
+ (+) De-initialize the FMC NORSRAM interface
+ (+) Configure the FMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the FMC_NORSRAM device according to the specified
+ * control parameters in the FMC_NORSRAM_InitTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Init: Pointer to NORSRAM Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef* Init)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank));
+ assert_param(IS_FMC_MUX(Init->DataAddressMux));
+ assert_param(IS_FMC_MEMORY(Init->MemoryType));
+ assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode));
+ assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity));
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+ assert_param(IS_FMC_WRAP_MODE(Init->WrapMode));
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
+ assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
+ assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation));
+ assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal));
+ assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode));
+ assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait));
+ assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst));
+ assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock));
+ assert_param(IS_FMC_PAGESIZE(Init->PageSize));
+#if defined (STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+ assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo));
+#endif /* STM32F446xx || STM32F469xx || STM32F479xx */
+
+ /* Get the BTCR register value */
+ tmpr = Device->BTCR[Init->NSBank];
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+ /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WRAPMOD, WAITCFG, WREN,
+ WAITEN, EXTMOD, ASYNCWAIT, CPSIZE, CBURSTRW and CCLKEN bits */
+ tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \
+ FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \
+ FMC_BCR1_WAITPOL | FMC_BCR1_WRAPMOD | FMC_BCR1_WAITCFG | \
+ FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \
+ FMC_BCR1_ASYNCWAIT | FMC_BCR1_CPSIZE | FMC_BCR1_CBURSTRW | \
+ FMC_BCR1_CCLKEN));
+
+ /* Set NORSRAM device control parameters */
+ tmpr |= (uint32_t)(Init->DataAddressMux |\
+ Init->MemoryType |\
+ Init->MemoryDataWidth |\
+ Init->BurstAccessMode |\
+ Init->WaitSignalPolarity |\
+ Init->WrapMode |\
+ Init->WaitSignalActive |\
+ Init->WriteOperation |\
+ Init->WaitSignal |\
+ Init->ExtendedMode |\
+ Init->AsynchronousWait |\
+ Init->PageSize |\
+ Init->WriteBurst |\
+ Init->ContinuousClock);
+#else /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) */
+ /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, CPSIZE, WAITCFG, WREN,
+ WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW, CCLKEN and WFDIS bits */
+ tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \
+ FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \
+ FMC_BCR1_WAITPOL | FMC_BCR1_WAITCFG | FMC_BCR1_CPSIZE | \
+ FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \
+ FMC_BCR1_ASYNCWAIT | FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN | \
+ FMC_BCR1_WFDIS));
+
+ /* Set NORSRAM device control parameters */
+ tmpr |= (uint32_t)(Init->DataAddressMux |\
+ Init->MemoryType |\
+ Init->MemoryDataWidth |\
+ Init->BurstAccessMode |\
+ Init->WaitSignalPolarity |\
+ Init->WaitSignalActive |\
+ Init->WriteOperation |\
+ Init->WaitSignal |\
+ Init->ExtendedMode |\
+ Init->AsynchronousWait |\
+ Init->WriteBurst |\
+ Init->ContinuousClock |\
+ Init->PageSize |\
+ Init->WriteFifo);
+#endif /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */
+
+ if(Init->MemoryType == FMC_MEMORY_TYPE_NOR)
+ {
+ tmpr |= (uint32_t)FMC_NORSRAM_FLASH_ACCESS_ENABLE;
+ }
+
+ Device->BTCR[Init->NSBank] = tmpr;
+
+ /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
+ if((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1))
+ {
+ Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->ContinuousClock);
+ }
+
+#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+ if(Init->NSBank != FMC_NORSRAM_BANK1)
+ {
+ Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->WriteFifo);
+ }
+#endif /* STM32F446xx || STM32F469xx || STM32F479xx */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the FMC_NORSRAM peripheral
+ * @param Device: Pointer to NORSRAM device instance
+ * @param ExDevice: Pointer to NORSRAM extended mode device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
+ assert_param(IS_FMC_NORSRAM_BANK(Bank));
+
+ /* Disable the FMC_NORSRAM device */
+ __FMC_NORSRAM_DISABLE(Device, Bank);
+
+ /* De-initialize the FMC_NORSRAM device */
+ /* FMC_NORSRAM_BANK1 */
+ if(Bank == FMC_NORSRAM_BANK1)
+ {
+ Device->BTCR[Bank] = 0x000030DBU;
+ }
+ /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
+ else
+ {
+ Device->BTCR[Bank] = 0x000030D2U;
+ }
+
+ Device->BTCR[Bank + 1] = 0x0FFFFFFFU;
+ ExDevice->BWTR[Bank] = 0x0FFFFFFFU;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FMC_NORSRAM Timing according to the specified
+ * parameters in the FMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency));
+ assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FMC_NORSRAM_BANK(Bank));
+
+ /* Get the BTCR register value */
+ tmpr = Device->BTCR[Bank + 1U];
+
+ /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */
+ tmpr &= ((uint32_t)~(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD | FMC_BTR1_DATAST | \
+ FMC_BTR1_BUSTURN | FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT | \
+ FMC_BTR1_ACCMOD));
+
+ /* Set FMC_NORSRAM device timing parameters */
+ tmpr |= (uint32_t)(Timing->AddressSetupTime |\
+ ((Timing->AddressHoldTime) << 4U) |\
+ ((Timing->DataSetupTime) << 8U) |\
+ ((Timing->BusTurnAroundDuration) << 16U) |\
+ (((Timing->CLKDivision) - 1U) << 20U) |\
+ (((Timing->DataLatency) - 2U) << 24U) |\
+ (Timing->AccessMode));
+
+ Device->BTCR[Bank + 1U] = tmpr;
+
+ /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
+ if(HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN))
+ {
+ tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~(((uint32_t)0x0FU) << 20U));
+ tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << 20U);
+ Device->BTCR[FMC_NORSRAM_BANK1 + 1U] = tmpr;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FMC_NORSRAM Extended mode Timing according to the specified
+ * parameters in the FMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+ if(ExtendedMode == FMC_EXTENDED_MODE_ENABLE)
+ {
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device));
+ assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FMC_NORSRAM_BANK(Bank));
+
+ /* Get the BWTR register value */
+ tmpr = Device->BWTR[Bank];
+
+ /* Clear ADDSET, ADDHLD, DATAST, BUSTURN and ACCMOD bits */
+ tmpr &= ((uint32_t)~(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD | FMC_BWTR1_DATAST | \
+ FMC_BWTR1_BUSTURN | FMC_BWTR1_ACCMOD));
+
+ tmpr |= (uint32_t)(Timing->AddressSetupTime |\
+ ((Timing->AddressHoldTime) << 4U) |\
+ ((Timing->DataSetupTime) << 8U) |\
+ ((Timing->BusTurnAroundDuration) << 16U) |\
+ (Timing->AccessMode));
+
+ Device->BWTR[Bank] = tmpr;
+ }
+ else
+ {
+ Device->BWTR[Bank] = 0x0FFFFFFFU;
+ }
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FMC_NORSRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FMC NORSRAM interface.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables dynamically FMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FMC_NORSRAM_BANK(Bank));
+
+ /* Enable write operation */
+ Device->BTCR[Bank] |= FMC_WRITE_OPERATION_ENABLE;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FMC_NORSRAM_BANK(Bank));
+
+ /* Disable write operation */
+ Device->BTCR[Bank] &= ~FMC_WRITE_OPERATION_ENABLE;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FMC_LL_NAND
+ * @brief NAND Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NAND device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FMC NAND banks in order
+ to run the NAND external devices.
+
+ (+) FMC NAND bank reset using the function FMC_NAND_DeInit()
+ (+) FMC NAND bank control configuration using the function FMC_NAND_Init()
+ (+) FMC NAND bank common space timing configuration using the function
+ FMC_NAND_CommonSpace_Timing_Init()
+ (+) FMC NAND bank attribute space timing configuration using the function
+ FMC_NAND_AttributeSpace_Timing_Init()
+ (+) FMC NAND bank enable/disable ECC correction feature using the functions
+ FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable()
+ (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC()
+
+@endverbatim
+ * @{
+ */
+
+#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+/** @defgroup HAL_FMC_NAND_Group1 Initialization/de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FMC NAND interface
+ (+) De-initialize the FMC NAND interface
+ (+) Configure the FMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FMC_NAND device according to the specified
+ * control parameters in the FMC_NAND_HandleTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Init: Pointer to NAND Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Init->NandBank));
+ assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FMC_ECC_STATE(Init->EccComputation));
+ assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize));
+ assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Get the NAND bank register value */
+ tmpr = Device->PCR;
+
+ /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */
+ tmpr &= ((uint32_t)~(FMC_PCR_PWAITEN | FMC_PCR_PBKEN | FMC_PCR_PTYP | \
+ FMC_PCR_PWID | FMC_PCR_ECCEN | FMC_PCR_TCLR | \
+ FMC_PCR_TAR | FMC_PCR_ECCPS));
+
+ /* Set NAND device control parameters */
+ tmpr |= (uint32_t)(Init->Waitfeature |\
+ FMC_PCR_MEMORY_TYPE_NAND |\
+ Init->MemoryDataWidth |\
+ Init->EccComputation |\
+ Init->ECCPageSize |\
+ ((Init->TCLRSetupTime) << 9U) |\
+ ((Init->TARSetupTime) << 13U));
+
+ /* NAND bank registers configuration */
+ Device->PCR = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_NAND Common space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Get the NAND bank 2 register value */
+ tmpr = Device->PMEM;
+
+
+ /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PMEM_MEMSET2 | FMC_PMEM_MEMWAIT2 | FMC_PMEM_MEMHOLD2 | \
+ FMC_PMEM_MEMHIZ2));
+
+ /* Set FMC_NAND device timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U)
+ );
+
+ /* NAND bank registers configuration */
+ Device->PMEM = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_NAND Attribute space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Get the NAND bank register value */
+ tmpr = Device->PATT;
+
+ /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PATT_ATTSET2 | FMC_PATT_ATTWAIT2 | FMC_PATT_ATTHOLD2 | \
+ FMC_PATT_ATTHIZ2));
+
+ /* Set FMC_NAND device timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U));
+
+ /* NAND bank registers configuration */
+ Device->PATT = tmpr;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DeInitializes the FMC_NAND device
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Disable the NAND Bank */
+ __FMC_NAND_DISABLE(Device, Bank);
+
+ /* De-initialize the NAND Bank */
+ /* Set the FMC_NAND_BANK registers to their reset values */
+ Device->PCR = 0x00000018U;
+ Device->SR = 0x00000040U;
+ Device->PMEM = 0xFCFCFCFCU;
+ Device->PATT = 0xFCFCFCFCU;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup HAL_FMC_NAND_Group2 Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FMC_NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FMC NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Enable ECC feature */
+ Device->PCR |= FMC_PCR_ECCEN;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Disables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Disable ECC feature */
+ Device->PCR &= ~FMC_PCR_ECCEN;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param ECCval: Pointer to ECC value
+ * @param Bank: NAND bank number
+ * @param Timeout: Timeout wait value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until FIFO is empty */
+ while(__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Get the ECCR register value */
+ *ECCval = (uint32_t)Device->ECCR;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#else /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */
+/** @defgroup HAL_FMC_NAND_Group1 Initialization/de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FMC NAND interface
+ (+) De-initialize the FMC NAND interface
+ (+) Configure the FMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the FMC_NAND device according to the specified
+ * control parameters in the FMC_NAND_HandleTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Init: Pointer to NAND Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Init->NandBank));
+ assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FMC_ECC_STATE(Init->EccComputation));
+ assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize));
+ assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
+
+ if(Init->NandBank == FMC_NAND_BANK2)
+ {
+ /* Get the NAND bank 2 register value */
+ tmpr = Device->PCR2;
+ }
+ else
+ {
+ /* Get the NAND bank 3 register value */
+ tmpr = Device->PCR3;
+ }
+
+ /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */
+ tmpr &= ((uint32_t)~(FMC_PCR2_PWAITEN | FMC_PCR2_PBKEN | FMC_PCR2_PTYP | \
+ FMC_PCR2_PWID | FMC_PCR2_ECCEN | FMC_PCR2_TCLR | \
+ FMC_PCR2_TAR | FMC_PCR2_ECCPS));
+
+ /* Set NAND device control parameters */
+ tmpr |= (uint32_t)(Init->Waitfeature |\
+ FMC_PCR_MEMORY_TYPE_NAND |\
+ Init->MemoryDataWidth |\
+ Init->EccComputation |\
+ Init->ECCPageSize |\
+ ((Init->TCLRSetupTime) << 9U) |\
+ ((Init->TARSetupTime) << 13U));
+
+ if(Init->NandBank == FMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ Device->PCR2 = tmpr;
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ Device->PCR3 = tmpr;
+ }
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Initializes the FMC_NAND Common space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* Get the NAND bank 2 register value */
+ tmpr = Device->PMEM2;
+ }
+ else
+ {
+ /* Get the NAND bank 3 register value */
+ tmpr = Device->PMEM3;
+ }
+
+ /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PMEM2_MEMSET2 | FMC_PMEM2_MEMWAIT2 | FMC_PMEM2_MEMHOLD2 | \
+ FMC_PMEM2_MEMHIZ2));
+
+ /* Set FMC_NAND device timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U)
+ );
+
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ Device->PMEM2 = tmpr;
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ Device->PMEM3 = tmpr;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_NAND Attribute space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* Get the NAND bank 2 register value */
+ tmpr = Device->PATT2;
+ }
+ else
+ {
+ /* Get the NAND bank 3 register value */
+ tmpr = Device->PATT3;
+ }
+
+ /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PATT2_ATTSET2 | FMC_PATT2_ATTWAIT2 | FMC_PATT2_ATTHOLD2 | \
+ FMC_PATT2_ATTHIZ2));
+
+ /* Set FMC_NAND device timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U));
+
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ Device->PATT2 = tmpr;
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ Device->PATT3 = tmpr;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FMC_NAND device
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Disable the NAND Bank */
+ __FMC_NAND_DISABLE(Device, Bank);
+
+ /* De-initialize the NAND Bank */
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* Set the FMC_NAND_BANK2 registers to their reset values */
+ Device->PCR2 = 0x00000018U;
+ Device->SR2 = 0x00000040U;
+ Device->PMEM2 = 0xFCFCFCFCU;
+ Device->PATT2 = 0xFCFCFCFCU;
+ }
+ /* FMC_Bank3_NAND */
+ else
+ {
+ /* Set the FMC_NAND_BANK3 registers to their reset values */
+ Device->PCR3 = 0x00000018U;
+ Device->SR3 = 0x00000040U;
+ Device->PMEM3 = 0xFCFCFCFCU;
+ Device->PATT3 = 0xFCFCFCFCU;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup FMC_LL_NAND_Private_Functions_Group2
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FMC_NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FMC NAND interface.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Enable ECC feature */
+ if(Bank == FMC_NAND_BANK2)
+ {
+ Device->PCR2 |= FMC_PCR2_ECCEN;
+ }
+ else
+ {
+ Device->PCR3 |= FMC_PCR3_ECCEN;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Disable ECC feature */
+ if(Bank == FMC_NAND_BANK2)
+ {
+ Device->PCR2 &= ~FMC_PCR2_ECCEN;
+ }
+ else
+ {
+ Device->PCR3 &= ~FMC_PCR3_ECCEN;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param ECCval: Pointer to ECC value
+ * @param Bank: NAND bank number
+ * @param Timeout: Timeout wait value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_NAND_DEVICE(Device));
+ assert_param(IS_FMC_NAND_BANK(Bank));
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until FIFO is empty */
+ while(__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ if(Bank == FMC_NAND_BANK2)
+ {
+ /* Get the ECCR2 register value */
+ *ECCval = (uint32_t)Device->ECCR2;
+ }
+ else
+ {
+ /* Get the ECCR3 register value */
+ *ECCval = (uint32_t)Device->ECCR3;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) */
+/**
+ * @}
+ */
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+/** @addtogroup FMC_LL_PCCARD
+ * @brief PCCARD Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use PCCARD device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FMC PCCARD bank in order
+ to run the PCCARD/compact flash external devices.
+
+ (+) FMC PCCARD bank reset using the function FMC_PCCARD_DeInit()
+ (+) FMC PCCARD bank control configuration using the function FMC_PCCARD_Init()
+ (+) FMC PCCARD bank common space timing configuration using the function
+ FMC_PCCARD_CommonSpace_Timing_Init()
+ (+) FMC PCCARD bank attribute space timing configuration using the function
+ FMC_PCCARD_AttributeSpace_Timing_Init()
+ (+) FMC PCCARD bank IO space timing configuration using the function
+ FMC_PCCARD_IOSpace_Timing_Init()
+@endverbatim
+ * @{
+ */
+
+/** @addtogroup FMC_LL_PCCARD_Private_Functions_Group1
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FMC PCCARD interface
+ (+) De-initialize the FMC PCCARD interface
+ (+) Configure the FMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FMC_PCCARD device according to the specified
+ * control parameters in the FMC_PCCARD_HandleTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Init: Pointer to PCCARD Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_PCCARD_Init(FMC_PCCARD_TypeDef *Device, FMC_PCCARD_InitTypeDef *Init)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Get PCCARD control register value */
+ tmpr = Device->PCR4;
+
+ /* Clear TAR, TCLR, PWAITEN and PWID bits */
+ tmpr &= ((uint32_t)~(FMC_PCR4_TAR | FMC_PCR4_TCLR | FMC_PCR4_PWAITEN | \
+ FMC_PCR4_PWID));
+
+ /* Set FMC_PCCARD device control parameters */
+ tmpr |= (uint32_t)(Init->Waitfeature |\
+ FMC_NAND_PCC_MEM_BUS_WIDTH_16 |\
+ (Init->TCLRSetupTime << 9U) |\
+ (Init->TARSetupTime << 13U));
+
+ Device->PCR4 = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_PCCARD Common space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_PCCARD_CommonSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Get PCCARD common space timing register value */
+ tmpr = Device->PMEM4;
+
+ /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PMEM4_MEMSET4 | FMC_PMEM4_MEMWAIT4 | FMC_PMEM4_MEMHOLD4 | \
+ FMC_PMEM4_MEMHIZ4));
+ /* Set PCCARD timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U));
+
+ Device->PMEM4 = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_PCCARD Attribute space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_PCCARD_AttributeSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ uint32_t tmpr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Get PCCARD timing parameters */
+ tmpr = Device->PATT4;
+
+ /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */
+ tmpr &= ((uint32_t)~(FMC_PATT4_ATTSET4 | FMC_PATT4_ATTWAIT4 | FMC_PATT4_ATTHOLD4 | \
+ FMC_PATT4_ATTHIZ4));
+
+ /* Set PCCARD timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U));
+ Device->PATT4 = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_PCCARD IO space Timing according to the specified
+ * parameters in the FMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_PCCARD_IOSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ uint32_t tmpr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Get FMC_PCCARD device timing parameters */
+ tmpr = Device->PIO4;
+
+ /* Clear IOSET4, IOWAIT4, IOHOLD4 and IOHIZ4 bits */
+ tmpr &= ((uint32_t)~(FMC_PIO4_IOSET4 | FMC_PIO4_IOWAIT4 | FMC_PIO4_IOHOLD4 | \
+ FMC_PIO4_IOHIZ4));
+
+ /* Set FMC_PCCARD device timing parameters */
+ tmpr |= (uint32_t)(Timing->SetupTime |\
+ ((Timing->WaitSetupTime) << 8U) |\
+ ((Timing->HoldSetupTime) << 16U) |\
+ ((Timing->HiZSetupTime) << 24U));
+
+ Device->PIO4 = tmpr;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FMC_PCCARD device
+ * @param Device: Pointer to PCCARD device instance
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_PCCARD_DeInit(FMC_PCCARD_TypeDef *Device)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_PCCARD_DEVICE(Device));
+
+ /* Disable the FMC_PCCARD device */
+ __FMC_PCCARD_DISABLE(Device);
+
+ /* De-initialize the FMC_PCCARD device */
+ Device->PCR4 = 0x00000018U;
+ Device->SR4 = 0x00000000U;
+ Device->PMEM4 = 0xFCFCFCFCU;
+ Device->PATT4 = 0xFCFCFCFCU;
+ Device->PIO4 = 0xFCFCFCFCU;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
+
+
+/** @addtogroup FMC_LL_SDRAM
+ * @brief SDRAM Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use SDRAM device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FMC SDRAM banks in order
+ to run the SDRAM external devices.
+
+ (+) FMC SDRAM bank reset using the function FMC_SDRAM_DeInit()
+ (+) FMC SDRAM bank control configuration using the function FMC_SDRAM_Init()
+ (+) FMC SDRAM bank timing configuration using the function FMC_SDRAM_Timing_Init()
+ (+) FMC SDRAM bank enable/disable write operation using the functions
+ FMC_SDRAM_WriteOperation_Enable()/FMC_SDRAM_WriteOperation_Disable()
+ (+) FMC SDRAM bank send command using the function FMC_SDRAM_SendCommand()
+
+@endverbatim
+ * @{
+ */
+
+/** @addtogroup FMC_LL_SDRAM_Private_Functions_Group1
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FMC SDRAM interface
+ (+) De-initialize the FMC SDRAM interface
+ (+) Configure the FMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FMC_SDRAM device according to the specified
+ * control parameters in the FMC_SDRAM_InitTypeDef
+ * @param Device: Pointer to SDRAM device instance
+ * @param Init: Pointer to SDRAM Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init)
+{
+ uint32_t tmpr1 = 0U;
+ uint32_t tmpr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_SDRAM_BANK(Init->SDBank));
+ assert_param(IS_FMC_COLUMNBITS_NUMBER(Init->ColumnBitsNumber));
+ assert_param(IS_FMC_ROWBITS_NUMBER(Init->RowBitsNumber));
+ assert_param(IS_FMC_SDMEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FMC_INTERNALBANK_NUMBER(Init->InternalBankNumber));
+ assert_param(IS_FMC_CAS_LATENCY(Init->CASLatency));
+ assert_param(IS_FMC_WRITE_PROTECTION(Init->WriteProtection));
+ assert_param(IS_FMC_SDCLOCK_PERIOD(Init->SDClockPeriod));
+ assert_param(IS_FMC_READ_BURST(Init->ReadBurst));
+ assert_param(IS_FMC_READPIPE_DELAY(Init->ReadPipeDelay));
+
+ /* Set SDRAM bank configuration parameters */
+ if (Init->SDBank != FMC_SDRAM_BANK2)
+ {
+ tmpr1 = Device->SDCR[FMC_SDRAM_BANK1];
+
+ /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+ tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \
+ FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \
+ FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
+
+
+ tmpr1 |= (uint32_t)(Init->ColumnBitsNumber |\
+ Init->RowBitsNumber |\
+ Init->MemoryDataWidth |\
+ Init->InternalBankNumber |\
+ Init->CASLatency |\
+ Init->WriteProtection |\
+ Init->SDClockPeriod |\
+ Init->ReadBurst |\
+ Init->ReadPipeDelay
+ );
+ Device->SDCR[FMC_SDRAM_BANK1] = tmpr1;
+ }
+ else /* FMC_Bank2_SDRAM */
+ {
+///////////////////////////////
+// BEGIN PIECE OF WEIRD CODE //
+///////////////////////////////
+//
+// tmpr1 = Device->SDCR[FMC_SDRAM_BANK1];
+//
+// /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+// tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \
+// FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \
+// FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE));
+//
+// tmpr1 |= (uint32_t)(Init->SDClockPeriod |\
+// Init->ReadBurst |\
+// Init->ReadPipeDelay);
+//
+///////////////////////////////
+// END PIECE OF WEIRD CODE //
+///////////////////////////////
+
+ tmpr2 = Device->SDCR[FMC_SDRAM_BANK1];
+
+ /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */
+ tmpr2 &= ((uint32_t)~(FMC_SDCR2_NC | FMC_SDCR2_NR | FMC_SDCR2_MWID | \
+ FMC_SDCR2_NB | FMC_SDCR2_CAS | FMC_SDCR2_WP | \
+ FMC_SDCR2_SDCLK | FMC_SDCR2_RBURST | FMC_SDCR2_RPIPE));
+
+ tmpr2 |= (uint32_t)(Init->ColumnBitsNumber |\
+ Init->RowBitsNumber |\
+ Init->MemoryDataWidth |\
+ Init->InternalBankNumber |\
+ Init->CASLatency |\
+ Init->WriteProtection);
+
+//
+// Device->SDCR[FMC_SDRAM_BANK1] = tmpr1;
+//
+ Device->SDCR[FMC_SDRAM_BANK2] = tmpr2;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FMC_SDRAM device timing according to the specified
+ * parameters in the FMC_SDRAM_TimingTypeDef
+ * @param Device: Pointer to SDRAM device instance
+ * @param Timing: Pointer to SDRAM Timing structure
+ * @param Bank: SDRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank)
+{
+ uint32_t tmpr1 = 0U;
+ uint32_t tmpr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_LOADTOACTIVE_DELAY(Timing->LoadToActiveDelay));
+ assert_param(IS_FMC_EXITSELFREFRESH_DELAY(Timing->ExitSelfRefreshDelay));
+ assert_param(IS_FMC_SELFREFRESH_TIME(Timing->SelfRefreshTime));
+ assert_param(IS_FMC_ROWCYCLE_DELAY(Timing->RowCycleDelay));
+ assert_param(IS_FMC_WRITE_RECOVERY_TIME(Timing->WriteRecoveryTime));
+ assert_param(IS_FMC_RP_DELAY(Timing->RPDelay));
+ assert_param(IS_FMC_RCD_DELAY(Timing->RCDDelay));
+ assert_param(IS_FMC_SDRAM_BANK(Bank));
+
+ /* Set SDRAM device timing parameters */
+ if (Bank != FMC_SDRAM_BANK2)
+ {
+ tmpr1 = Device->SDTR[FMC_SDRAM_BANK1];
+
+ /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+ tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \
+ FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \
+ FMC_SDTR1_TRCD));
+
+ tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1U) |\
+ (((Timing->ExitSelfRefreshDelay)-1U) << 4U) |\
+ (((Timing->SelfRefreshTime)-1U) << 8U) |\
+ (((Timing->RowCycleDelay)-1U) << 12U) |\
+ (((Timing->WriteRecoveryTime)-1U) <<16U) |\
+ (((Timing->RPDelay)-1U) << 20U) |\
+ (((Timing->RCDDelay)-1U) << 24U));
+ Device->SDTR[FMC_SDRAM_BANK1] = tmpr1;
+ }
+ else /* FMC_Bank2_SDRAM */
+ {
+///////////////////////////////
+// BEGIN PIECE OF WEIRD CODE //
+///////////////////////////////
+//
+// tmpr1 = Device->SDTR[FMC_SDRAM_BANK2];
+//
+// /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+// tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \
+// FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \
+// FMC_SDTR1_TRCD));
+//
+// tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1U) |\
+// (((Timing->ExitSelfRefreshDelay)-1U) << 4U) |\
+// (((Timing->SelfRefreshTime)-1U) << 8U) |\
+// (((Timing->WriteRecoveryTime)-1U) <<16U) |\
+// (((Timing->RCDDelay)-1U) << 24U));
+//
+///////////////////////////////
+// END PIECE OF WEIRD CODE //
+///////////////////////////////
+
+ tmpr2 = Device->SDTR[FMC_SDRAM_BANK1];
+
+ /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */
+ tmpr2 &= ((uint32_t)~(FMC_SDTR2_TMRD | FMC_SDTR2_TXSR | FMC_SDTR2_TRAS | \
+ FMC_SDTR2_TRC | FMC_SDTR2_TWR | FMC_SDTR2_TRP | \
+ FMC_SDTR2_TRCD));
+
+ tmpr2 |= (uint32_t)(((Timing->LoadToActiveDelay)-1U) |\
+ (((Timing->ExitSelfRefreshDelay)-1U) << 4U) |\
+ (((Timing->SelfRefreshTime)-1U) << 8U) |\
+ (((Timing->WriteRecoveryTime)-1U) <<16U) |\
+ (((Timing->RCDDelay)-1U) << 24U));
+
+//
+// Device->SDTR[FMC_SDRAM_BANK2] = tmpr1;
+//
+ Device->SDTR[FMC_SDRAM_BANK2] = tmpr2;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FMC_SDRAM peripheral
+ * @param Device: Pointer to SDRAM device instance
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_SDRAM_BANK(Bank));
+
+ /* De-initialize the SDRAM device */
+ Device->SDCR[Bank] = 0x000002D0U;
+ Device->SDTR[Bank] = 0x0FFFFFFFU;
+ Device->SDCMR = 0x00000000U;
+ Device->SDRTR = 0x00000000U;
+ Device->SDSR = 0x00000000U;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup FMC_LL_SDRAMPrivate_Functions_Group2
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FMC_SDRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FMC SDRAM interface.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables dynamically FMC_SDRAM write protection.
+ * @param Device: Pointer to SDRAM device instance
+ * @param Bank: SDRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_SDRAM_BANK(Bank));
+
+ /* Enable write protection */
+ Device->SDCR[Bank] |= FMC_SDRAM_WRITE_PROTECTION_ENABLE;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FMC_SDRAM write protection.
+ * @param hsdram: FMC_SDRAM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_SDRAM_BANK(Bank));
+
+ /* Disable write protection */
+ Device->SDCR[Bank] &= ~FMC_SDRAM_WRITE_PROTECTION_ENABLE;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Send Command to the FMC SDRAM bank
+ * @param Device: Pointer to SDRAM device instance
+ * @param Command: Pointer to SDRAM command structure
+ * @param Timing: Pointer to SDRAM Timing structure
+ * @param Timeout: Timeout wait value
+ * @retval HAL state
+ */
+HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout)
+{
+ __IO uint32_t tmpr = 0U;
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_COMMAND_MODE(Command->CommandMode));
+ assert_param(IS_FMC_COMMAND_TARGET(Command->CommandTarget));
+ assert_param(IS_FMC_AUTOREFRESH_NUMBER(Command->AutoRefreshNumber));
+ assert_param(IS_FMC_MODE_REGISTER(Command->ModeRegisterDefinition));
+
+ /* Set command register */
+ tmpr = (uint32_t)((Command->CommandMode) |\
+ (Command->CommandTarget) |\
+ (((Command->AutoRefreshNumber)-1U) << 5U) |\
+ ((Command->ModeRegisterDefinition) << 9U)
+ );
+
+ Device->SDCMR = tmpr;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until command is send */
+ while(HAL_IS_BIT_SET(Device->SDSR, FMC_SDSR_BUSY))
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Program the SDRAM Memory Refresh rate.
+ * @param Device: Pointer to SDRAM device instance
+ * @param RefreshRate: The SDRAM refresh rate value.
+ * @retval HAL state
+ */
+HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_REFRESH_RATE(RefreshRate));
+
+ /* Set the refresh rate in command register */
+ Device->SDRTR |= (RefreshRate<<1U);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the Number of consecutive SDRAM Memory auto Refresh commands.
+ * @param Device: Pointer to SDRAM device instance
+ * @param AutoRefreshNumber: Specifies the auto Refresh number.
+ * @retval None
+ */
+HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, uint32_t AutoRefreshNumber)
+{
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_AUTOREFRESH_NUMBER(AutoRefreshNumber));
+
+ /* Set the Auto-refresh number in command register */
+ Device->SDCMR |= (AutoRefreshNumber << 5U);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Returns the indicated FMC SDRAM bank mode status.
+ * @param Device: Pointer to SDRAM device instance
+ * @param Bank: Defines the FMC SDRAM bank. This parameter can be
+ * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM.
+ * @retval The FMC SDRAM bank mode status, could be on of the following values:
+ * FMC_SDRAM_NORMAL_MODE, FMC_SDRAM_SELF_REFRESH_MODE or
+ * FMC_SDRAM_POWER_DOWN_MODE.
+ */
+uint32_t FMC_SDRAM_GetModeStatus(FMC_SDRAM_TypeDef *Device, uint32_t Bank)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FMC_SDRAM_DEVICE(Device));
+ assert_param(IS_FMC_SDRAM_BANK(Bank));
+
+ /* Get the corresponding bank mode */
+ if(Bank == FMC_SDRAM_BANK1)
+ {
+ tmpreg = (uint32_t)(Device->SDSR & FMC_SDSR_MODES1);
+ }
+ else
+ {
+ tmpreg = ((uint32_t)(Device->SDSR & FMC_SDSR_MODES2) >> 2U);
+ }
+
+ /* Return the mode status */
+ return tmpreg;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
+#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_PCCARD_MODULE_ENABLED || HAL_SDRAM_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/