avr_mdcart_sram_lite

view test.c @ 1:318a758ede82

ops
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 08 Mar 2017 09:05:19 +0200
parents c47d05df0667
children 42d26388b709
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <avr/io.h>
6 #include <avr/interrupt.h>
7 #include "serial.h"
9 /* pin assignments:
10 * A[0,7] data
11 * B[0,7] A0 - A7
12 * C[0,3] A8 - A11
13 * D7 CAS3
14 * D6 RAS2
15 * D5 RAS3
16 */
18 #define CAS3_BIT 0x80
19 #define RAS2_BIT 0x40
20 #define RAS3_BIT 0x20
21 #define WE_BIT 0x04
23 void proc_cmd(char *cmd);
24 void cmd_read(char *buf);
25 void cmd_write(char *buf);
26 void cmd_setcfg(char *buf);
28 void dram_init(void);
29 void dram_detect(void);
30 int memtest(unsigned long addr);
31 void dram_refresh(void);
32 void dram_write(unsigned long addr, unsigned char val);
33 unsigned char dram_read(unsigned long addr);
35 #define MAX_INPUT_SIZE 128
36 static char input[MAX_INPUT_SIZE];
37 static unsigned char inp_cidx;
39 /* SIMM access config */
40 static int addr_bits;
41 static unsigned long addr_mask;
42 static int ras_lines = 1;
43 static long memsize_kb; /* derived from the above */
46 int main(void)
47 {
48 dram_init();
49 init_serial(38400);
50 sei();
52 printf("Detecting memory ...\n");
53 dram_detect();
55 memsize_kb = (1 << (addr_bits * 2)) * 4 * ras_lines;
57 printf("Address lines: %d\n", addr_bits);
58 printf("RAS lines: %d\n", ras_lines);
59 printf("Memory size: %ldmb (%ldkb)\n", memsize_kb >> 10, memsize_kb);
60 fputs("> ", stdout);
62 for(;;) {
63 while(have_input()) {
64 int c = getchar();
65 putchar(c);
67 if(c == '\r' || c == '\n') {
68 input[inp_cidx] = 0;
69 proc_cmd(input);
70 inp_cidx = 0;
72 fputs("> ", stdout);
73 } else if(inp_cidx < sizeof input - 1) {
74 input[inp_cidx++] = c;
75 }
76 }
78 dram_refresh();
79 }
80 return 0;
81 }
83 void proc_cmd(char *cmd)
84 {
85 switch(cmd[0]) {
86 case 'w':
87 cmd_write(cmd + 1);
88 break;
90 case 'r':
91 cmd_read(cmd + 1);
92 break;
94 case 's':
95 cmd_setcfg(cmd + 1);
96 break;
98 case 'h':
99 printf("commands:\n");
100 printf(" w <addr> <value> - write byte to address\n");
101 printf(" r <addr> - read byte from address\n");
102 printf(" s <addr_bits|ras_lines> <value>\n");
103 printf(" h - help\n");
104 break;
105 }
106 }
108 void cmd_read(char *buf)
109 {
110 char *endp;
111 unsigned long addr;
112 unsigned char data;
114 addr = strtol(buf, &endp, 0);
115 if(endp == buf) {
116 fprintf(stderr, "invalid argument to write command: %s\n", buf);
117 return;
118 }
119 buf = endp;
121 data = dram_read(addr);
122 printf("%04lx: %02x (%u)\n", addr, (unsigned int)data, (unsigned int)data);
123 }
125 void cmd_write(char *buf)
126 {
127 char *endp;
128 unsigned long addr;
129 unsigned char data;
131 addr = strtol(buf, &endp, 0);
132 if(endp == buf) {
133 fprintf(stderr, "invalid address argument to read command: %s\n", buf);
134 return;
135 }
136 buf = endp;
138 data = strtol(buf, &endp, 0);
139 if(endp == buf) {
140 fprintf(stderr, "invalid data argument to read command: %s\n", buf);
141 return;
142 }
143 buf = endp;
145 dram_write(addr, data);
146 printf("%04lx: %02x (%u)\n", addr, (unsigned int)data, (unsigned int)data);
147 }
149 void cmd_setcfg(char *buf)
150 {
151 char *endp;
152 char *name, *valstr;
153 long value;
155 name = buf;
156 while(*name && isspace(*name)) ++name;
157 if(!*name) {
158 fprintf(stderr, "invalid or missing variable name\n");
159 return;
160 }
161 endp = name;
162 while(*endp && !isspace(*endp)) ++endp;
163 *endp = 0;
165 valstr = endp + 1;
166 value = strtol(valstr, &endp, 0);
167 if(endp == valstr) {
168 fprintf(stderr, "invalid or missing variable value: %s\n", valstr);
169 return;
170 }
172 if(strcmp(name, "addr_bits") == 0) {
173 if(value > 0 && value <= 12) {
174 addr_bits = value;
175 printf("Address bits: %ld\n", value);
176 } else {
177 fprintf(stderr, "invalid address bits value: %ld\n", value);
178 }
179 } else if(strcmp(name, "ras_lines") == 0) {
180 if(value > 0 && value <= 2) {
181 ras_lines = value;
182 printf("RAS lines: %d\n", ras_lines);
183 } else {
184 fprintf(stderr, "invalid RAS lines value: %ld\n", value);
185 }
186 } else {
187 fprintf(stderr, "unknown variable: %s\n", name);
188 }
189 }
191 void dram_set_data(unsigned char val)
192 {
193 DDRA = 0xff;
194 PORTA = val;
195 }
197 void dram_release_data(void)
198 {
199 DDRA = 0;
200 PORTA = 0;
201 }
203 void dram_set_addr(unsigned long addr)
204 {
205 PORTB = addr & 0xff;
206 PORTC = (addr >> 8) & 3;
207 }
209 void dram_assert_cas(void)
210 {
211 PORTD &= ~CAS3_BIT;
212 }
214 void dram_release_cas(void)
215 {
216 PORTD |= CAS3_BIT;
217 }
219 void dram_assert_ras(unsigned char bits)
220 {
221 PORTD &= ~bits;
222 }
224 void dram_release_ras(unsigned char bits)
225 {
226 PORTD |= bits;
227 }
229 void dram_set_we(void)
230 {
231 PORTD &= ~WE_BIT;
232 }
234 void dram_clear_we(void)
235 {
236 PORTD |= WE_BIT;
237 }
239 void dram_init(void)
240 {
241 DDRA = 0; /* port A is the data bus */
242 PORTA = 0; /* no pullups when A is input */
243 DDRB = 0xff; /* port B is A0-A7 */
244 DDRC = 0xff; /* port C (low nibble) is A8-A11 */
245 DDRD = 0xff; /* port D are the control lines CAS/RAS/WR */
247 PORTD = 0xff; /* deassert all control signals */
248 }
250 void dram_detect(void)
251 {
252 /* detect how many address bits we've got */
253 addr_bits = 12;
254 while(addr_bits > 8) {
255 printf("addr mask: %lu\n", (unsigned long)((1 << (unsigned long)addr_bits) - 1));
256 addr_mask = (1 << (unsigned long)addr_bits) - 1;
257 if(memtest((1 << ((unsigned long)addr_bits * 2)) - 1) == 0) {
258 break;
259 }
260 --addr_bits;
261 }
262 if(addr_bits < 1) {
263 fprintf(stderr, "Failed to detect DRAM configuration (address lines)...\n");
264 return;
265 }
266 }
268 int memtest(unsigned long addr)
269 {
270 int i;
271 unsigned char pat[] = { 0xf0, 0x0f, 0xaa, 0x55, 0xc0, 0x30, 0x0c, 0x03 };
272 unsigned char val;
274 printf("testing address: %lx (a:%d,r:%d)\n", addr, addr_bits, ras_lines);
276 for(i=0; i<sizeof pat / sizeof *pat; i++) {
277 dram_write(addr, pat[i]);
278 if((val = dram_read(addr)) != pat[i]) {
279 printf("pattern %x failed, got: %x\n", (int)pat[i], val);
280 return -1;
281 }
282 }
283 return 0;
284 }
286 void dram_refresh(void)
287 {
288 dram_assert_cas();
289 dram_assert_ras(RAS2_BIT | RAS3_BIT);
290 dram_release_cas();
291 dram_release_ras(RAS2_BIT | RAS3_BIT);
292 }
294 void dram_write(unsigned long addr, unsigned char val)
295 {
296 dram_set_data(val);
297 dram_set_we();
298 /* set row address */
299 dram_set_addr((addr >> addr_bits) & addr_mask);
300 dram_assert_ras(RAS2_BIT);
301 /* set column address */
302 dram_set_addr(addr & addr_mask);
303 dram_assert_cas();
304 dram_release_ras(RAS2_BIT);
305 dram_release_cas();
306 dram_release_data();
307 dram_clear_we();
308 }
310 unsigned char dram_read(unsigned long addr)
311 {
312 unsigned char val;
314 dram_clear_we();
315 dram_release_data();
317 /* set row address */
318 dram_set_addr((addr >> addr_bits) & addr_mask);
319 dram_assert_ras(RAS2_BIT);
320 /* set column address */
321 dram_set_addr(addr & addr_mask);
322 dram_assert_cas();
324 val = PINA;
326 dram_release_ras(RAS2_BIT);
327 dram_release_cas();
329 return val;
330 }