Reformat new eeprom code to match libftdi style:
[libftdi] / examples / stream_test.c
CommitLineData
40da63b1
UB
1/* stream_test.c
2 *
3 * Test reading from FT2232H in synchronous FIFO mode.
4 *
5 * The FT2232H must supply data due to an appropriate circuit
6 *
7 * To check for skipped block with appended code,
8 * a structure as follows is assumed
9 * 1* uint32_t num (incremented in 0x4000 steps)
10 * 3* uint32_t dont_care
11 *
12 * After start, data will be read in streaming until the program is aborted
13 * Progess information wil be printed out
14 * If a filename is given on the command line, the data read will be
15 * written to that file
16 *
17 */
18#include <stdio.h>
19#include <stdlib.h>
20#include <stdint.h>
21#include <string.h>
22#include <unistd.h>
23#include <getopt.h>
24#include <signal.h>
25#include <errno.h>
26#include <ftdi.h>
27void check_outfile(char *);
28
29static FILE *outputFile;
30
31static int check = 1;
32static int exitRequested = 0;
33/*
34 * sigintHandler --
35 *
36 * SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
37 */
38
39static void
40sigintHandler(int signum)
41{
42 exitRequested = 1;
43}
44
45static void
46usage(const char *argv0)
47{
48 fprintf(stderr,
36335b92 49 "Usage: %s [options...] \n"
40da63b1 50 "Test streaming read from FT2232H\n"
36335b92
UB
51 "[-P string] only look for product with given string\n"
52 "[-n] don't check for special block structure\n"
40da63b1
UB
53 "\n"
54 "If some filename is given, write data read to that file\n"
55 "Progess information is printed each second\n"
56 "Abort with ^C\n"
57 "\n"
58 "Options:\n"
59 "\n"
36335b92 60 "Copyright (C) 2009 Micah Dowty <micah@navi.cx>\n"
40da63b1
UB
61 "Adapted for use with libftdi (C) 2010 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>\n",
62 argv0);
63 exit(1);
64}
65
66static uint32_t start = 0;
67static uint32_t offset = 0;
705f012d 68static uint64_t blocks = 0;
40da63b1
UB
69static uint32_t skips = 0;
70static uint32_t n_err = 0;
71static int
72readCallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata)
73{
74 if (length)
75 {
76 if (check)
77 {
78 int i,rem;
79 uint32_t num;
80 for (i= offset; i<length-16; i+=16)
81 {
82 num = *(uint32_t*) (buffer+i);
83 if (start && (num != start +0x4000))
84 {
85 uint32_t delta = ((num-start)/0x4000)-1;
ededbc1c
UB
86 fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu\n",
87 delta, start -0x4000, num, (unsigned long long)blocks);
40da63b1
UB
88 n_err++;
89 skips += delta;
90 }
91 blocks ++;
92 start = num;
93 }
94 rem = length -i;
95 if (rem >3)
96 {
97 num = *(uint32_t*) (buffer+i);
98 if (start && (num != start +0x4000))
99 {
100 uint32_t delta = ((num-start)/0x4000)-1;
ededbc1c
UB
101 fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu\n",
102 delta, start -0x4000, num, (unsigned long long) blocks);
40da63b1
UB
103 n_err++;
104 skips += delta;
105 }
106 start = num;
107 }
108 else if (rem)
109 start += 0x4000;
110 if (rem != 0);
111 {
112 blocks ++;
113 offset = 16-rem;
114 }
115 }
116 if (outputFile)
117 {
118 if (fwrite(buffer, length, 1, outputFile) != 1)
119 {
120 perror("Write error");
121 return 1;
122 }
123 }
124 }
125 if (progress)
126 {
705f012d 127 fprintf(stderr, "%10.02fs total time %9.3f MiB captured %7.1f kB/s curr rate %7.1f kB/s totalrate %d dropouts\n",
40da63b1
UB
128 progress->totalTime,
129 progress->current.totalBytes / (1024.0 * 1024.0),
130 progress->currentRate / 1024.0,
705f012d
UB
131 progress->totalRate / 1024.0,
132 n_err);
40da63b1
UB
133 }
134 return exitRequested ? 1 : 0;
135}
136
137int main(int argc, char **argv)
138{
139 struct ftdi_context ftdic;
140 int err, c;
141 FILE *of = NULL;
142 char const *outfile = 0;
143 outputFile =0;
144 exitRequested = 0;
145 char *descstring = NULL;
146 int option_index;
147 static struct option long_options[] = {{NULL},};
148
149 while ((c = getopt_long(argc, argv, "P:n", long_options, &option_index)) !=- 1)
150 switch (c)
151 {
152 case -1:
153 break;
154 case 'P':
155 descstring = optarg;
156 break;
157 case 'n':
158 check = 0;
159 break;
160 default:
161 usage(argv[0]);
162 }
163
164 if (optind == argc - 1)
165 {
166 // Exactly one extra argument- a dump file
167 outfile = argv[optind];
168 }
169 else if (optind < argc)
170 {
171 // Too many extra args
172 usage(argv[0]);
173 }
174
175 if (ftdi_init(&ftdic) < 0)
176 {
177 fprintf(stderr, "ftdi_init failed\n");
178 return EXIT_FAILURE;
179 }
180
181 if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)
182 {
183 fprintf(stderr, "ftdi_set_interface failed\n");
184 return EXIT_FAILURE;
185 }
186
187 if (ftdi_usb_open_desc(&ftdic, 0x0403, 0x6010, descstring, NULL) < 0)
188 {
189 fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic));
190 return EXIT_FAILURE;
191 }
192
193 /* A timeout value of 1 results in may skipped blocks */
194 if(ftdi_set_latency_timer(&ftdic, 2))
195 {
705f012d 196 fprintf(stderr,"Can't set latency, Error %s\n",ftdi_get_error_string(&ftdic));
40da63b1
UB
197 return EXIT_FAILURE;
198 }
199
200/* if(ftdi_usb_purge_rx_buffer(&ftdic) < 0)
201 {
202 fprintf(stderr,"Can't rx purge\n",ftdi_get_error_string(&ftdic));
203 return EXIT_FAILURE;
204 }*/
205 if (outfile)
206 if ((of = fopen(outfile,"w+")) == 0)
207 fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno));
208 if (of)
209 if (setvbuf(of, NULL, _IOFBF , 1<<16) == 0)
210 outputFile = of;
211 signal(SIGINT, sigintHandler);
212
213 err = ftdi_readstream(&ftdic, readCallback, NULL, 8, 256);
214 if (err < 0 && !exitRequested)
215 exit(1);
216
217 if (outputFile) {
218 fclose(outputFile);
219 outputFile = NULL;
220 }
221 fprintf(stderr, "Capture ended.\n");
222
223 if (ftdi_set_bitmode(&ftdic, 0xff, BITMODE_RESET) < 0)
224 {
705f012d 225 fprintf(stderr,"Can't set synchronous fifo mode, Error %s\n",ftdi_get_error_string(&ftdic));
40da63b1
UB
226 return EXIT_FAILURE;
227 }
228 ftdi_usb_close(&ftdic);
229 ftdi_deinit(&ftdic);
230 signal(SIGINT, SIG_DFL);
231 if (check && outfile)
232 {
233 if ((outputFile = fopen(outfile,"r")) == 0)
234 {
235 fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno));
236 return EXIT_FAILURE;
237 }
238 check_outfile(descstring);
239 fclose(outputFile);
240 }
241 else if (check)
ededbc1c
UB
242 fprintf(stderr,"%d errors of %llu blocks (%Le), %d (%Le) blocks skipped\n",
243 n_err, (unsigned long long) blocks, (long double)n_err/(long double) blocks,
40da63b1
UB
244 skips, (long double)skips/(long double) blocks);
245 exit (0);
246}
247
248void check_outfile(char *descstring)
249{
250 if(strcmp(descstring,"FT2232HTEST") == 0)
251 {
252 char buf0[1024];
253 char buf1[1024];
254 char bufr[1024];
255 char *pa, *pb, *pc;
256 unsigned int num_lines = 0, line_num = 1;
257 int err_count = 0;
258 unsigned int num_start, num_end;
259
40da63b1
UB
260 pa = buf0;
261 pb = buf1;
262 pc = buf0;
263 if(fgets(pa, 1023, outputFile) == NULL)
264 {
265 fprintf(stderr,"Empty output file\n");
266 return;
267 }
268 while(fgets(pb, 1023, outputFile) != NULL)
269 {
270 num_lines++;
271 unsigned int num_save = num_start;
272 if( sscanf(pa,"%6u%94s%6u",&num_start, bufr,&num_end) !=3)
273 {
274 fprintf(stdout,"Format doesn't match at line %8d \"%s",
275 num_lines, pa);
276 err_count++;
277 line_num = num_save +2;
278 }
279 else
280 {
281 if ((num_start+1)%100000 != num_end)
282 {
283 if (err_count < 20)
284 fprintf(stdout,"Malformed line %d \"%s\"\n",
285 num_lines, pa);
286 err_count++;
287 }
288 else if(num_start != line_num)
289 {
290 if (err_count < 20)
291 fprintf(stdout,"Skipping from %d to %d\n",
292 line_num, num_start);
293 err_count++;
294
295 }
296 line_num = num_end;
297 }
298 pa = pb;
299 pb = pc;
300 pc = pa;
301 }
302 if(err_count)
303 fprintf(stdout,"\n%d errors of %d data sets %f\n", err_count, num_lines, (double) err_count/(double)num_lines);
304 else
305 fprintf(stdout,"No errors for %d lines\n",num_lines);
306 }
307 else if(strcmp(descstring,"LLBBC10") == 0)
308 {
309 uint32_t block0[4];
310 uint32_t block1[4];
311 uint32_t *pa = block0;
312 uint32_t *pb = block1;
313 uint32_t *pc = block0;
314 uint32_t start= 0;
315 uint32_t nread = 0;
40da63b1
UB
316 int n_shown = 0;
317 int n_errors = 0;
318 if (fread(pa, sizeof(uint32_t), 4,outputFile) < 4)
319 {
320 fprintf(stderr,"Empty result file\n");
321 return;
322 }
323 while(fread(pb, sizeof(uint32_t), 4,outputFile) != 0)
324 {
325 blocks++;
326 nread = pa[0];
327 if(start>0 && (nread != start))
328 {
329 if(n_shown < 30)
330 {
ededbc1c
UB
331 fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu \n",
332 (nread-start)/0x4000, start -0x4000, nread, (unsigned long long) blocks);
40da63b1
UB
333 n_shown ++;
334 }
335 n_errors++;
336 }
337 else if (n_shown >0)
338 n_shown--;
339 start = nread + 0x4000;
340 pa = pb;
341 pb = pc;
342 pc = pa;
343 }
344 if(n_errors)
ededbc1c
UB
345 fprintf(stderr, "%d blocks wrong from %llu blocks read\n",
346 n_errors, (unsigned long long) blocks);
40da63b1 347 else
ededbc1c 348 fprintf(stderr, "%llu blocks all fine\n", (unsigned long long) blocks);
40da63b1
UB
349 }
350}