Working at 50MHz system clock
[gram.git] / examples / headless / main.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <time.h>
6
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <termios.h>
10 #include <unistd.h>
11
12 #include <netinet/in.h>
13
14 #include <gram.h>
15
16 uint32_t gram_read(struct gramCtx *ctx, void *addr) {
17 uint8_t commands[6] = { 0x02, 0x01 };
18 uint32_t reply;
19 int received, sent, fd;
20
21 fd = *(int*)(ctx->user_data);
22
23 *(uint32_t*)(&commands[2]) = htonl((uint32_t)addr >> 2);
24
25 sent = write(fd, commands, sizeof(commands));
26 if (sent != sizeof(commands)) {
27 fprintf(stderr, "gram_read error (sent bytes length mismatch)\n");
28 }
29 received = read(fd, &reply, sizeof(reply));
30 if (received != sizeof(reply)) {
31 fprintf(stderr, "gram_read error (read bytes length mismatch: %d != %d)\n", received, sizeof(reply));
32 }
33
34 //printf("gram_read: 0x%08x: 0x%08x\n", addr, ntohl(reply));
35
36 return ntohl(reply);
37 }
38
39 int gram_write(struct gramCtx *ctx, void *addr, uint32_t value) {
40 uint8_t commands[10] = { 0x01, 0x01 };
41 int sent;
42
43 *(uint32_t*)(commands+2) = htonl((uint32_t)addr >> 2);
44 *(uint32_t*)(commands+6) = htonl(value);
45
46 //printf("gram_write: 0x%08x: 0x%08x\n", addr, value);
47
48 sent = write(*(int*)(ctx->user_data), commands, sizeof(commands));
49 if (sent != sizeof(commands)) {
50 fprintf(stderr, "gram_write error (sent bytes length mismatch)\n");
51 return -1;
52 }
53
54 return 0;
55 }
56
57 int serial_setup(const char *devname, int baudrate) {
58 struct termios tty;
59 int serialfd;
60
61 serialfd = open("/dev/ttyUSB1", O_RDWR|O_NOCTTY);
62 if (serialfd < 0) {
63 fprintf(stderr, "Error %i from open: %s\n", errno, strerror(errno));
64 }
65
66 memset(&tty, 0, sizeof(tty));
67 if (tcgetattr(serialfd, &tty) != 0) {
68 fprintf(stderr, "Error %i from tcgetattr: %s\n", errno, strerror(errno));
69 }
70
71 /* Parameters from flterm */
72 tcgetattr(serialfd, &tty);
73 tty.c_cflag = B115200;
74 tty.c_cflag |= CS8;
75 tty.c_cflag |= CREAD;
76 tty.c_iflag = IGNPAR | IGNBRK;
77 tty.c_cflag |= CLOCAL;
78 tty.c_oflag = 0;
79 tty.c_lflag = 0;
80 tty.c_cc[VTIME] = 0;
81 tty.c_cc[VMIN] = 1;
82 tcsetattr(serialfd, TCSANOW, &tty);
83 tcflush(serialfd, TCOFLUSH);
84 tcflush(serialfd, TCIFLUSH);
85
86 cfsetispeed(&tty, B115200);
87 cfsetospeed(&tty, B115200);
88
89 cfmakeraw(&tty);
90
91 tcflush(serialfd, TCIFLUSH );
92 if (tcsetattr(serialfd, TCSANOW, &tty) != 0) {
93 fprintf(stderr, "Error %i from tcsetattr: %s\n", errno, strerror(errno));
94 }
95
96 return serialfd;
97 }
98
99 int main(int argc, char *argv[]) {
100 struct gramCtx ctx;
101 int serial_port, baudrate = 0;
102 uint32_t read_value, expected_value;
103 const size_t kPatternSize = 512;
104 uint32_t pattern[kPatternSize];
105 const int kDumpWidth = 8;
106 size_t i;
107 int res;
108 uint32_t tmp;
109 int delay, miss = 0;
110
111 uint32_t ddr_base = 0x10000000;
112
113 #if 0
114 struct gramProfile profile = {
115 .mode_registers = {
116 0xb30, 0x806, 0x200, 0x0
117 },
118 .rdly_p0 = 2,
119 .rdly_p1 = 2,
120 };
121 #endif
122 #if 0
123 struct gramProfile profile = {
124 .mode_registers = {
125 0xb30, 0x806, 0x200, 0x0
126 },
127 .rdly_p0 = 2,
128 .rdly_p1 = 2,
129 };
130 #endif
131 #if 1
132 struct gramProfile profile = {
133 .mode_registers = {
134 0xb20, 0x806, 0x200, 0x0
135 },
136 .rdly_p0 = 2,
137 .rdly_p1 = 2,
138 };
139 #endif
140 #if 0
141 struct gramProfile profile = {
142 .mode_registers = {
143 0x320, 0x6, 0x200, 0x0
144 },
145 .rdly_p0 = 2,
146 .rdly_p1 = 2,
147 };
148 #endif
149 struct gramProfile profile2;
150
151 if (argc < 3) {
152 fprintf(stderr, "Usage: %s port baudrate\n", argv[0]);
153 return EXIT_FAILURE;
154 }
155
156 sscanf(argv[2], "%d", &baudrate);
157 if (baudrate <= 0) {
158 fprintf(stderr, "%d is not a valid baudrate\n", baudrate);
159 }
160
161 printf("Port: %s, baudrate: %d\n", argv[1], baudrate);
162
163 serial_port = serial_setup(argv[1], baudrate);
164 ctx.user_data = &serial_port;
165
166 printf("gram init... ");
167 gram_init(&ctx, &profile, (void*)ddr_base, (void*)0x00009000, (void*)0x00008000);
168 printf("done\n");
169
170 #if 0
171 printf("Rdly\np0: ");
172 for (size_t i = 0; i < 8; i++) {
173 profile2.rdly_p0 = i;
174 gram_load_calibration(&ctx, &profile2);
175 gram_reset_burstdet(&ctx);
176 for (size_t j = 0; j < 128; j++) {
177 tmp = gram_read(&ctx, ddr_base+4*j);
178 }
179 if (gram_read_burstdet(&ctx, 0)) {
180 printf("1");
181 } else {
182 printf("0");
183 }
184 fflush(stdout);
185 }
186 printf("\n");
187
188 printf("Rdly\np1: ");
189 for (size_t i = 0; i < 8; i++) {
190 profile2.rdly_p1 = i;
191 gram_load_calibration(&ctx, &profile2);
192 gram_reset_burstdet(&ctx);
193 for (size_t j = 0; j < 128; j++) {
194 tmp = gram_read(&ctx, ddr_base+4*j);
195 }
196 if (gram_read_burstdet(&ctx, 1)) {
197 printf("1");
198 } else {
199 printf("0");
200 }
201 fflush(stdout);
202 }
203 printf("\n");
204
205 printf("Auto calibrating... ");
206 res = gram_generate_calibration(&ctx, &profile2);
207 if (res != GRAM_ERR_NONE) {
208 printf("failed\n");
209 gram_load_calibration(&ctx, &profile);
210 } else {
211 gram_load_calibration(&ctx, &profile2);
212 }
213 printf("done\n");
214
215 printf("Auto calibration profile:\n");
216 printf("\tp0 rdly: %d\n", profile2.rdly_p0);
217 printf("\tp1 rdly: %d\n", profile2.rdly_p1);
218
219 gram_reset_burstdet(&ctx);
220 #endif
221
222 srand(time(NULL));
223 for (i = 0; i < kPatternSize; i++) {
224 pattern[i] = rand();
225 }
226
227 printf("memtest... \n");
228
229 printf("Writing data sequence...");
230 for (i = 0; i < kPatternSize; i++) {
231 gram_write(&ctx, ddr_base+4*i, pattern[i]);
232 }
233 printf("done\n");
234
235 if (argc >= 4) {
236 sscanf(argv[3], "%d", &delay);
237 printf("waiting for %d second(s)...", delay);
238 fflush(stdout);
239 sleep(delay);
240 printf("done\n");
241 }
242
243 printf("Dumping data sequence...\n");
244 for (i = 0; i < kPatternSize; i++) {
245 if ((i % kDumpWidth) == 0) {
246 printf("%08x | ", ddr_base+4*i);
247 }
248
249 expected_value = pattern[i];
250
251 for (int j = 3; j >= 0; j--) {
252 printf("%02x", ((uint8_t*)(&expected_value))[j]);
253 }
254
255 if ((i % kDumpWidth) == kDumpWidth-1) {
256 printf("\n");
257 } else {
258 printf(" ");
259 }
260 }
261 printf("\n");
262
263 printf("Reading data sequence...\n");
264 for (i = 0; i < kPatternSize; i++) {
265 if ((i % kDumpWidth) == 0) {
266 printf("%08x | ", ddr_base+4*i);
267 }
268
269 read_value = gram_read(&ctx, ddr_base+4*i);
270 expected_value = pattern[i];
271
272 for (int j = 3; j >= 0; j--) {
273 if (((uint8_t*)(&read_value))[j] != ((uint8_t*)(&expected_value))[j]) {
274 printf("\033[0;31m%02x\033[0m", ((uint8_t*)(&read_value))[j]);
275 miss++;
276 } else {
277 printf("\033[0;32m%02x\033[0m", ((uint8_t*)(&read_value))[j]);
278 }
279 }
280
281 if ((i % kDumpWidth) == kDumpWidth-1) {
282 printf("\n");
283 } else {
284 printf(" ");
285 }
286 }
287
288 printf("Burstdet %d-%d\n", gram_read_burstdet(&ctx, 0), gram_read_burstdet(&ctx, 1));
289
290 printf("Memtest miss score (lowest is better): %d/100\n", (miss/4)*100/kPatternSize);
291
292 close(serial_port);
293
294 return EXIT_SUCCESS;
295 }