Reformat example 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 *
05c2e40a 7 * To check for skipped block with appended code,
40da63b1
UB
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{
05c2e40a 42 exitRequested = 1;
40da63b1
UB
43}
44
45static void
46usage(const char *argv0)
47{
05c2e40a
TJ
48 fprintf(stderr,
49 "Usage: %s [options...] \n"
50 "Test streaming read from FT2232H\n"
51 "[-P string] only look for product with given string\n"
52 "[-n] don't check for special block structure\n"
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"
60 "Copyright (C) 2009 Micah Dowty <micah@navi.cx>\n"
61 "Adapted for use with libftdi (C) 2010 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>\n",
62 argv0);
63 exit(1);
40da63b1
UB
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{
05c2e40a
TJ
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;
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);
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;
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);
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 {
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",
128 progress->totalTime,
129 progress->current.totalBytes / (1024.0 * 1024.0),
130 progress->currentRate / 1024.0,
131 progress->totalRate / 1024.0,
132 n_err);
133 }
134 return exitRequested ? 1 : 0;
40da63b1
UB
135}
136
137int main(int argc, char **argv)
138{
05c2e40a
TJ
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},};
40da63b1 148
05c2e40a
TJ
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 {
196 fprintf(stderr,"Can't set latency, Error %s\n",ftdi_get_error_string(&ftdic));
197 return EXIT_FAILURE;
198 }
199
200 /* if(ftdi_usb_purge_rx_buffer(&ftdic) < 0)
40da63b1 201 {
05c2e40a 202 fprintf(stderr,"Can't rx purge\n",ftdi_get_error_string(&ftdic));
40da63b1 203 return EXIT_FAILURE;
05c2e40a
TJ
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 {
219 fclose(outputFile);
220 outputFile = NULL;
221 }
222 fprintf(stderr, "Capture ended.\n");
223
224 if (ftdi_set_bitmode(&ftdic, 0xff, BITMODE_RESET) < 0)
225 {
226 fprintf(stderr,"Can't set synchronous fifo mode, Error %s\n",ftdi_get_error_string(&ftdic));
227 return EXIT_FAILURE;
228 }
229 ftdi_usb_close(&ftdic);
230 ftdi_deinit(&ftdic);
231 signal(SIGINT, SIG_DFL);
232 if (check && outfile)
233 {
234 if ((outputFile = fopen(outfile,"r")) == 0)
235 {
236 fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno));
237 return EXIT_FAILURE;
238 }
239 check_outfile(descstring);
240 fclose(outputFile);
241 }
242 else if (check)
243 fprintf(stderr,"%d errors of %llu blocks (%Le), %d (%Le) blocks skipped\n",
244 n_err, (unsigned long long) blocks, (long double)n_err/(long double) blocks,
245 skips, (long double)skips/(long double) blocks);
246 exit (0);
40da63b1
UB
247}
248
249void check_outfile(char *descstring)
250{
05c2e40a 251 if (strcmp(descstring,"FT2232HTEST") == 0)
40da63b1 252 {
05c2e40a
TJ
253 char buf0[1024];
254 char buf1[1024];
255 char bufr[1024];
256 char *pa, *pb, *pc;
257 unsigned int num_lines = 0, line_num = 1;
258 int err_count = 0;
259 unsigned int num_start, num_end;
40da63b1 260
05c2e40a
TJ
261 pa = buf0;
262 pb = buf1;
263 pc = buf0;
264 if (fgets(pa, 1023, outputFile) == NULL)
265 {
266 fprintf(stderr,"Empty output file\n");
267 return;
268 }
269 while (fgets(pb, 1023, outputFile) != NULL)
270 {
271 num_lines++;
272 unsigned int num_save = num_start;
273 if ( sscanf(pa,"%6u%94s%6u",&num_start, bufr,&num_end) !=3)
274 {
275 fprintf(stdout,"Format doesn't match at line %8d \"%s",
276 num_lines, pa);
277 err_count++;
278 line_num = num_save +2;
279 }
280 else
281 {
282 if ((num_start+1)%100000 != num_end)
283 {
284 if (err_count < 20)
285 fprintf(stdout,"Malformed line %d \"%s\"\n",
286 num_lines, pa);
287 err_count++;
288 }
289 else if (num_start != line_num)
290 {
291 if (err_count < 20)
292 fprintf(stdout,"Skipping from %d to %d\n",
293 line_num, num_start);
294 err_count++;
295
296 }
297 line_num = num_end;
298 }
299 pa = pb;
300 pb = pc;
301 pc = pa;
302 }
303 if (err_count)
304 fprintf(stdout,"\n%d errors of %d data sets %f\n", err_count, num_lines, (double) err_count/(double)num_lines);
305 else
306 fprintf(stdout,"No errors for %d lines\n",num_lines);
307 }
308 else if (strcmp(descstring,"LLBBC10") == 0)
309 {
40da63b1
UB
310 uint32_t block0[4];
311 uint32_t block1[4];
312 uint32_t *pa = block0;
313 uint32_t *pb = block1;
314 uint32_t *pc = block0;
315 uint32_t start= 0;
316 uint32_t nread = 0;
40da63b1
UB
317 int n_shown = 0;
318 int n_errors = 0;
319 if (fread(pa, sizeof(uint32_t), 4,outputFile) < 4)
320 {
321 fprintf(stderr,"Empty result file\n");
322 return;
323 }
05c2e40a 324 while (fread(pb, sizeof(uint32_t), 4,outputFile) != 0)
40da63b1
UB
325 {
326 blocks++;
327 nread = pa[0];
05c2e40a 328 if (start>0 && (nread != start))
40da63b1 329 {
05c2e40a 330 if (n_shown < 30)
40da63b1 331 {
ededbc1c
UB
332 fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu \n",
333 (nread-start)/0x4000, start -0x4000, nread, (unsigned long long) blocks);
40da63b1
UB
334 n_shown ++;
335 }
336 n_errors++;
337 }
05c2e40a
TJ
338 else if (n_shown >0)
339 n_shown--;
40da63b1
UB
340 start = nread + 0x4000;
341 pa = pb;
342 pb = pc;
343 pc = pa;
344 }
05c2e40a 345 if (n_errors)
ededbc1c
UB
346 fprintf(stderr, "%d blocks wrong from %llu blocks read\n",
347 n_errors, (unsigned long long) blocks);
40da63b1 348 else
ededbc1c 349 fprintf(stderr, "%llu blocks all fine\n", (unsigned long long) blocks);
40da63b1
UB
350 }
351}