libftdi Archives

Subject: Why can not set DTR and RTS?

From: linux fddl <fddllinux@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Thu, 18 Apr 2013 16:54:14 +0800
  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   

Current Thread