2025-02-19 16:17:08 +01:00

183 lines
4.6 KiB
C

/* serial_test.c
Read/write data via serial I/O
This program is distributed under the GPL, version 2
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __WIN32__
#define sleep(x) Sleep(x)
#endif
#include <getopt.h>
#include <signal.h>
#include <ftdi.h>
static int exitRequested = 0;
/*
* sigintHandler --
*
* SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
*/
static void
sigintHandler(int signum)
{
exitRequested = 1;
}
int main(int argc, char **argv)
{
struct ftdi_context *ftdi;
unsigned char buf[1024];
int f = 0, i;
int vid = 0x403;
int pid = 0;
int baudrate = 115200;
int interface = INTERFACE_ANY;
int do_write = 0;
unsigned int pattern = 0xffff;
int retval = EXIT_FAILURE;
while ((i = getopt(argc, argv, "i:v:p:b:w::")) != -1)
{
switch (i)
{
case 'i': // 0=ANY, 1=A, 2=B, 3=C, 4=D
interface = strtoul(optarg, NULL, 0);
break;
case 'v':
vid = strtoul(optarg, NULL, 0);
break;
case 'p':
pid = strtoul(optarg, NULL, 0);
break;
case 'b':
baudrate = strtoul(optarg, NULL, 0);
break;
case 'w':
do_write = 1;
if (optarg)
pattern = strtoul(optarg, NULL, 0);
if (pattern > 0xff)
{
fprintf(stderr, "Please provide a 8 bit pattern\n");
exit(-1);
}
break;
default:
fprintf(stderr, "usage: %s [-i interface] [-v vid] [-p pid] [-b baudrate] [-w [pattern]]\n", *argv);
exit(-1);
}
}
// Init
if ((ftdi = ftdi_new()) == 0)
{
fprintf(stderr, "ftdi_new failed\n");
return EXIT_FAILURE;
}
if (!vid && !pid && (interface == INTERFACE_ANY))
{
ftdi_set_interface(ftdi, INTERFACE_ANY);
struct ftdi_device_list *devlist;
int res;
if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0)
{
fprintf(stderr, "No FTDI with default VID/PID found\n");
goto do_deinit;
}
if (res == 1)
{
f = ftdi_usb_open_dev(ftdi, devlist[0].dev);
if (f<0)
{
fprintf(stderr, "Unable to open device %d: (%s)",
i, ftdi_get_error_string(ftdi));
}
}
ftdi_list_free(&devlist);
if (res > 1)
{
fprintf(stderr, "%d Devices found, please select Device with VID/PID\n", res);
/* TODO: List Devices*/
goto do_deinit;
}
if (res == 0)
{
fprintf(stderr, "No Devices found with default VID/PID\n");
goto do_deinit;
}
}
else
{
// Select interface
ftdi_set_interface(ftdi, interface);
// Open device
f = ftdi_usb_open(ftdi, vid, pid);
}
if (f < 0)
{
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi));
exit(-1);
}
// Set baudrate
f = ftdi_set_baudrate(ftdi, baudrate);
if (f < 0)
{
fprintf(stderr, "unable to set baudrate: %d (%s)\n", f, ftdi_get_error_string(ftdi));
exit(-1);
}
/* Set line parameters
*
* TODO: Make these parameters settable from the command line
*
* Parameters are choosen that sending a continous stream of 0x55
* should give a square wave
*
*/
f = ftdi_set_line_property(ftdi, 8, STOP_BIT_1, NONE);
if (f < 0)
{
fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi));
exit(-1);
}
if (do_write)
for(i=0; i<1024; i++)
buf[i] = pattern;
signal(SIGINT, sigintHandler);
while (!exitRequested)
{
if (do_write)
f = ftdi_write_data(ftdi, buf,
(baudrate/512 >sizeof(buf))?sizeof(buf):
(baudrate/512)?baudrate/512:1);
else
f = ftdi_read_data(ftdi, buf, sizeof(buf));
if (f<0)
sleep(1);
else if(f> 0 && !do_write)
{
fprintf(stderr, "read %d bytes\n", f);
fwrite(buf, f, 1, stdout);
fflush(stderr);
fflush(stdout);
}
}
signal(SIGINT, SIG_DFL);
retval = EXIT_SUCCESS;
ftdi_usb_close(ftdi);
do_deinit:
ftdi_free(ftdi);
return retval;
}