3 * Test reading from FT2232H in synchronous FIFO mode.
5 * The FT2232H must supply data due to an appropriate circuit
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
12 * After start, data will be read in streaming until the program is aborted
13 * Progress information will be printed out
14 * If a filename is given on the command line, the data read will be
15 * written to that file
27 void check_outfile(char *);
29 static FILE *outputFile;
32 static int exitRequested = 0;
36 * SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
40 sigintHandler(int signum)
46 usage(const char *argv0)
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"
54 "If some filename is given, write data read to that file\n"
55 "Progress information is printed each second\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",
66 static uint32_t start = 0;
67 static uint32_t offset = 0;
68 static uint64_t blocks = 0;
69 static uint32_t skips = 0;
70 static uint32_t n_err = 0;
72 readCallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata)
80 for (i= offset; i<length-16; i+=16)
82 num = *(uint32_t*) (buffer+i);
83 if (start && (num != start +0x4000))
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);
97 num = *(uint32_t*) (buffer+i);
98 if (start && (num != start +0x4000))
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);
118 if (fwrite(buffer, length, 1, outputFile) != 1)
120 perror("Write error");
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",
129 progress->current.totalBytes / (1024.0 * 1024.0),
130 progress->currentRate / 1024.0,
131 progress->totalRate / 1024.0,
134 return exitRequested ? 1 : 0;
137 int main(int argc, char **argv)
139 struct ftdi_context *ftdi;
142 char const *outfile = 0;
145 char *descstring = NULL;
147 static struct option long_options[] = {{NULL},};
149 while ((c = getopt_long(argc, argv, "P:n", long_options, &option_index)) !=- 1)
164 if (optind == argc - 1)
166 // Exactly one extra argument- a dump file
167 outfile = argv[optind];
169 else if (optind < argc)
171 // Too many extra args
175 if ((ftdi = ftdi_new()) == 0)
177 fprintf(stderr, "ftdi_new failed\n");
181 if (ftdi_set_interface(ftdi, INTERFACE_A) < 0)
183 fprintf(stderr, "ftdi_set_interface failed\n");
188 if (ftdi_usb_open_desc(ftdi, 0x0403, 0x6010, descstring, NULL) < 0)
190 fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi));
195 /* A timeout value of 1 results in may skipped blocks */
196 if(ftdi_set_latency_timer(ftdi, 2))
198 fprintf(stderr,"Can't set latency, Error %s\n",ftdi_get_error_string(ftdi));
199 ftdi_usb_close(ftdi);
204 /* if(ftdi_usb_purge_rx_buffer(ftdi) < 0)
206 fprintf(stderr,"Can't rx purge\n",ftdi_get_error_string(ftdi));
210 if ((of = fopen(outfile,"w+")) == 0)
211 fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno));
213 if (setvbuf(of, NULL, _IOFBF , 1<<16) == 0)
215 signal(SIGINT, sigintHandler);
217 err = ftdi_readstream(ftdi, readCallback, NULL, 8, 256);
218 if (err < 0 && !exitRequested)
225 fprintf(stderr, "Capture ended.\n");
227 if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET) < 0)
229 fprintf(stderr,"Can't set synchronous fifo mode, Error %s\n",ftdi_get_error_string(ftdi));
230 ftdi_usb_close(ftdi);
234 ftdi_usb_close(ftdi);
236 signal(SIGINT, SIG_DFL);
237 if (check && outfile)
239 if ((outputFile = fopen(outfile,"r")) == 0)
241 fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno));
242 ftdi_usb_close(ftdi);
246 check_outfile(descstring);
250 fprintf(stderr,"%d errors of %llu blocks (%Le), %d (%Le) blocks skipped\n",
251 n_err, (unsigned long long) blocks, (long double)n_err/(long double) blocks,
252 skips, (long double)skips/(long double) blocks);
256 void check_outfile(char *descstring)
258 if(strcmp(descstring,"FT2232HTEST") == 0)
264 unsigned int num_lines = 0, line_num = 1;
266 unsigned int num_start, num_end;
271 if(fgets(pa, 1023, outputFile) == NULL)
273 fprintf(stderr,"Empty output file\n");
276 while(fgets(pb, 1023, outputFile) != NULL)
279 unsigned int num_save = num_start;
280 if( sscanf(pa,"%6u%94s%6u",&num_start, bufr,&num_end) !=3)
282 fprintf(stdout,"Format doesn't match at line %8d \"%s",
285 line_num = num_save +2;
289 if ((num_start+1)%100000 != num_end)
292 fprintf(stdout,"Malformed line %d \"%s\"\n",
296 else if(num_start != line_num)
299 fprintf(stdout,"Skipping from %d to %d\n",
300 line_num, num_start);
311 fprintf(stdout,"\n%d errors of %d data sets %f\n", err_count, num_lines, (double) err_count/(double)num_lines);
313 fprintf(stdout,"No errors for %d lines\n",num_lines);
315 else if(strcmp(descstring,"LLBBC10") == 0)
319 uint32_t *pa = block0;
320 uint32_t *pb = block1;
321 uint32_t *pc = block0;
326 if (fread(pa, sizeof(uint32_t), 4,outputFile) < 4)
328 fprintf(stderr,"Empty result file\n");
331 while(fread(pb, sizeof(uint32_t), 4,outputFile) != 0)
335 if(start>0 && (nread != start))
339 fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu \n",
340 (nread-start)/0x4000, start -0x4000, nread, (unsigned long long) blocks);
347 start = nread + 0x4000;
353 fprintf(stderr, "%d blocks wrong from %llu blocks read\n",
354 n_errors, (unsigned long long) blocks);
356 fprintf(stderr, "%llu blocks all fine\n", (unsigned long long) blocks);