1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-05-16 shelton first version
9 */
10
11 #include "drv_common.h"
12
13 #ifdef BSP_USING_SDRAM
14 #include "drv_sdram.h"
15
16 #define DRV_DEBUG
17 #define LOG_TAG "drv.sdram"
18 #include <drv_log.h>
19
20 #ifdef RT_USING_MEMHEAP_AS_HEAP
21 static struct rt_memheap system_heap;
22 #endif
23
sdram_init_sequence(xmc_cmd_bank1_2_type cmd_bank)24 static void sdram_init_sequence(xmc_cmd_bank1_2_type cmd_bank)
25 {
26 xmc_sdram_cmd_type sdram_cmd_struct;
27 uint32_t timeout = 0xffff, delay = 0;
28
29 sdram_cmd_struct.cmd = XMC_CMD_CLK;
30 sdram_cmd_struct.auto_refresh = 1;
31 sdram_cmd_struct.cmd_banks = cmd_bank;
32 sdram_cmd_struct.data = 0;
33 xmc_sdram_cmd(&sdram_cmd_struct);
34
35 while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
36 {
37 timeout --;
38 }
39
40 /* insert 100 ms delay */
41 for (delay = 0; delay < 0xffff; delay ++)
42 ;
43
44 sdram_cmd_struct.cmd = XMC_CMD_PRECHARG_ALL;
45 sdram_cmd_struct.auto_refresh = 1;
46 sdram_cmd_struct.cmd_banks = cmd_bank;
47 sdram_cmd_struct.data = 0;
48 xmc_sdram_cmd(&sdram_cmd_struct);
49
50 timeout = 0xffff;
51 while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
52 {
53 timeout --;
54 }
55
56 /* set refresh rate */
57 xmc_sdram_refresh_counter_set(SDRAM_REFRESH_COUNT);
58
59 sdram_cmd_struct.cmd = XMC_CMD_AUTO_REFRESH;
60 sdram_cmd_struct.auto_refresh = 8;
61 sdram_cmd_struct.cmd_banks = cmd_bank;
62 sdram_cmd_struct.data = 0;
63 xmc_sdram_cmd(&sdram_cmd_struct);
64
65 timeout = 0xffff;
66 while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
67 {
68 timeout --;
69 }
70
71 sdram_cmd_struct.cmd = XMC_CMD_LOAD_MODE;
72 sdram_cmd_struct.auto_refresh = 1;
73 sdram_cmd_struct.cmd_banks = cmd_bank;
74
75 #if SDRAM_DATA_WIDTH == 8
76 sdram_cmd_struct.data = (uint32_t)SDRAM_BURST_LEN_1 |
77 #elif SDRAM_DATA_WIDTH == 16
78 sdram_cmd_struct.data = (uint32_t)SDRAM_BURST_LEN_2 |
79 #endif
80 SDRAM_BURST_SEQUENTIAL |
81 #if SDRAM_CAS_LATENCY == 3
82 SDRAM_CAS_LATENCY_3 |
83 #else
84 SDRAM_CAS_LATENCY_2 |
85 #endif
86 SDRAM_OPERATING_MODE_STANDARD |
87 SDRAM_WR_BURST_SINGLE;
88
89 xmc_sdram_cmd(&sdram_cmd_struct);
90
91 timeout = 0xffff;
92 while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
93 {
94 timeout --;
95 }
96 }
97
sdram_init(void)98 static int sdram_init(void)
99 {
100 int result = RT_EOK;
101 xmc_cmd_bank1_2_type target_bank = XMC_CMD_BANK1;
102
103 xmc_sdram_init_type sdram_init_struct;
104 xmc_sdram_timing_type sdram_timing_struct;
105
106 at32_msp_sdram_init(NULL);
107
108 /* xmc configuration */
109 xmc_sdram_default_para_init(&sdram_init_struct, &sdram_timing_struct);
110
111 #if SDRAM_TARGET_BANK == 1
112 sdram_init_struct.sdram_bank = XMC_SDRAM_BANK1;
113 #else
114 sdram_init_struct.sdram_bank = XMC_SDRAM_BANK2;
115 #endif
116 #if SDRAM_COLUMN_BITS == 8
117 sdram_init_struct.column_address = XMC_COLUMN_8;
118 #elif SDRAM_COLUMN_BITS == 9
119 sdram_init_struct.column_address = XMC_COLUMN_9;
120 #elif SDRAM_COLUMN_BITS == 10
121 sdram_init_struct.column_address = XMC_COLUMN_10;
122 #else
123 sdram_init_struct.column_address = XMC_COLUMN_11;
124 #endif
125 #if SDRAM_ROW_BITS == 11
126 sdram_init_struct.row_address = XMC_ROW_11;
127 #elif SDRAM_ROW_BITS == 12
128 sdram_init_struct.row_address = XMC_ROW_12;
129 #else
130 sdram_init_struct.row_address = XMC_ROW_13;
131 #endif
132 #if SDRAM_DATA_WIDTH == 8
133 sdram_init_struct.width = XMC_MEM_WIDTH_8;
134 #elif SDRAM_DATA_WIDTH == 16
135 sdram_init_struct.width = XMC_MEM_WIDTH_16;
136 #endif
137
138 sdram_init_struct.internel_banks = XMC_INBK_4;
139
140 #if SDRAM_CAS_LATENCY == 1
141 sdram_init_struct.cas = XMC_CAS_1;
142 #elif SDRAM_CAS_LATENCY == 2
143 sdram_init_struct.cas = XMC_CAS_2;
144 #else
145 sdram_init_struct.cas = XMC_CAS_3;
146 #endif
147 #if SDRAM_RPIPE_DELAY == 0
148 sdram_init_struct.read_delay = XMC_READ_DELAY_0;
149 #elif SDRAM_RPIPE_DELAY == 1
150 sdram_init_struct.read_delay = XMC_READ_DELAY_1;
151 #else
152 sdram_init_struct.read_delay = XMC_READ_DELAY_2;
153 #endif
154 #if SDCLOCK_PERIOD == 2
155 sdram_init_struct.clkdiv = XMC_CLKDIV_2;
156 #else
157 sdram_init_struct.clkdiv = XMC_CLKDIV_3;
158 #endif
159
160 sdram_init_struct.write_protection = FALSE;
161 sdram_init_struct.burst_read = TRUE;
162
163 sdram_timing_struct.tmrd = LOADTOACTIVEDELAY;
164 sdram_timing_struct.txsr = EXITSELFREFRESHDELAY;
165 sdram_timing_struct.tras = SELFREFRESHTIME;
166 sdram_timing_struct.trc = ROWCYCLEDELAY;
167 sdram_timing_struct.twr = WRITERECOVERYTIME;
168 sdram_timing_struct.trp = RPDELAY;
169 sdram_timing_struct.trcd = RCDDELAY;
170
171 xmc_sdram_init(&sdram_init_struct, &sdram_timing_struct);
172
173 #if SDRAM_TARGET_BANK == 1
174 target_bank = XMC_CMD_BANK1;
175 #else
176 target_bank = XMC_CMD_BANK2;
177 #endif
178
179 sdram_init_sequence(target_bank);
180
181 #ifdef RT_USING_MEMHEAP_AS_HEAP
182 /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
183 rt_memheap_init(&system_heap, "sdram", (void *)SDRAM_BANK_ADDR, SDRAM_SIZE);
184 #endif
185
186 return result;
187 }
188
189 INIT_BOARD_EXPORT(sdram_init);
190
191 #ifdef DRV_DEBUG
192 #ifdef FINSH_USING_MSH
sdram_sample(void)193 int sdram_sample(void)
194 {
195 int i = 0;
196 uint32_t start_time = 0, time_cast = 0;
197 #if SDRAM_DATA_WIDTH == 8
198 char data_width = 1;
199 uint8_t data = 0;
200 #elif SDRAM_DATA_WIDTH == 16
201 char data_width = 2;
202 uint16_t data = 0;
203 #else
204 char data_width = 4;
205 uint32_t data = 0;
206 #endif
207
208 /* write data */
209 LOG_D("writing the %ld bytes data, waiting....", SDRAM_SIZE);
210 start_time = rt_tick_get();
211 for (i = 0; i < SDRAM_SIZE / data_width; i++)
212 {
213 #if SDRAM_DATA_WIDTH == 8
214 *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint8_t)(i % 100);
215 #elif SDRAM_DATA_WIDTH == 16
216 *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)(i % 1000);
217 #endif
218 }
219 time_cast = rt_tick_get() - start_time;
220 LOG_D("write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
221 time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
222
223 /* read data */
224 LOG_D("start reading and verifying data, waiting....");
225 for (i = 0; i < SDRAM_SIZE / data_width; i++)
226 {
227 #if SDRAM_DATA_WIDTH == 8
228 data = *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width);
229 if (data != i % 100)
230 {
231 LOG_E("sdram test failed!");
232 break;
233 }
234 #elif SDRAM_DATA_WIDTH == 16
235 data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
236 if (data != (uint16_t)(i % 1000))
237 {
238 LOG_E("sdram test failed, i = %d!", i);
239 break;
240 }
241 #endif
242 }
243
244 if (i >= SDRAM_SIZE / data_width)
245 {
246 LOG_D("sdram test success!");
247 }
248
249 return RT_EOK;
250 }
251
252 MSH_CMD_EXPORT(sdram_sample, sdram sample test)
253
254 #endif /* FINSH_USING_MSH */
255 #endif /* DRV_DEBUG */
256 #endif /* BSP_USING_SDRAM */
257