35e6b46a3a8fddf434582135c6b03700988d84c2
[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 0xb20, 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 0x320, 0x6, 0x200, 0x0
135 },
136 .rdly_p0 = 2,
137 .rdly_p1 = 2,
138 };
139 #endif
140 struct gramProfile profile2;
141
142 if (argc < 3) {
143 fprintf(stderr, "Usage: %s port baudrate\n", argv[0]);
144 return EXIT_FAILURE;
145 }
146
147 sscanf(argv[2], "%d", &baudrate);
148 if (baudrate <= 0) {
149 fprintf(stderr, "%d is not a valid baudrate\n", baudrate);
150 }
151
152 printf("Port: %s, baudrate: %d\n", argv[1], baudrate);
153
154 serial_port = serial_setup(argv[1], baudrate);
155 ctx.user_data = &serial_port;
156
157 printf("gram init... ");
158 gram_init(&ctx, &profile, (void*)ddr_base, (void*)0x00009000, (void*)0x00008000);
159 printf("done\n");
160
161 #if 0
162 printf("Rdly\np0: ");
163 for (size_t i = 0; i < 8; i++) {
164 profile2.rdly_p0 = i;
165 gram_load_calibration(&ctx, &profile2);
166 gram_reset_burstdet(&ctx);
167 for (size_t j = 0; j < 128; j++) {
168 tmp = gram_read(&ctx, ddr_base+4*j);
169 }
170 if (gram_read_burstdet(&ctx, 0)) {
171 printf("1");
172 } else {
173 printf("0");
174 }
175 fflush(stdout);
176 }
177 printf("\n");
178
179 printf("Rdly\np1: ");
180 for (size_t i = 0; i < 8; i++) {
181 profile2.rdly_p1 = i;
182 gram_load_calibration(&ctx, &profile2);
183 gram_reset_burstdet(&ctx);
184 for (size_t j = 0; j < 128; j++) {
185 tmp = gram_read(&ctx, ddr_base+4*j);
186 }
187 if (gram_read_burstdet(&ctx, 1)) {
188 printf("1");
189 } else {
190 printf("0");
191 }
192 fflush(stdout);
193 }
194 printf("\n");
195
196 printf("Auto calibrating... ");
197 res = gram_generate_calibration(&ctx, &profile2);
198 if (res != GRAM_ERR_NONE) {
199 printf("failed\n");
200 gram_load_calibration(&ctx, &profile);
201 } else {
202 gram_load_calibration(&ctx, &profile2);
203 }
204 printf("done\n");
205
206 printf("Auto calibration profile:\n");
207 printf("\tp0 rdly: %d\n", profile2.rdly_p0);
208 printf("\tp1 rdly: %d\n", profile2.rdly_p1);
209
210 gram_reset_burstdet(&ctx);
211 #endif
212
213 srand(time(NULL));
214 for (i = 0; i < kPatternSize; i++) {
215 pattern[i] = rand();
216 }
217
218 printf("memtest... \n");
219
220 printf("Writing data sequence...");
221 for (i = 0; i < kPatternSize; i++) {
222 gram_write(&ctx, ddr_base+4*i, pattern[i]);
223 }
224 printf("done\n");
225
226 if (argc >= 4) {
227 sscanf(argv[3], "%d", &delay);
228 printf("waiting for %d second(s)...", delay);
229 fflush(stdout);
230 sleep(delay);
231 printf("done\n");
232 }
233
234 printf("Dumping data sequence...\n");
235 for (i = 0; i < kPatternSize; i++) {
236 if ((i % kDumpWidth) == 0) {
237 printf("%08x | ", ddr_base+4*i);
238 }
239
240 expected_value = pattern[i];
241
242 for (int j = 3; j >= 0; j--) {
243 printf("%02x", ((uint8_t*)(&expected_value))[j]);
244 }
245
246 if ((i % kDumpWidth) == kDumpWidth-1) {
247 printf("\n");
248 } else {
249 printf(" ");
250 }
251 }
252 printf("\n");
253
254 printf("Reading data sequence...\n");
255 for (i = 0; i < kPatternSize; i++) {
256 if ((i % kDumpWidth) == 0) {
257 printf("%08x | ", ddr_base+4*i);
258 }
259
260 read_value = gram_read(&ctx, ddr_base+4*i);
261 expected_value = pattern[i];
262
263 for (int j = 3; j >= 0; j--) {
264 if (((uint8_t*)(&read_value))[j] != ((uint8_t*)(&expected_value))[j]) {
265 printf("\033[0;31m%02x\033[0m", ((uint8_t*)(&read_value))[j]);
266 miss++;
267 } else {
268 printf("\033[0;32m%02x\033[0m", ((uint8_t*)(&read_value))[j]);
269 }
270 }
271
272 if ((i % kDumpWidth) == kDumpWidth-1) {
273 printf("\n");
274 } else {
275 printf(" ");
276 }
277 }
278
279 printf("Burstdet %d-%d\n", gram_read_burstdet(&ctx, 0), gram_read_burstdet(&ctx, 1));
280
281 printf("Memtest miss score (lowest is better): %d/100\n", (miss/4)*100/kPatternSize);
282
283 close(serial_port);
284
285 return EXIT_SUCCESS;
286 }