Replace "olimex_iso" transport with generic "ftdi".
Constructor now takes arguments for vendor/product IDs and baud rate.
This commit is contained in:
parent
1392cea7e1
commit
837e1d8e00
2
Makefile
2
Makefile
|
@ -116,7 +116,7 @@ OBJ=\
|
||||||
util/demangle.o \
|
util/demangle.o \
|
||||||
transport/cp210x.o \
|
transport/cp210x.o \
|
||||||
transport/cdc_acm.o \
|
transport/cdc_acm.o \
|
||||||
transport/olimex_iso.o \
|
transport/ftdi.o \
|
||||||
transport/rf2500.o \
|
transport/rf2500.o \
|
||||||
transport/ti3410.o \
|
transport/ti3410.o \
|
||||||
transport/comport.o \
|
transport/comport.o \
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "opdb.h"
|
#include "opdb.h"
|
||||||
|
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "olimex_iso.h"
|
#include "ftdi.h"
|
||||||
#include "rf2500.h"
|
#include "rf2500.h"
|
||||||
#include "ti3410.h"
|
#include "ti3410.h"
|
||||||
#include "cp210x.h"
|
#include "cp210x.h"
|
||||||
|
@ -1249,7 +1249,8 @@ static device_t fet_open_olimex_iso(const struct device_args *args)
|
||||||
if (args->flags & DEVICE_FLAG_TTY)
|
if (args->flags & DEVICE_FLAG_TTY)
|
||||||
trans = comport_open(args->path, 200000);
|
trans = comport_open(args->path, 200000);
|
||||||
else
|
else
|
||||||
trans = olimex_iso_open(args->path, args->requested_serial);
|
trans = ftdi_open(args->path, args->requested_serial,
|
||||||
|
0x15ba, 0x0008, 200000);
|
||||||
|
|
||||||
if (!trans)
|
if (!trans)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -20,18 +20,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "olimex_iso.h"
|
#include "ftdi.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "usbutil.h"
|
#include "usbutil.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
|
||||||
struct iso_transport {
|
struct ftdi_transport {
|
||||||
struct transport base;
|
struct transport base;
|
||||||
struct usb_dev_handle *handle;
|
struct usb_dev_handle *handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USB_VENDOR 0x15ba
|
|
||||||
#define USB_PRODUCT 0x0008
|
|
||||||
#define USB_INTERFACE 0
|
#define USB_INTERFACE 0
|
||||||
#define USB_CONFIG 1
|
#define USB_CONFIG 1
|
||||||
|
|
||||||
|
@ -62,61 +60,61 @@ struct iso_transport {
|
||||||
|
|
||||||
#define FTDI_PACKET_SIZE 64
|
#define FTDI_PACKET_SIZE 64
|
||||||
|
|
||||||
struct config_rec {
|
#define FTDI_CLOCK 3000000
|
||||||
const char *desc;
|
|
||||||
int request;
|
|
||||||
int value;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct config_rec config[] = {
|
#define FTDI_DTR 0x0001
|
||||||
{"reset FTDI",
|
#define FTDI_RTS 0x0002
|
||||||
FTDI_SIO_RESET, FTDI_SIO_RESET_SIO},
|
#define FTDI_WRITE_DTR 0x0100
|
||||||
{"set data characteristics",
|
#define FTDI_WRITE_RTS 0x0200
|
||||||
FTDI_SIO_SET_DATA, 8}, /* 8,N,1 */
|
|
||||||
{"disable flow control",
|
|
||||||
FTDI_SIO_SET_FLOW_CTRL, 0},
|
|
||||||
{"set modem control lines",
|
|
||||||
FTDI_SIO_MODEM_CTRL, 0x303}, /* DSR + CTS */
|
|
||||||
{"set baud rate divisor",
|
|
||||||
FTDI_SIO_SET_BAUD_RATE, 0xf}, /* 200 kbps */
|
|
||||||
{"set latency timer",
|
|
||||||
FTDI_SIO_SET_LATENCY_TIMER, 50}, /* 50 ms */
|
|
||||||
{"purge TX",
|
|
||||||
FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_TX},
|
|
||||||
{"purge RX",
|
|
||||||
FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX}
|
|
||||||
};
|
|
||||||
|
|
||||||
int configure_ftdi(struct usb_dev_handle *handle)
|
static int do_cfg(struct usb_dev_handle *handle, const char *what,
|
||||||
|
int request, int value)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LEN(config); i++) {
|
|
||||||
const struct config_rec *r = &config[i];
|
|
||||||
|
|
||||||
if (usb_control_msg(handle, REQTYPE_HOST_TO_DEVICE,
|
if (usb_control_msg(handle, REQTYPE_HOST_TO_DEVICE,
|
||||||
r->request, r->value, 0,
|
request, value, 0,
|
||||||
NULL, 0, REQ_TIMEOUT_MS)) {
|
NULL, 0, REQ_TIMEOUT_MS)) {
|
||||||
printc_err("olimex_iso: %s failed: %s\n",
|
printc_err("ftdi: %s failed: %s\n", what, usb_strerror());
|
||||||
r->desc, usb_strerror());
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_device(struct iso_transport *tr, struct usb_device *dev)
|
int configure_ftdi(struct usb_dev_handle *h, int baud_rate)
|
||||||
|
{
|
||||||
|
if (do_cfg(h, "reset FTDI",
|
||||||
|
FTDI_SIO_RESET, FTDI_SIO_RESET_SIO) < 0 ||
|
||||||
|
do_cfg(h, "set data characteristics",
|
||||||
|
FTDI_SIO_SET_DATA, 8) < 0 ||
|
||||||
|
do_cfg(h, "disable flow control",
|
||||||
|
FTDI_SIO_SET_FLOW_CTRL, 0) < 0 ||
|
||||||
|
do_cfg(h, "set modem control lines",
|
||||||
|
FTDI_SIO_MODEM_CTRL, 0x303) < 0 ||
|
||||||
|
do_cfg(h, "set baud rate",
|
||||||
|
FTDI_SIO_SET_BAUD_RATE, FTDI_CLOCK / baud_rate) < 0 ||
|
||||||
|
do_cfg(h, "set latency timer",
|
||||||
|
FTDI_SIO_SET_LATENCY_TIMER, 50) < 0 ||
|
||||||
|
do_cfg(h, "purge TX",
|
||||||
|
FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_TX) < 0 ||
|
||||||
|
do_cfg(h, "purge RX",
|
||||||
|
FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_device(struct ftdi_transport *tr, struct usb_device *dev,
|
||||||
|
int baud_rate)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
int driver;
|
int driver;
|
||||||
char drv_name[128];
|
char drv_name[128];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printc_dbg("olimex_iso: trying to open %s\n", dev->filename);
|
printc_dbg("ftdi: trying to open %s\n", dev->filename);
|
||||||
tr->handle = usb_open(dev);
|
tr->handle = usb_open(dev);
|
||||||
if (!tr->handle) {
|
if (!tr->handle) {
|
||||||
printc_err("olimex_iso: can't open device: %s\n",
|
printc_err("ftdi: can't open device: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -127,14 +125,14 @@ static int open_device(struct iso_transport *tr, struct usb_device *dev)
|
||||||
if (driver >= 0) {
|
if (driver >= 0) {
|
||||||
printc_dbg("Detaching kernel driver \"%s\"\n", drv_name);
|
printc_dbg("Detaching kernel driver \"%s\"\n", drv_name);
|
||||||
if (usb_detach_kernel_driver_np(tr->handle, USB_INTERFACE) < 0)
|
if (usb_detach_kernel_driver_np(tr->handle, USB_INTERFACE) < 0)
|
||||||
printc_err("warning: olimex_iso: can't detach "
|
printc_err("warning: ftdi: can't detach "
|
||||||
"kernel driver: %s\n", usb_strerror());
|
"kernel driver: %s\n", usb_strerror());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __Windows__
|
#ifdef __Windows__
|
||||||
if (usb_set_configuration(tr->handle, USB_CONFIG) < 0) {
|
if (usb_set_configuration(tr->handle, USB_CONFIG) < 0) {
|
||||||
printc_err("olimex_iso: can't set configuration: %s\n",
|
printc_err("ftdi: can't set configuration: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
usb_close(tr->handle);
|
usb_close(tr->handle);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -142,14 +140,14 @@ static int open_device(struct iso_transport *tr, struct usb_device *dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (usb_claim_interface(tr->handle, USB_INTERFACE) < 0) {
|
if (usb_claim_interface(tr->handle, USB_INTERFACE) < 0) {
|
||||||
printc_err("olimex_iso: can't claim interface: %s\n",
|
printc_err("ftdi: can't claim interface: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
usb_close(tr->handle);
|
usb_close(tr->handle);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configure_ftdi(tr->handle) < 0) {
|
if (configure_ftdi(tr->handle, baud_rate) < 0) {
|
||||||
printc_err("olimex_iso: failed to configure device: %s\n",
|
printc_err("ftdi: failed to configure device: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
usb_close(tr->handle);
|
usb_close(tr->handle);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -160,7 +158,7 @@ static int open_device(struct iso_transport *tr, struct usb_device *dev)
|
||||||
|
|
||||||
static void tr_destroy(transport_t tr_base)
|
static void tr_destroy(transport_t tr_base)
|
||||||
{
|
{
|
||||||
struct iso_transport *tr = (struct iso_transport *)tr_base;
|
struct ftdi_transport *tr = (struct ftdi_transport *)tr_base;
|
||||||
|
|
||||||
usb_close(tr->handle);
|
usb_close(tr->handle);
|
||||||
free(tr);
|
free(tr);
|
||||||
|
@ -168,7 +166,7 @@ static void tr_destroy(transport_t tr_base)
|
||||||
|
|
||||||
static int tr_recv(transport_t tr_base, uint8_t *databuf, int max_len)
|
static int tr_recv(transport_t tr_base, uint8_t *databuf, int max_len)
|
||||||
{
|
{
|
||||||
struct iso_transport *tr = (struct iso_transport *)tr_base;
|
struct ftdi_transport *tr = (struct ftdi_transport *)tr_base;
|
||||||
time_t deadline = time(NULL) + TIMEOUT_S;
|
time_t deadline = time(NULL) + TIMEOUT_S;
|
||||||
char tmpbuf[FTDI_PACKET_SIZE];
|
char tmpbuf[FTDI_PACKET_SIZE];
|
||||||
|
|
||||||
|
@ -181,7 +179,7 @@ static int tr_recv(transport_t tr_base, uint8_t *databuf, int max_len)
|
||||||
TIMEOUT_S * 1000);
|
TIMEOUT_S * 1000);
|
||||||
|
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
printc_err("olimex_iso: usb_bulk_read: %s\n",
|
printc_err("ftdi: usb_bulk_read: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -189,24 +187,24 @@ static int tr_recv(transport_t tr_base, uint8_t *databuf, int max_len)
|
||||||
if (r > 2) {
|
if (r > 2) {
|
||||||
memcpy(databuf, tmpbuf + 2, r - 2);
|
memcpy(databuf, tmpbuf + 2, r - 2);
|
||||||
#ifdef DEBUG_OLIMEX_ISO
|
#ifdef DEBUG_OLIMEX_ISO
|
||||||
printc_dbg("olimex_iso: tr_recv: flags = %02x %02x\n",
|
printc_dbg("ftdi: tr_recv: flags = %02x %02x\n",
|
||||||
tmpbuf[0], tmpbuf[1]);
|
tmpbuf[0], tmpbuf[1]);
|
||||||
debug_hexdump("olimex_iso: tr_recv", databuf, r - 2);
|
debug_hexdump("ftdi: tr_recv", databuf, r - 2);
|
||||||
#endif
|
#endif
|
||||||
return r - 2;
|
return r - 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printc_err("olimex_iso: timed out while receiving data\n");
|
printc_err("ftdi: timed out while receiving data\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tr_send(transport_t tr_base, const uint8_t *databuf, int len)
|
static int tr_send(transport_t tr_base, const uint8_t *databuf, int len)
|
||||||
{
|
{
|
||||||
struct iso_transport *tr = (struct iso_transport *)tr_base;
|
struct ftdi_transport *tr = (struct ftdi_transport *)tr_base;
|
||||||
|
|
||||||
#ifdef DEBUG_OLIMEX_ISO
|
#ifdef DEBUG_OLIMEX_ISO
|
||||||
debug_hexdump("olimex_iso: tr_send", databuf, len);
|
debug_hexdump("ftdi: tr_send", databuf, len);
|
||||||
#endif
|
#endif
|
||||||
while (len) {
|
while (len) {
|
||||||
int r = usb_bulk_write(tr->handle, EP_OUT,
|
int r = usb_bulk_write(tr->handle, EP_OUT,
|
||||||
|
@ -214,7 +212,7 @@ static int tr_send(transport_t tr_base, const uint8_t *databuf, int len)
|
||||||
TIMEOUT_S * 1000);
|
TIMEOUT_S * 1000);
|
||||||
|
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
printc_err("olimex_iso: usb_bulk_write: %s\n",
|
printc_err("ftdi: usb_bulk_write: %s\n",
|
||||||
usb_strerror());
|
usb_strerror());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -228,16 +226,28 @@ static int tr_send(transport_t tr_base, const uint8_t *databuf, int len)
|
||||||
|
|
||||||
static int tr_flush(transport_t tr_base)
|
static int tr_flush(transport_t tr_base)
|
||||||
{
|
{
|
||||||
return 0;
|
struct ftdi_transport *tr = malloc(sizeof(*tr));
|
||||||
|
|
||||||
|
return do_cfg(tr->handle, "purge RX",
|
||||||
|
FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tr_set_modem(transport_t tr_base, transport_modem_t state)
|
static int tr_set_modem(transport_t tr_base, transport_modem_t state)
|
||||||
{
|
{
|
||||||
printc_err("olimex_iso: unsupported operation: set_modem\n");
|
struct ftdi_transport *tr = malloc(sizeof(*tr));
|
||||||
return -1;
|
int value = FTDI_WRITE_DTR | FTDI_WRITE_RTS;
|
||||||
|
|
||||||
|
/* DTR and RTS bits are active-low for this device */
|
||||||
|
if (!(state & TRANSPORT_MODEM_DTR))
|
||||||
|
value |= FTDI_DTR;
|
||||||
|
if (!(state & TRANSPORT_MODEM_RTS))
|
||||||
|
value |= FTDI_RTS;
|
||||||
|
|
||||||
|
return do_cfg(tr->handle, "set modem control lines",
|
||||||
|
FTDI_SIO_MODEM_CTRL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct transport_class olimex_iso_transport = {
|
static const struct transport_class ftdi_class = {
|
||||||
.destroy = tr_destroy,
|
.destroy = tr_destroy,
|
||||||
.send = tr_send,
|
.send = tr_send,
|
||||||
.recv = tr_recv,
|
.recv = tr_recv,
|
||||||
|
@ -245,18 +255,20 @@ static const struct transport_class olimex_iso_transport = {
|
||||||
.set_modem = tr_set_modem
|
.set_modem = tr_set_modem
|
||||||
};
|
};
|
||||||
|
|
||||||
transport_t olimex_iso_open(const char *devpath,
|
transport_t ftdi_open(const char *devpath,
|
||||||
const char *requested_serial)
|
const char *requested_serial,
|
||||||
|
uint16_t vendor, uint16_t product,
|
||||||
|
int baud_rate)
|
||||||
{
|
{
|
||||||
struct iso_transport *tr = malloc(sizeof(*tr));
|
struct ftdi_transport *tr = malloc(sizeof(*tr));
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
|
|
||||||
if (!tr) {
|
if (!tr) {
|
||||||
pr_error("olimex_iso: can't allocate memory");
|
pr_error("ftdi: can't allocate memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr->base.ops = &olimex_iso_transport;
|
tr->base.ops = &ftdi_class;
|
||||||
|
|
||||||
usb_init();
|
usb_init();
|
||||||
usb_find_busses();
|
usb_find_busses();
|
||||||
|
@ -265,16 +277,15 @@ transport_t olimex_iso_open(const char *devpath,
|
||||||
if (devpath)
|
if (devpath)
|
||||||
dev = usbutil_find_by_loc(devpath);
|
dev = usbutil_find_by_loc(devpath);
|
||||||
else
|
else
|
||||||
dev = usbutil_find_by_id(USB_VENDOR, USB_PRODUCT,
|
dev = usbutil_find_by_id(vendor, product, requested_serial);
|
||||||
requested_serial);
|
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
free(tr);
|
free(tr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_device(tr, dev) < 0) {
|
if (open_device(tr, dev, baud_rate) < 0) {
|
||||||
printc_err("olimex_iso: failed to open device\n");
|
printc_err("ftdi: failed to open device\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OLIMEX_ISO_H_
|
#ifndef FTDI_H_
|
||||||
#define OLIMEX_ISO_H_
|
#define FTDI_H_
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@
|
||||||
*
|
*
|
||||||
* A particular USB device or serial number may be specified.
|
* A particular USB device or serial number may be specified.
|
||||||
*/
|
*/
|
||||||
transport_t olimex_iso_open(const char *usb_device,
|
transport_t ftdi_open(const char *usb_device,
|
||||||
const char *requested_serial);
|
const char *requested_serial,
|
||||||
|
uint16_t vendor, uint16_t product,
|
||||||
|
int baud_rate);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue