I have a usb-to-serial cable(FTDI 232RL chip),
I am trying to control my board by a userland program(linux) basing on
libftdi, but can not set DTR and RTS. I really do not know why.
I also tried to call ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET) and
ftdi_setflowctrl(ftdi, SIO_DISABLE_FLOW_CTRL)/ftdi_setflowctrl(ftdi,
SIO_DTR_DSR_HS), but all of them were useless.
Here is my code(I'm so sorry, it's not clean enough), is there anything wrong?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <ftdi.h>
#define DEBUG
#ifdef DEBUG
#define DBG printf
#else
#define DBG
#endif
#define VID 0x0403
#define PID 0x6001
struct usb_id_info {
int vendor;
int product;
};
/* ctrl the pin(s) or not */
struct ctrl_pins {
int dtr; /* ctrl RS232's DTR pin */
int rts; /* ctrl RS232's RTS pin */
};
struct cmd_context {
struct usb_id_info usb_id;
struct ctrl_pins pins;
};
static struct cmd_context cmd;
static char app_name[32] = {"ftdi-pin-ctrl"};
static void show_usage(void)
{
fprintf(stderr, "Usage: %s [-v hex] [-p hex] [-o pin]\n",
app_name);
fprintf(stderr, "Options are:\n");
fprintf(stderr, " -v hex assign a vendor id, default 0x0403\n");
fprintf(stderr, " -p hex assign a product id, default 0x6001\n");
fprintf(stderr, " -o pin which pin to ctrl, now only dtr and rts are
supported, default none\n");
}
static void exit_bad_args(void)
{
show_usage();
exit(EXIT_FAILURE);
}
static int parse_args(int argc, char **argv)
{
int result = 0;
const char short_opts[] = {"v:p:o:h"};
while((result = getopt(argc, argv, short_opts)) != -1) {
switch(result) {
case 'v':
DBG("option=%c, optarg=%s\n", result, optarg);
cmd.usb_id.vendor = (int)strtoul(optarg, NULL, 16);
break;
case 'p':
DBG("option=%c, optarg=%s\n", result, optarg);
cmd.usb_id.product = (int)strtoul(optarg, NULL, 16);
break;
case 'o':
DBG("option=%c, optarg=%s\n", result, optarg);
if(!strcmp("dtr", optarg))
cmd.pins.dtr = 1;
if(!strcmp("rts", optarg))
cmd.pins.rts = 1;
DBG("dtr[%d], rts[%d]\n", cmd.pins.dtr, cmd.pins.rts);
break;
case 'h':
show_usage();
exit(EXIT_SUCCESS);
default:
show_usage();
exit(EXIT_FAILURE);
}
}
DBG("vendor[0x%04x]\n", cmd.usb_id.vendor);
DBG("product[0x%04x]\n", cmd.usb_id.product);
DBG("dtr[%d], rts[%d]\n", cmd.pins.dtr, cmd.pins.rts);
return 0;
}
static void set_default_args(void)
{
memset(&cmd, 0, sizeof(cmd));
cmd.usb_id.vendor = VID;
cmd.usb_id.product = PID;
}
static int ctrl_dtr(struct ftdi_context *ftdi)
{
int f;
int i;
for (i = 0; i < 8; i++) {
if (f = ftdi_setdtr(ftdi, SIO_SET_DTR_HIGH))
return f;
usleep(1 * 1000000);
if (f = ftdi_setdtr(ftdi, SIO_SET_DTR_LOW))
return f;
usleep(1 * 1000000);
}
return f;
}
static int ctrl_rts(struct ftdi_context *ftdi)
{
int f;
int i;
for (i = 0; i < 8; i++) {
if (f = ftdi_setrts(ftdi, SIO_SET_DTR_HIGH))
return f;
usleep(1 * 1000000);
if (f = ftdi_setrts(ftdi, SIO_SET_DTR_LOW))
return f;
usleep(1 * 1000000);
}
return f;
}
int main(int argc, char **argv)
{
struct ftdi_context *ftdi;
int f,i;
unsigned char buf[1];
int retval = 0;
/* at least one args is needed */
if (argc <= 1)
exit_bad_args();
set_default_args();
parse_args(argc, argv);
if ((ftdi = ftdi_new()) == 0) {
fprintf(stderr, "ftdi_new failed\n");
return EXIT_FAILURE;
}
// f = ftdi_usb_open(ftdi, 0x0403, 0x6001);
f = ftdi_usb_open(ftdi, cmd.usb_id.vendor, cmd.usb_id.product);
if (f < 0 && f != -5) {
fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
f, ftdi_get_error_string(ftdi));
retval = EXIT_FAILURE;
goto done;
}
printf("ftdi open succeeded: %d\n",f);
//sjh
printf("enabling bitbang mode\n");
ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
//usleep(3 * 1000000);
#if 1
printf("resetting bitmode...\n");
f = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
if (f < 0) {
fprintf(stderr, "unable to RESET ftdi device: %d (%s)\n", f,
ftdi_get_error_string(ftdi));
retval = 1;
goto done;
}
#endif
#if 1
printf("disabling flowctrl...\n");
//f = ftdi_setflowctrl(ftdi, SIO_DISABLE_FLOW_CTRL);
f = ftdi_setflowctrl(ftdi, SIO_DTR_DSR_HS);
if (f < 0) {
fprintf(stderr, "fail to disable flowctrl ftdi device: %d (%s)\n", f,
ftdi_get_error_string(ftdi));
retval = 1;
goto done;
}
#endif
#if 1
printf("setting baudrage...\n");
f = ftdi_set_baudrate(ftdi, 9600);
if (f < 0) {
fprintf(stderr, "fail to set baudrate ftdi device: %d (%s)\n", f,
ftdi_get_error_string(ftdi));
retval = 1;
goto done;
}
#endif
//if (cmd.pins.dtr) {
printf("controlling dtr...\n");
f = ctrl_dtr(ftdi);
if (f < 0) {
fprintf(stderr,"setup failed for dtr, error %d (%s)\n",
f, ftdi_get_error_string(ftdi));
retval = EXIT_FAILURE;
goto done;
}
//}
//if (cmd.pins.rts) {
printf("controlling rts...\n");
f = ctrl_rts(ftdi);
if (f < 0) {
fprintf(stderr,"setup failed for dtr, error %d (%s)\n",
f, ftdi_get_error_string(ftdi));
retval = EXIT_FAILURE;
goto done;
}
//}
#if 1
buf[0] = 0x0;
printf("turning everything on\n");
f = ftdi_write_data(ftdi, buf, 1);
if (f < 0)
{
fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f,
ftdi_get_error_string(ftdi));
}
//usleep(3 * 1000000);
buf[0] = 0xFF;
printf("turning everything off\n");
f = ftdi_write_data(ftdi, buf, 1);
if (f < 0)
{
fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f,
ftdi_get_error_string(ftdi));
}
//usleep(3 * 1000000);
for (i = 0; i < 32; i++)
{
buf[0] = 0 | (0xFF ^ 1 << (i % 8));
if ( i > 0 && (i % 8) == 0)
{
printf("\n");
}
printf("%02hhx ",buf[0]);
fflush(stdout);
f = ftdi_write_data(ftdi, buf, 1);
if (f < 0)
{
fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f,
ftdi_get_error_string(ftdi));
}
usleep(1 * 1000000);
}
printf("\n");
#endif
printf("disabling bitbang mode\n");
ftdi_disable_bitbang(ftdi);
ftdi_usb_close(ftdi);
done:
ftdi_free(ftdi);
return retval;
}
Best regards
ShiJinghui
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|