From 9ecfef2aec5069eaefa3648e07fe58cbb02152fa Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Mon, 8 Sep 2008 16:14:53 +0000 Subject: [PATCH] libftdi: (tomj) fixed flow control code, fixed wrong array/buffer assignment in find_all.c --- AUTHORS | 1 + ChangeLog | 4 ++- examples/find_all.c | 2 +- src/ftdi.c | 63 ++++++++++++++++++++++++++++++++++++++++---------- src/ftdi.h | 18 +++++++++++++- 5 files changed, 72 insertions(+), 16 deletions(-) diff --git a/AUTHORS b/AUTHORS index 03a341c..66def99 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ see Changelog for full details: Juergen Beisert Lorenz Moesenlechner Mark Hämmerling + Marek Vavruša Matthias Kranz Matthijs ten Berge Max diff --git a/ChangeLog b/ChangeLog index abccc27..9aa047e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,10 @@ New in 0.14 ----------- -* Ability to set RS232 break type (Intra2net) +* Fixed flow control code for second FT2232 interface (Marek Vavruša) +* Ability to set flow control via one USB call (Marek Vavruša) * 64 bit build support in the RPM spec file (Uwe Bonnes) * Small fix to the RPM spec file (Uwe Bonnes) +* Ability to set RS232 break type (Intra2net) * Grouped flow control and modem status code together (Intra2net) New in 0.13 diff --git a/examples/find_all.c b/examples/find_all.c index 0ee1aa6..9cfa4c6 100644 --- a/examples/find_all.c +++ b/examples/find_all.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) i = 0; for (curdev = devlist; curdev != NULL; i++) { printf("Checking device: %d\n", i); - if((ret = ftdi_usb_get_strings(&ftdic, curdev->dev, &manufacturer, 128, description, 128, NULL, 0)) < 0) { + if((ret = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0) { fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } diff --git a/src/ftdi.c b/src/ftdi.c index 22d29bf..a08abbf 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -518,7 +518,9 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, */ int ftdi_usb_reset(struct ftdi_context *ftdi) { - if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) + if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE, + SIO_RESET_REQUEST, SIO_RESET_SIO, + ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1,"FTDI reset failed"); // Invalidate data in the readbuffer @@ -538,7 +540,9 @@ int ftdi_usb_reset(struct ftdi_context *ftdi) */ int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi) { - if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) + if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE, + SIO_RESET_REQUEST, SIO_RESET_PURGE_RX, + ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1, "FTDI purge of RX buffer failed"); // Invalidate data in the readbuffer @@ -558,7 +562,9 @@ int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi) */ int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi) { - if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) + if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE, + SIO_RESET_REQUEST, SIO_RESET_PURGE_TX, + ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1, "FTDI purge of TX buffer failed"); return 0; @@ -747,7 +753,9 @@ int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) : (baudrate * 21 < actual_baudrate * 20))) ftdi_error_return (-1, "Unsupported baudrate. Note: bitbang baudrates are automatically multiplied by 4"); - if (usb_control_msg(ftdi->usb_dev, 0x40, 3, value, index, NULL, 0, ftdi->usb_write_timeout) != 0) + if (usb_control_msg(ftdi->usb_dev, SIO_SET_BAUDRATE_REQUEST_TYPE, + SIO_SET_BAUDRATE_REQUEST, value, + index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return (-2, "Setting new baudrate failed"); ftdi->baudrate = baudrate; @@ -830,7 +838,9 @@ int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits, break; } - if (usb_control_msg(ftdi->usb_dev, 0x40, 0x04, value, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) + if (usb_control_msg(ftdi->usb_dev, SIO_SET_DATA_REQUEST_TYPE, + SIO_SET_DATA_REQUEST, value, + ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return (-1, "Setting new line property failed"); return 0; @@ -1428,11 +1438,6 @@ int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status) return 0; } - -/* - Flow control code by Lorenz Moesenlechner (lorenz@hcilab.org) - and Matthias Kranz (matthias@hcilab.org) -*/ /** Set flowcontrol for ftdi chip @@ -1446,7 +1451,7 @@ int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status) int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl) { if (usb_control_msg(ftdi->usb_dev, SIO_SET_FLOW_CTRL_REQUEST_TYPE, - SIO_SET_FLOW_CTRL_REQUEST, 0, (flowctrl | ftdi->interface), + SIO_SET_FLOW_CTRL_REQUEST, 0, (flowctrl | ftdi->index), NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1, "set flow control failed"); @@ -1472,7 +1477,7 @@ int ftdi_setdtr(struct ftdi_context *ftdi, int state) usb_val = SIO_SET_DTR_LOW; if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE, - SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->interface, + SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1, "set dtr failed"); @@ -1498,7 +1503,7 @@ int ftdi_setrts(struct ftdi_context *ftdi, int state) usb_val = SIO_SET_RTS_LOW; if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE, - SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->interface, + SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) ftdi_error_return(-1, "set of rts failed"); @@ -1506,6 +1511,38 @@ int ftdi_setrts(struct ftdi_context *ftdi, int state) } /** + Set dtr and rts line in one pass + + \param ftdi pointer to ftdi_context + \param dtr DTR state to set line to (1 or 0) + \param rts RTS state to set line to (1 or 0) + + \retval 0: all fine + \retval -1 set dtr/rts failed + */ +int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts) +{ + unsigned short usb_val; + + if (dtr) + usb_val = SIO_SET_DTR_HIGH; + else + usb_val = SIO_SET_DTR_LOW; + + if (rts) + usb_val |= SIO_SET_RTS_HIGH; + else + usb_val |= SIO_SET_RTS_LOW; + + if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE, + SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index, + NULL, 0, ftdi->usb_write_timeout) != 0) + ftdi_error_return(-1, "set of rts/dtr failed"); + + return 0; +} + +/** Set the special event character \param ftdi pointer to ftdi_context diff --git a/src/ftdi.h b/src/ftdi.h index 1dc4ea3..ed40b68 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -94,11 +94,26 @@ enum ftdi_interface { /* Address Low */ /* Definitions for flow control */ +#define SIO_RESET 0 /* Reset the port */ #define SIO_MODEM_CTRL 1 /* Set the modem control register */ #define SIO_SET_FLOW_CTRL 2 /* Set flow control register */ +#define SIO_SET_BAUD_RATE 3 /* Set baud rate */ +#define SIO_SET_DATA 4 /* Set the data characteristics of the port */ + +#define SIO_RESET_REQUEST_TYPE 0x40 +#define SIO_RESET_REQUEST SIO_RESET +#define SIO_RESET_SIO 0 +#define SIO_RESET_PURGE_RX 1 +#define SIO_RESET_PURGE_TX 2 + +#define SIO_SET_BAUDRATE_REQUEST_TYPE 0x40 +#define SIO_SET_BAUDRATE_REQUEST SIO_SET_BAUD_RATE + +#define SIO_SET_DATA_REQUEST_TYPE 0x40 +#define SIO_SET_DATA_REQUEST SIO_SET_DATA -#define SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40 #define SIO_SET_FLOW_CTRL_REQUEST SIO_SET_FLOW_CTRL +#define SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40 #define SIO_DISABLE_FLOW_CTRL 0x0 #define SIO_RTS_CTS_HS (0x1 << 8) @@ -294,6 +309,7 @@ extern "C" { // flow control int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl); + int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts); int ftdi_setdtr(struct ftdi_context *ftdi, int state); int ftdi_setrts(struct ftdi_context *ftdi, int state); -- 1.7.1