aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32/LLD/FSMCv1
diff options
context:
space:
mode:
authorbarthess <barthess@yandex.ru>2014-10-19 23:58:48 +0300
committerbarthess <barthess@yandex.ru>2014-10-19 23:58:48 +0300
commit8dabb3b8f529dafece19b728899290ad3deb8fb5 (patch)
tree5ba1f35e586e5b6d5fe18199ec62e24296dedc37 /os/hal/ports/STM32/LLD/FSMCv1
parent721c48bc978edeeff89e4b1169cb96b1569fdc3a (diff)
downloadChibiOS-Contrib-8dabb3b8f529dafece19b728899290ad3deb8fb5.tar.gz
ChibiOS-Contrib-8dabb3b8f529dafece19b728899290ad3deb8fb5.tar.bz2
ChibiOS-Contrib-8dabb3b8f529dafece19b728899290ad3deb8fb5.zip
Added SDRAM support via FSMC
Diffstat (limited to 'os/hal/ports/STM32/LLD/FSMCv1')
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c264
-rw-r--r--os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h382
2 files changed, 646 insertions, 0 deletions
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c
new file mode 100644
index 0000000..eca66ea
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c
@@ -0,0 +1,264 @@
+/*
+ ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess (SDRAM routines added by Nick Klimov aka progfin).
+ */
+
+/**
+ * @file fsmc_sdram.c
+ * @brief SDRAM Driver subsystem low level driver source.
+ *
+ * @addtogroup SDRAM
+ * @{
+ */
+
+#include "hal.h"
+
+#if (defined(STM32F427xx) || defined(STM32F437xx) || \
+ defined(STM32F429xx) || defined(STM32F439xx))
+
+#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__)
+
+#include "fsmc_sdram.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+/**
+ * @brief SDRAM1 driver identifier.
+ */
+#if STM32_SDRAM_USE_FSMC_SDRAM1 || defined(__DOXYGEN__)
+SDRAMDriver SDRAMD1;
+#endif
+
+/**
+ * @brief SDRAM2 driver identifier.
+ */
+#if STM32_SDRAM_USE_FSMC_SDRAM2 || defined(__DOXYGEN__)
+SDRAMDriver SDRAMD2;
+#endif
+
+/*===========================================================================*/
+/* Driver local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Executes the SDRAM memory initialization sequence.
+ *
+ * @param[in] sdramp pointer to the @p SDRAMDriver object
+ *
+ * @notapi
+ */
+static void fsmcSdramInitSequence(uint32_t CommandTarget) {
+ uint32_t tmpreg;
+ /* Step 3 -----------------------------------------------------------------*/
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ /* Configure a clock configuration enable command */
+ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled |
+ CommandTarget |
+ ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1
+ (0 << 9); // FMC_ModeRegisterDefinition = 0
+ /* Step 4 -----------------------------------------------------------------*/
+ /* Insert 10 ms delay */
+ chSysPolledDelayX(MS2ST(10));
+ /* Step 5 -----------------------------------------------------------------*/
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ /* Configure a PALL (precharge all) command */
+ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_PALL |
+ CommandTarget |
+ ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1
+ (0 << 9); // FMC_ModeRegisterDefinition = 0
+ /* Step 6 -----------------------------------------------------------------*/
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ /* Configure a Auto-Refresh command: Send the first command */
+ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh |
+ CommandTarget |
+ ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4
+ (0 << 9); // FMC_ModeRegisterDefinition = 0
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ /* Configure a Auto-Refresh command: Send the second command*/
+ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh |
+ CommandTarget |
+ ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4
+ (0 << 9); // FMC_ModeRegisterDefinition = 0
+ /* Step 7 -----------------------------------------------------------------*/
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ /* Program the external memory mode register */
+ tmpreg = FMC_SDCMR_MRD_BURST_LENGTH_2 |
+ FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL |
+ FMC_SDCMR_MRD_CAS_LATENCY_3 |
+ FMC_SDCMR_MRD_OPERATING_MODE_STANDARD |
+ FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE;
+ /* Send the command */
+ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode |
+ CommandTarget |
+ ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1
+ (tmpreg << 9);
+ /* Step 8 -----------------------------------------------------------------*/
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+ // 64ms/4096=15.625us
+#if (STM32_SYSCLK == 180000000)
+ //15.625us*90MHz=1406-20=1386
+ FMC_Bank5_6->SDRTR=1386<<1;
+#elif (STM32_SYSCLK == 168000000)
+ //15.625us*84MHz=1312-20=1292
+ FMC_Bank5_6->SDRTR=1292<<1;
+#else
+ #error No refresh timings for this clock
+#endif
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDRAM driver initialization.
+ *
+ * @notapi
+ */
+void fsmcSdramInit(void) {
+
+ fsmc_init();
+
+#if STM32_SDRAM_USE_FSMC_SDRAM1
+ SDRAMD1.sdram = FSMCD1.sdram1;
+ SDRAMD1.state = SDRAM_STOP;
+#endif /* STM32_SDRAM_USE_FSMC_SDRAM1 */
+
+#if STM32_SDRAM_USE_FSMC_SDRAM2
+ SDRAMD2.sdram = FSMCD1.sdram2;
+ SDRAMD2.state = SDRAM_STOP;
+#endif /* STM32_SDRAM_USE_FSMC_SDRAM2 */
+
+}
+
+/**
+ * @brief Configures and activates the SDRAM peripheral.
+ *
+ * @param[in] sdramp pointer to the @p SDRAMDriver object
+ * @param[in] cfgp pointer to the @p SDRAMConfig object
+ *
+ * @notapi
+ */
+#define SDCR2_DONTCARE_BITS (FMC_SDClock_Period_Mask | \
+ FMC_Read_Burst_Mask | \
+ FMC_ReadPipe_Delay_Mask)
+#define SDTR2_DONTCARE_BITS (FMC_RowCycleDelay_Mask | FMC_RPDelay_Mask)
+void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) {
+
+ if (FSMCD1.state == FSMC_STOP)
+ fsmc_start(&FSMCD1);
+
+ osalDbgAssert((sdramp->state == SDRAM_STOP) || (sdramp->state == SDRAM_READY),
+ "invalid state");
+
+ if (sdramp->state == SDRAM_STOP) {
+ // Executes the SDRAM memory initialization sequence.
+ if (sdramp->sdram == (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE) {
+ sdramp->sdram->SDCR = cfgp->sdcr;
+ sdramp->sdram->SDTR = cfgp->sdtr;
+ fsmcSdramInitSequence(FMC_Command_Target_bank1);
+ } else { /* SDCR2 "don't care" bits configuration */
+ ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDCR =
+ cfgp->sdcr & SDCR2_DONTCARE_BITS;
+ sdramp->sdram->SDCR = cfgp->sdcr;
+ ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDTR =
+ cfgp->sdtr & SDTR2_DONTCARE_BITS;
+ sdramp->sdram->SDTR = cfgp->sdtr;
+ fsmcSdramInitSequence(FMC_Command_Target_bank2);
+ }
+ sdramp->state = SDRAM_READY;
+ }
+
+}
+
+/**
+ * @brief Deactivates the SDRAM peripheral.
+ *
+ * @param[in] sdramp pointer to the @p SDRAMDriver object
+ *
+ * @notapi
+ */
+void fsmcSdramStop(SDRAMDriver *sdramp) {
+
+ if (sdramp->state == SDRAM_READY) {
+ sdramp->state = SDRAM_STOP;
+ }
+}
+
+
+/**
+ * @brief Wait until the SDRAM controller is ready.
+ *
+ * @notapi
+ */
+void fsmcSdram_WaitReady(void) {
+ /* Wait until the SDRAM controller is ready */
+ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
+}
+
+/**
+ * @brief Enables or disables write protection to the specified SDRAM Bank.
+ * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be
+ * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM.
+ * @param NewState: new state of the write protection flag.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+/* FMC SDCRx write protection Mask*/
+#define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF)
+void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State) {
+
+ if (State)
+ sdramp->sdram->SDCR |= FMC_Write_Protection_Enable;
+ else
+ sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET;
+
+}
+
+
+#endif /* STM32_USE_FSMC_SDRAM */
+
+#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */
+
+/** @} */
+
diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h
new file mode 100644
index 0000000..17fc28d
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h
@@ -0,0 +1,382 @@
+/*
+ ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess (SDRAM routines added by Nick Klimov aka progfin).
+ */
+
+/**
+ * @file fsmc_sdram.h
+ * @brief SDRAM Driver subsystem low level driver header.
+ *
+ * @addtogroup SDRAM
+ * @{
+ */
+
+#ifndef _FMC_SDRAM_H_
+#define _FMC_SDRAM_H_
+
+#if (defined(STM32F427xx) || defined(STM32F437xx) || \
+ defined(STM32F429xx) || defined(STM32F439xx))
+
+#include "fsmc.h"
+
+#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/** @defgroup FMC_ColumnBits_Number
+ * @{
+ */
+#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000)
+#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001)
+#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002)
+#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003)
+
+#define IS_FMC_COLUMNBITS_NUMBER(COLUMN) \
+ (((COLUMN) == FMC_ColumnBits_Number_8b) || \
+ ((COLUMN) == FMC_ColumnBits_Number_9b) || \
+ ((COLUMN) == FMC_ColumnBits_Number_10b) || \
+ ((COLUMN) == FMC_ColumnBits_Number_11b))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_RowBits_Number
+ * @{
+ */
+#define FMC_RowBits_Number_11b ((uint32_t)0x00000000)
+#define FMC_RowBits_Number_12b ((uint32_t)0x00000004)
+#define FMC_RowBits_Number_13b ((uint32_t)0x00000008)
+
+#define IS_FMC_ROWBITS_NUMBER(ROW) \
+ (((ROW) == FMC_RowBits_Number_11b) || \
+ ((ROW) == FMC_RowBits_Number_12b) || \
+ ((ROW) == FMC_RowBits_Number_13b))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_SDMemory_Data_Width
+ * @{
+ */
+#define FMC_SDMemory_Width_8b ((uint32_t)0x00000000)
+#define FMC_SDMemory_Width_16b ((uint32_t)0x00000010)
+#define FMC_SDMemory_Width_32b ((uint32_t)0x00000020)
+
+#define IS_FMC_SDMEMORY_WIDTH(WIDTH) \
+ (((WIDTH) == FMC_SDMemory_Width_8b) || \
+ ((WIDTH) == FMC_SDMemory_Width_16b) || \
+ ((WIDTH) == FMC_SDMemory_Width_32b))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_InternalBank_Number
+ * @{
+ */
+#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000)
+#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040)
+
+#define IS_FMC_INTERNALBANK_NUMBER(NUMBER) \
+ (((NUMBER) == FMC_InternalBank_Number_2) || \
+ ((NUMBER) == FMC_InternalBank_Number_4))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FMC_CAS_Latency
+ * @{
+ */
+#define FMC_CAS_Latency_1 ((uint32_t)0x00000080)
+#define FMC_CAS_Latency_2 ((uint32_t)0x00000100)
+#define FMC_CAS_Latency_3 ((uint32_t)0x00000180)
+
+#define IS_FMC_CAS_LATENCY(LATENCY) \
+ (((LATENCY) == FMC_CAS_Latency_1) || \
+ ((LATENCY) == FMC_CAS_Latency_2) || \
+ ((LATENCY) == FMC_CAS_Latency_3))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_Write_Protection
+ * @{
+ */
+#define FMC_Write_Protection_Disable ((uint32_t)0x00000000)
+#define FMC_Write_Protection_Enable ((uint32_t)0x00000200)
+
+#define IS_FMC_WRITE_PROTECTION(WRITE) \
+ (((WRITE) == FMC_Write_Protection_Disable) || \
+ ((WRITE) == FMC_Write_Protection_Enable))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FMC_SDClock_Period
+ * @{
+ */
+#define FMC_SDClock_Disable ((uint32_t)0x00000000)
+#define FMC_SDClock_Period_2 ((uint32_t)0x00000800)
+#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00)
+#define FMC_SDClock_Period_Mask ((uint32_t)0x00000C00)
+
+#define IS_FMC_SDCLOCK_PERIOD(PERIOD) \
+ (((PERIOD) == FMC_SDClock_Disable) || \
+ ((PERIOD) == FMC_SDClock_Period_2) || \
+ ((PERIOD) == FMC_SDClock_Period_3))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_Read_Burst
+ * @{
+ */
+#define FMC_Read_Burst_Disable ((uint32_t)0x00000000)
+#define FMC_Read_Burst_Enable ((uint32_t)0x00001000)
+#define FMC_Read_Burst_Mask ((uint32_t)0x00001000)
+
+#define IS_FMC_READ_BURST(RBURST) \
+ (((RBURST) == FMC_Read_Burst_Disable) || \
+ ((RBURST) == FMC_Read_Burst_Enable))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_ReadPipe_Delay
+ * @{
+ */
+#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000)
+#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000)
+#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000)
+#define FMC_ReadPipe_Delay_Mask ((uint32_t)0x00006000)
+
+#define IS_FMC_READPIPE_DELAY(DELAY) \
+ (((DELAY) == FMC_ReadPipe_Delay_0) || \
+ ((DELAY) == FMC_ReadPipe_Delay_1) || \
+ ((DELAY) == FMC_ReadPipe_Delay_2))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_Command_Mode
+ * @{
+ */
+#define FMC_Command_Mode_normal ((uint32_t)0x00000000)
+#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001)
+#define FMC_Command_Mode_PALL ((uint32_t)0x00000002)
+#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003)
+#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004)
+#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005)
+#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006)
+
+#define IS_FMC_COMMAND_MODE(COMMAND) \
+ (((COMMAND) == FMC_Command_Mode_normal) || \
+ ((COMMAND) == FMC_Command_Mode_CLK_Enabled) || \
+ ((COMMAND) == FMC_Command_Mode_PALL) || \
+ ((COMMAND) == FMC_Command_Mode_AutoRefresh) || \
+ ((COMMAND) == FMC_Command_Mode_LoadMode) || \
+ ((COMMAND) == FMC_Command_Mode_Selfrefresh) || \
+ ((COMMAND) == FMC_Command_Mode_PowerDown))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_Command_Target
+ * @{
+ */
+#define FMC_Command_Target_bank2 ((uint32_t)0x00000008)
+#define FMC_Command_Target_bank1 ((uint32_t)0x00000010)
+#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018)
+
+#define IS_FMC_COMMAND_TARGET(TARGET) \
+ (((TARGET) == FMC_Command_Target_bank1) || \
+ ((TARGET) == FMC_Command_Target_bank2) || \
+ ((TARGET) == FMC_Command_Target_bank1_2))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_AutoRefresh_Number
+ * @{
+ */
+#define IS_FMC_AUTOREFRESH_NUMBER(NUMBER) (((NUMBER) > 0) && ((NUMBER) <= 16))
+
+/**
+ * @}
+ */
+
+/** @defgroup FMC_ModeRegister_Definition
+ * @{
+ */
+#define IS_FMC_MODE_REGISTER(CONTENT) ((CONTENT) <= 8191)
+
+/**
+ * @}
+ */
+
+
+/**
+ * @brief FMC SDRAM Mode definition register defines
+ */
+#define FMC_SDCMR_MRD_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define FMC_SDCMR_MRD_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define FMC_SDCMR_MRD_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define FMC_SDCMR_MRD_BURST_LENGTH_8 ((uint16_t)0x0004)
+#define FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define FMC_SDCMR_MRD_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+#define FMC_SDCMR_MRD_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define FMC_SDCMR_MRD_CAS_LATENCY_3 ((uint16_t)0x0030)
+#define FMC_SDCMR_MRD_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+#define FMC_SDCMR_MRD_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+
+
+#define FMC_RowCycleDelay_Mask ((uint16_t)0x0000000F << 12)
+#define FMC_RPDelay_Mask ((uint16_t)0x0000000F << 20)
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+/**
+ * @name Configuration options
+ * @{
+ */
+
+/**
+ * @brief SDRAM driver enable switch.
+ * @details If set to @p TRUE the support for SDRAM1 is included.
+ */
+#if !defined(STM32_SDRAM_USE_FSMC_SDRAM1) || defined(__DOXYGEN__)
+#define STM32_SDRAM_USE_FSMC_SDRAM1 FALSE
+#else
+#define STM32_SDRAM1_MAP_BASE FSMC_Bank5_MAP_BASE
+#endif
+
+/**
+ * @brief SDRAM driver enable switch.
+ * @details If set to @p TRUE the support for SDRAM2 is included.
+ */
+#if !defined(STM32_SDRAM_USE_FSMC_SDRAM2) || defined(__DOXYGEN__)
+#define STM32_SDRAM_USE_FSMC_SDRAM2 FALSE
+#else
+#define STM32_SDRAM2_MAP_BASE FSMC_Bank6_MAP_BASE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !STM32_SDRAM_USE_FSMC_SDRAM1 && !STM32_SDRAM_USE_FSMC_SDRAM2
+#error "SDRAM driver activated but no SDRAM peripheral assigned"
+#endif
+
+#if (STM32_SDRAM_USE_FSMC_SDRAM1 || STM32_SDRAM_USE_FSMC_SDRAM2) && !STM32_HAS_FSMC
+#error "FMC not present in the selected device"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ SDRAM_UNINIT = 0, /**< Not initialized. */
+ SDRAM_STOP = 1, /**< Stopped. */
+ SDRAM_READY = 2, /**< Ready. */
+} sdramstate_t;
+
+/**
+ * @brief Type of a structure representing an SDRAM driver.
+ */
+typedef struct SDRAMDriver SDRAMDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t sdcr;
+ uint32_t sdtr;
+} SDRAMConfig;
+
+/**
+ * @brief Structure representing an SDRAM driver.
+ */
+struct SDRAMDriver {
+ /**
+ * @brief Driver state.
+ */
+ sdramstate_t state;
+ /**
+ * @brief Pointer to the FMC SDRAM registers block.
+ */
+ FSMC_SDRAM_TypeDef *sdram;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SDRAM_USE_FSMC_SDRAM1 && !defined(__DOXYGEN__)
+extern SDRAMDriver SDRAMD1;
+#endif
+
+#if STM32_SDRAM_USE_FSMC_SDRAM2 && !defined(__DOXYGEN__)
+extern SDRAMDriver SDRAMD2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void fsmcSdramInit(void);
+ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp);
+ void fsmcSdramStop(SDRAMDriver *sdramp);
+ void fsmcSdram_WaitReady(void);
+ void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_USE_FSMC_SDRAM */
+
+#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */
+
+#endif /* _FMC_SDRAM_H_ */
+
+/** @} */