summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryuanzihao <[email protected]>2023-08-20 22:06:26 +0800
committerMeco Man <[email protected]>2023-08-20 23:47:59 -0400
commit5b36522b485aa07302851d7ceb9dcfd26cfc0209 (patch)
tree5e91a68b4a7cddafac4ab448a86d037bd99c4dd3
parent348c1fcecdee06a6da23f380e829eba4e3b1dd85 (diff)
[bsp][gd32]添加 立创开发板 GD32F470 的 SDRAM驱动,从STM32的drv_sdram.c修改而来
-rw-r--r--bsp/gd32/arm/gd32470z-lckfb/board/Kconfig5
-rw-r--r--bsp/gd32/arm/gd32470z-lckfb/board/board.c4
-rw-r--r--bsp/gd32/arm/libraries/GD32F4xx_Firmware_Library/SConscript4
-rw-r--r--bsp/gd32/arm/libraries/gd32_drivers/SConscript4
-rw-r--r--bsp/gd32/arm/libraries/gd32_drivers/drv_sdram.c328
-rw-r--r--bsp/gd32/arm/libraries/gd32_drivers/sdram_port.h69
6 files changed, 411 insertions, 3 deletions
diff --git a/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig b/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig
index 2b0c0ce10f..f7c61074aa 100644
--- a/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig
+++ b/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig
@@ -230,6 +230,11 @@ menu "On-chip Peripheral Drivers"
endif
endif
+ config BSP_USING_SDRAM
+ bool "Enable SDRAM"
+ select RT_USING_SDRAM
+ default n
+
source "../libraries/gd32_drivers/Kconfig"
endmenu
diff --git a/bsp/gd32/arm/gd32470z-lckfb/board/board.c b/bsp/gd32/arm/gd32470z-lckfb/board/board.c
index 5f0ce9bc58..49a77b5299 100644
--- a/bsp/gd32/arm/gd32470z-lckfb/board/board.c
+++ b/bsp/gd32/arm/gd32470z-lckfb/board/board.c
@@ -75,9 +75,7 @@ void rt_hw_board_init()
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
-#ifdef BSP_USING_SDRAM
- rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END);
-#else
+#ifdef RT_USING_HEAP
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
}
diff --git a/bsp/gd32/arm/libraries/GD32F4xx_Firmware_Library/SConscript b/bsp/gd32/arm/libraries/GD32F4xx_Firmware_Library/SConscript
index 3e7c854023..5346b953ad 100644
--- a/bsp/gd32/arm/libraries/GD32F4xx_Firmware_Library/SConscript
+++ b/bsp/gd32/arm/libraries/GD32F4xx_Firmware_Library/SConscript
@@ -48,6 +48,10 @@ if GetDepend(['RT_USING_SDIO']):
src += ['GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c']
src += ['GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c']
+if GetDepend(['BSP_USING_SDRAM']):
+ src += ['GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c']
+ src += ['GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c']
+
path = [
cwd + '/CMSIS/GD/GD32F4xx/Include',
cwd + '/CMSIS',
diff --git a/bsp/gd32/arm/libraries/gd32_drivers/SConscript b/bsp/gd32/arm/libraries/gd32_drivers/SConscript
index 5bd27db73e..cb8c24eab5 100644
--- a/bsp/gd32/arm/libraries/gd32_drivers/SConscript
+++ b/bsp/gd32/arm/libraries/gd32_drivers/SConscript
@@ -53,6 +53,10 @@ if GetDepend('RT_USING_SDIO'):
if GetDepend('RT_USING_PWM'):
src += ['drv_pwm.c']
+# add sdram drivers.
+if GetDepend('BSP_USING_SDRAM'):
+ src += ['drv_sdram.c']
+
path = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_sdram.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_sdram.c
new file mode 100644
index 0000000000..469eb579e6
--- /dev/null
+++ b/bsp/gd32/arm/libraries/gd32_drivers/drv_sdram.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-12-04 zylx first version
+ * 2023-08-20 yuanzihao adapter gd32f4xx
+ */
+
+#include <board.h>
+
+#ifdef BSP_USING_SDRAM
+#include <sdram_port.h>
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.sdram"
+#include <drv_log.h>
+
+static exmc_sdram_parameter_struct sdram_init_struct;
+static exmc_sdram_command_parameter_struct sdram_command_init_struct;
+static exmc_sdram_timing_parameter_struct sdram_timing_init_struct;
+#ifdef RT_USING_MEMHEAP_AS_HEAP
+static struct rt_memheap system_heap;
+#endif
+
+
+static void SDRAM_Initialization_GPIO(void)
+{
+ /* enable EXMC clock*/
+ rcu_periph_clock_enable(RCU_EXMC);
+ rcu_periph_clock_enable(RCU_GPIOB);
+ rcu_periph_clock_enable(RCU_GPIOC);
+ rcu_periph_clock_enable(RCU_GPIOD);
+ rcu_periph_clock_enable(RCU_GPIOE);
+ rcu_periph_clock_enable(RCU_GPIOF);
+ rcu_periph_clock_enable(RCU_GPIOG);
+ rcu_periph_clock_enable(RCU_GPIOH);
+
+ /* common GPIO configuration */
+ /* SDNWE(PC0),SDNE0(PC2),SDCKE0(PC3) pin configuration */
+ gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
+ gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
+ gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
+
+ /* D2(PD0),D3(PD1),D13(PD8),D14(PD9),D15(PD10),D0(PD14),D1(PD15) pin configuration */
+ gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
+ GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
+ gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
+ GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
+ gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
+ GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
+
+ /* NBL0(PE0),NBL1(PE1),D4(PE7),D5(PE8),D6(PE9),D7(PE10),D8(PE11),D9(PE12),D10(PE13),D11(PE14),D12(PE15) pin configuration */
+ gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | 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_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | 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_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | 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);
+
+ /* A0(PF0),A1(PF1),A2(PF2),A3(PF3),A4(PF4),A5(PF5),NRAS(PF11),A6(PF12),A7(PF13),A8(PF14),A9(PF15) pin configuration */
+ gpio_af_set(GPIOF, GPIO_AF_12, 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_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLUP, 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_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, 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);
+
+ /* A10(PG0),A11(PG1),A12(PG2),A14(PG4),A15(PG5),SDCLK(PG8),NCAS(PG15) pin configuration */
+ gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 |
+ GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
+ gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 |
+ GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
+ gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 |
+ GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
+
+}
+
+/**
+ * @brief Perform the SDRAM exernal memory inialization sequence
+ * @param hsdram: SDRAM handle
+ * @param Command: Pointer to SDRAM command structure
+ * @retval None
+ */
+static rt_err_t SDRAM_Initialization_Sequence(exmc_sdram_parameter_struct *hsdram, exmc_sdram_command_parameter_struct *Command)
+{
+ __IO uint32_t tmpmrd = 0;
+ uint32_t target_bank = 0;
+ uint32_t sdram_device = EXMC_SDRAM_DEVICE0;
+ uint32_t command_content = 0;
+
+ uint32_t timeout = SDRAM_TIMEOUT;
+
+#if SDRAM_TARGET_BANK == 1
+ target_bank = EXMC_SDRAM_DEVICE0_SELECT;
+#else
+ target_bank = EXMC_SDRAM_DEVICE1_SELECT;
+#endif
+
+ SDRAM_Initialization_GPIO();
+ /* EXMC SDRAM device initialization sequence --------------------------------*/
+ /* Step 1 : configure SDRAM timing registers --------------------------------*/
+ /* LMRD: 2 clock cycles */
+ sdram_timing_init_struct.load_mode_register_delay = LOADTOACTIVEDELAY;
+ /* XSRD: min = 75ns */
+ sdram_timing_init_struct.exit_selfrefresh_delay = EXITSELFREFRESHDELAY;
+ /* RASD: min=44ns , max=120k (ns) */
+ sdram_timing_init_struct.row_address_select_delay = ROWCYCLEDELAY;
+ /* ARFD: min=66ns */
+ sdram_timing_init_struct.auto_refresh_delay = SELFREFRESHTIME;
+ /* WRD: min=1 Clock cycles +7.5ns */
+ sdram_timing_init_struct.write_recovery_delay = WRITERECOVERYTIME;
+ /* RPD: min=20ns */
+ sdram_timing_init_struct.row_precharge_delay = RPDELAY;
+ /* RCD: min=20ns */
+ sdram_timing_init_struct.row_to_column_delay = RCDDELAY;
+
+ /* step 2 : configure SDRAM control registers ---------------------------------*/
+ sdram_init_struct.sdram_device = sdram_device;
+ sdram_init_struct.column_address_width = SDRAM_COLUMN_BITS;
+ sdram_init_struct.row_address_width = SDRAM_ROW_BITS;
+ sdram_init_struct.data_width = SDRAM_DATA_WIDTH;
+ sdram_init_struct.internal_bank_number = EXMC_SDRAM_4_INTER_BANK;
+ sdram_init_struct.cas_latency = SDRAM_CAS_LATENCY;
+ sdram_init_struct.write_protection = DISABLE;
+ sdram_init_struct.sdclock_config = SDCLOCK_PERIOD;
+ sdram_init_struct.burst_read_switch = ENABLE;
+ sdram_init_struct.pipeline_read_delay = SDRAM_RPIPE_DELAY;
+ sdram_init_struct.timing = &sdram_timing_init_struct;
+ /* EXMC SDRAM bank initialization */
+ exmc_sdram_init(&sdram_init_struct);
+
+ /* step 3 : configure CKE high command---------------------------------------*/
+ sdram_command_init_struct.command = EXMC_SDRAM_CLOCK_ENABLE;
+ sdram_command_init_struct.bank_select = target_bank;
+ sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
+ sdram_command_init_struct.mode_register_content = 0;
+ /* wait until the SDRAM controller is ready */
+ while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
+ timeout--;
+ }
+ if(0 == timeout) {
+ return RT_ERROR;
+ }
+ /* send the command */
+ exmc_sdram_command_config(&sdram_command_init_struct);
+
+ /* step 4 : insert 10ms delay----------------------------------------------*/
+// rt_thread_mdelay(10);
+
+ /* step 5 : configure precharge all command----------------------------------*/
+ sdram_command_init_struct.command = EXMC_SDRAM_PRECHARGE_ALL;
+ sdram_command_init_struct.bank_select = target_bank;
+ sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
+ sdram_command_init_struct.mode_register_content = 0;
+ /* wait until the SDRAM controller is ready */
+ timeout = SDRAM_TIMEOUT;
+ while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
+ timeout--;
+ }
+ if(0 == timeout) {
+ return RT_ERROR;
+ }
+ /* send the command */
+ exmc_sdram_command_config(&sdram_command_init_struct);
+
+ /* step 6 : configure Auto-Refresh command-----------------------------------*/
+ sdram_command_init_struct.command = EXMC_SDRAM_AUTO_REFRESH;
+ sdram_command_init_struct.bank_select = target_bank;
+ sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_9_SDCLK;
+ sdram_command_init_struct.mode_register_content = 0;
+ /* wait until the SDRAM controller is ready */
+ timeout = SDRAM_TIMEOUT;
+ while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
+ timeout--;
+ }
+ if(0 == timeout) {
+ return RT_ERROR;
+ }
+ /* send the command */
+ exmc_sdram_command_config(&sdram_command_init_struct);
+
+ /* step 7 : configure load mode register command-----------------------------*/
+ /* program mode register */
+ command_content = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
+ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
+ SDRAM_MODEREG_CAS_LATENCY_3 |
+ SDRAM_MODEREG_OPERATING_MODE_STANDARD |
+ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
+
+ sdram_command_init_struct.command = EXMC_SDRAM_LOAD_MODE_REGISTER;
+ sdram_command_init_struct.bank_select = target_bank;
+ sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
+ sdram_command_init_struct.mode_register_content = command_content;
+
+ /* wait until the SDRAM controller is ready */
+ timeout = SDRAM_TIMEOUT;
+ while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
+ timeout--;
+ }
+ if(0 == timeout) {
+ return RT_ERROR;
+ }
+ /* send the command */
+ exmc_sdram_command_config(&sdram_command_init_struct);
+
+ /* step 8 : set the auto-refresh rate counter--------------------------------*/
+ /* 64ms, 8192-cycle refresh, 64ms/8192=7.81us */
+ /* SDCLK_Freq = SYS_Freq/2 */
+ /* (7.81 us * SDCLK_Freq) - 20 */
+ exmc_sdram_refresh_count_set(761);
+
+ /* wait until the SDRAM controller is ready */
+ timeout = SDRAM_TIMEOUT;
+ while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
+ timeout--;
+ }
+ if(0 == timeout) {
+ return RT_ERROR;
+ }
+ return RT_EOK;
+
+}
+
+static int SDRAM_Init(void)
+{
+ int result = RT_EOK;
+
+ /* Initialize the SDRAM controller */
+ if (SDRAM_Initialization_Sequence(&sdram_init_struct, &sdram_command_init_struct) != RT_EOK)
+ {
+ LOG_E("SDRAM init failed!");
+ result = -RT_ERROR;
+ }
+ else
+ {
+ rt_kprintf("sdram init success, mapped at 0x%X, size is %d bytes, data width is %d", SDRAM_BANK_ADDR, SDRAM_SIZE, SDRAM_DATA_WIDTH);
+#ifdef RT_USING_MEMHEAP_AS_HEAP
+ /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
+ rt_memheap_init(&system_heap, "sdram", (void *)SDRAM_BANK_ADDR, SDRAM_SIZE);
+#endif
+ }
+
+ return result;
+}
+INIT_BOARD_EXPORT(SDRAM_Init);
+
+#ifdef DRV_DEBUG
+#ifdef FINSH_USING_MSH
+int sdram_test(void)
+{
+ int i = 0;
+ uint32_t start_time = 0, time_cast = 0;
+#if SDRAM_DATA_WIDTH_IN_NUMBER == 8
+ char data_width = 1;
+ uint8_t data = 0;
+#elif SDRAM_DATA_WIDTH_IN_NUMBER == 16
+ char data_width = 2;
+ uint16_t data = 0;
+#else
+ char data_width = 4;
+ uint32_t data = 0;
+#endif
+
+ /* write data */
+ LOG_D("Writing the %ld bytes data, waiting....", SDRAM_SIZE);
+ start_time = rt_tick_get();
+ for (i = 0; i < SDRAM_SIZE / data_width; i++)
+ {
+#if SDRAM_DATA_WIDTH_IN_NUMBER == 8
+ *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint8_t)0x55;
+#elif SDRAM_DATA_WIDTH_IN_NUMBER == 16
+ *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
+#else
+ *(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint32_t)0x55555555;
+#endif
+ }
+ time_cast = rt_tick_get() - start_time;
+ LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
+ time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
+
+ /* read data */
+ LOG_D("start Reading and verifying data, waiting....");
+ for (i = 0; i < SDRAM_SIZE / data_width; i++)
+ {
+#if SDRAM_DATA_WIDTH_IN_NUMBER == 8
+ data = *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width);
+ if (data != 0x55)
+ {
+ LOG_E("SDRAM test failed!");
+ break;
+ }
+#elif SDRAM_DATA_WIDTH_IN_NUMBER == 16
+ data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
+ if (data != 0x5555)
+ {
+ LOG_E("SDRAM test failed!");
+ break;
+ }
+#else
+ data = *(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width);
+ if (data != 0x55555555)
+ {
+ LOG_E("SDRAM test failed!");
+ break;
+ }
+#endif
+ }
+
+ if (i >= SDRAM_SIZE / data_width)
+ {
+ LOG_D("SDRAM test success!");
+ }
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(sdram_test, sdram test)
+#endif /* FINSH_USING_MSH */
+#endif /* DRV_DEBUG */
+#endif /* BSP_USING_SDRAM */
diff --git a/bsp/gd32/arm/libraries/gd32_drivers/sdram_port.h b/bsp/gd32/arm/libraries/gd32_drivers/sdram_port.h
new file mode 100644
index 0000000000..d762b0dd9a
--- /dev/null
+++ b/bsp/gd32/arm/libraries/gd32_drivers/sdram_port.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-12-04 zylx The first version for STM32F4xx
+ * 2023-08-20 yuanzihao adapter gd32f4xx
+ */
+
+#ifndef __SDRAM_PORT_H__
+#define __SDRAM_PORT_H__
+
+/* parameters for sdram peripheral */
+#define SDRAM_DEVICE EXMC_SDRAM_DEVICE0
+/* Bank1 or Bank2 */
+#define SDRAM_TARGET_BANK 1
+/* stm32h7 Bank1:0XC0000000 Bank2:0XD0000000 */
+#define SDRAM_BANK_ADDR ((uint32_t)0XC0000000)
+/* data width: 8, 16, 32 */
+#define SDRAM_DATA_WIDTH_IN_NUMBER 16
+#define SDRAM_DATA_WIDTH EXMC_SDRAM_DATABUS_WIDTH_16B
+/* column bit numbers: 8, 9, 10, 11 */
+#define SDRAM_COLUMN_BITS EXMC_SDRAM_COW_ADDRESS_9
+/* row bit numbers: 11, 12, 13 */
+#define SDRAM_ROW_BITS EXMC_SDRAM_ROW_ADDRESS_13
+/* cas latency clock number: 1, 2, 3 */
+#define SDRAM_CAS_LATENCY EXMC_CAS_LATENCY_3_SDCLK
+/* read pipe delay: 0, 1, 2 */
+#define SDRAM_RPIPE_DELAY EXMC_PIPELINE_DELAY_2_HCLK
+/* clock divid: 2, 3 */
+#define SDCLOCK_PERIOD EXMC_SDCLK_PERIODS_3_HCLK
+/* refresh rate counter */
+#define SDRAM_REFRESH_COUNT ((uint32_t)0x02A5)
+#define SDRAM_SIZE ((uint32_t)0x2000000)
+#define SDRAM_TIMEOUT ((uint32_t)0x0000FFFF)
+
+/* Timing configuration for W9825G6KH-6 */
+/* 100 MHz of HCKL3 clock frequency (200MHz/2) */
+/* TMRD: 2 Clock cycles */
+#define LOADTOACTIVEDELAY 2
+/* TXSR: 8x10ns */
+#define EXITSELFREFRESHDELAY 8
+/* TRAS: 5x10ns */
+#define SELFREFRESHTIME 7
+/* TRC: 7x10ns */
+#define ROWCYCLEDELAY 5
+/* TWR: 2 Clock cycles */
+#define WRITERECOVERYTIME 2
+/* TRP: 2x10ns */
+#define RPDELAY 3
+/* TRCD: 2x10ns */
+#define RCDDELAY 3
+
+/* memory mode register */
+#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)
+
+#endif