Separate transports from drivers.
The transport/ subdirectory now contains implementations of the transport_t interface, which has been expanded to include flush and set_modem operations.
This commit is contained in:
parent
c66e885899
commit
d844adf828
12
Makefile
12
Makefile
|
@ -70,7 +70,7 @@ else
|
|||
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -Isimio -Iformats -Idrivers -Iutil -Iui
|
||||
INCLUDES = -I. -Isimio -Iformats -Itransport -Idrivers -Iutil -Iui
|
||||
GCC_CFLAGS = -O1 -Wall -Wno-char-subscripts -ggdb
|
||||
CONFIG_CFLAGS = -DLIB_DIR=\"$(LIBDIR)\"
|
||||
|
||||
|
@ -114,6 +114,11 @@ OBJ=\
|
|||
util/gdb_proto.o \
|
||||
util/dynload.o \
|
||||
util/demangle.o \
|
||||
transport/olimex.o \
|
||||
transport/olimex_iso.o \
|
||||
transport/rf2500.o \
|
||||
transport/ti3410.o \
|
||||
transport/uif.o \
|
||||
drivers/device.o \
|
||||
drivers/bsl.o \
|
||||
drivers/fet.o \
|
||||
|
@ -121,13 +126,8 @@ OBJ=\
|
|||
drivers/fet_db.o \
|
||||
drivers/flash_bsl.o \
|
||||
drivers/gdbc.o \
|
||||
drivers/olimex.o \
|
||||
drivers/rf2500.o \
|
||||
drivers/sim.o \
|
||||
drivers/uif.o \
|
||||
drivers/ti3410.o \
|
||||
drivers/tilib.o \
|
||||
drivers/olimex_iso.o \
|
||||
drivers/goodfet.o \
|
||||
formats/binfile.o \
|
||||
formats/coff.o \
|
||||
|
|
|
@ -231,7 +231,8 @@ static int send_rf2500_data(struct fet_device *dev,
|
|||
pbuf[2] = offset >> 8;
|
||||
pbuf[3] = plen;
|
||||
memcpy(pbuf + 4, data, plen);
|
||||
if (dev->transport->send(dev->transport, pbuf, plen + 4) < 0)
|
||||
if (dev->transport->ops->send(dev->transport,
|
||||
pbuf, plen + 4) < 0)
|
||||
return -1;
|
||||
|
||||
data += plen;
|
||||
|
@ -360,10 +361,10 @@ static int recv_packet(struct fet_device *dev)
|
|||
if (dev->fet_len >= plen + pkt_extra)
|
||||
return parse_packet(dev, plen);
|
||||
|
||||
len = dev->transport->recv(dev->transport,
|
||||
dev->fet_buf + dev->fet_len,
|
||||
sizeof(dev->fet_buf) -
|
||||
dev->fet_len);
|
||||
len = dev->transport->ops->recv(dev->transport,
|
||||
dev->fet_buf + dev->fet_len,
|
||||
sizeof(dev->fet_buf) -
|
||||
dev->fet_len);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
dev->fet_len += len;
|
||||
|
@ -449,7 +450,7 @@ static int send_command(struct fet_device *dev, int command_code,
|
|||
|
||||
assert (i < sizeof(buf));
|
||||
|
||||
return dev->transport->send(dev->transport, buf, i);
|
||||
return dev->transport->ops->send(dev->transport, buf, i);
|
||||
}
|
||||
|
||||
static int xfer(struct fet_device *dev,
|
||||
|
@ -776,7 +777,7 @@ static void fet_destroy(device_t dev_base)
|
|||
if (xfer(dev, C_CLOSE, NULL, 0, 1, 0) < 0)
|
||||
printc_err("fet: close command failed\n");
|
||||
|
||||
dev->transport->destroy(dev->transport);
|
||||
dev->transport->ops->destroy(dev->transport);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
@ -995,9 +996,11 @@ int try_open(struct fet_device *dev, const struct device_args *args,
|
|||
|
||||
if (dev->flags & FET_PROTO_NOLEAD_SEND) {
|
||||
printc("Resetting Olimex command processor...\n");
|
||||
transport->send(dev->transport, (const uint8_t *)"\x7e", 1);
|
||||
transport->ops->send(dev->transport,
|
||||
(const uint8_t *)"\x7e", 1);
|
||||
delay_ms(5);
|
||||
transport->send(dev->transport, (const uint8_t *)"\x7e", 1);
|
||||
transport->ops->send(dev->transport,
|
||||
(const uint8_t *)"\x7e", 1);
|
||||
delay_ms(5);
|
||||
}
|
||||
|
||||
|
@ -1073,7 +1076,7 @@ static device_t fet_open(const struct device_args *args,
|
|||
return (device_t)dev;
|
||||
|
||||
fail:
|
||||
transport->destroy(transport);
|
||||
transport->ops->destroy(transport);
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MSPDebug - debugging tool for the eZ430
|
||||
* Copyright (C) 2009-2011 Daniel Beer
|
||||
* Copyright (C) 2009-2012 Daniel Beer
|
||||
* Copyright (C) 2010 Peter Jansen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -260,20 +260,44 @@ static void usbtr_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
static int usbtr_flush(transport_t tr_base)
|
||||
{
|
||||
struct olimex_transport *tr = (struct olimex_transport *)tr_base;
|
||||
char buf[64];
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, tr->in_ep,
|
||||
buf, sizeof(buf),
|
||||
100) > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbtr_set_modem(transport_t tr_base, transport_modem_t state)
|
||||
{
|
||||
printc_err("olimex: unsupported operation: set_modem\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct transport_class olimex_transport = {
|
||||
.destroy = usbtr_destroy,
|
||||
.send = usbtr_send,
|
||||
.recv = usbtr_recv,
|
||||
.flush = usbtr_flush,
|
||||
.set_modem = usbtr_set_modem
|
||||
};
|
||||
|
||||
transport_t olimex_open(const char *devpath, const char *requested_serial)
|
||||
{
|
||||
struct olimex_transport *tr = malloc(sizeof(*tr));
|
||||
struct usb_device *dev;
|
||||
char buf[64];
|
||||
|
||||
if (!tr) {
|
||||
pr_error(__FILE__": can't allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tr->base.destroy = usbtr_destroy;
|
||||
tr->base.send = usbtr_send;
|
||||
tr->base.recv = usbtr_recv;
|
||||
tr->base.ops = &olimex_transport;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
|
@ -299,10 +323,7 @@ transport_t olimex_open(const char *devpath, const char *requested_serial)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, tr->in_ep,
|
||||
buf, sizeof(buf),
|
||||
100) > 0);
|
||||
usbtr_flush(&tr->base);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
|
@ -226,6 +226,25 @@ static int tr_send(transport_t tr_base, const uint8_t *databuf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tr_flush(transport_t tr_base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tr_set_modem(transport_t tr_base, transport_modem_t state)
|
||||
{
|
||||
printc_err("olimex_iso: unsupported operation: set_modem\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct transport_class olimex_iso_transport = {
|
||||
.destroy = tr_destroy,
|
||||
.send = tr_send,
|
||||
.recv = tr_recv,
|
||||
.flush = tr_flush,
|
||||
.set_modem = tr_set_modem
|
||||
};
|
||||
|
||||
transport_t olimex_iso_open(const char *devpath,
|
||||
const char *requested_serial)
|
||||
{
|
||||
|
@ -237,9 +256,7 @@ transport_t olimex_iso_open(const char *devpath,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tr->base.destroy = tr_destroy;
|
||||
tr->base.send = tr_send;
|
||||
tr->base.recv = tr_recv;
|
||||
tr->base.ops = &olimex_iso_transport;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
|
@ -1,5 +1,5 @@
|
|||
/* MSPDebug - debugging tool for the eZ430
|
||||
* Copyright (C) 2009, 2010 Daniel Beer
|
||||
* Copyright (C) 2009-2012 Daniel Beer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -188,20 +188,50 @@ static void usbtr_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
static int usbtr_flush(transport_t tr_base)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
struct rf2500_transport *tr = (struct rf2500_transport *)tr_base;
|
||||
char buf[64];
|
||||
|
||||
/* Flush out lingering data.
|
||||
*
|
||||
* The timeout apparently doesn't work on OS/X, and this loop
|
||||
* just hangs once the endpoint buffer empties.
|
||||
*/
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) > 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbtr_set_modem(transport_t tr_base, transport_modem_t state)
|
||||
{
|
||||
printc_err("rf2500: unsupported operation: set_modem\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct transport_class rf2500_transport = {
|
||||
.destroy = usbtr_destroy,
|
||||
.send = usbtr_send,
|
||||
.recv = usbtr_recv,
|
||||
.flush = usbtr_flush,
|
||||
.set_modem = usbtr_set_modem
|
||||
};
|
||||
|
||||
transport_t rf2500_open(const char *devpath, const char *requested_serial)
|
||||
{
|
||||
struct rf2500_transport *tr = malloc(sizeof(*tr));
|
||||
struct usb_device *dev;
|
||||
char buf[64];
|
||||
|
||||
if (!tr) {
|
||||
pr_error("rf2500: can't allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tr->base.destroy = usbtr_destroy;
|
||||
tr->base.send = usbtr_send;
|
||||
tr->base.recv = usbtr_recv;
|
||||
tr->base.ops = &rf2500_transport;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
|
@ -223,16 +253,7 @@ transport_t rf2500_open(const char *devpath, const char *requested_serial)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Flush out lingering data.
|
||||
*
|
||||
* The timeout apparently doesn't work on OS/X, and this loop
|
||||
* just hangs once the endpoint buffer empties.
|
||||
*/
|
||||
#ifndef __APPLE__
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) > 0);
|
||||
#endif
|
||||
usbtr_flush(&tr->base);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
|
@ -535,6 +535,25 @@ static int download_firmware(struct usb_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ti3410_flush(transport_t tr_base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti3410_set_modem(transport_t tr_base, transport_modem_t state)
|
||||
{
|
||||
printc_err("ti3410: unsupported operation: set_modem\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct transport_class ti3410_transport = {
|
||||
.destroy = ti3410_destroy,
|
||||
.send = ti3410_send,
|
||||
.recv = ti3410_recv,
|
||||
.flush = ti3410_flush,
|
||||
.set_modem = ti3410_set_modem
|
||||
};
|
||||
|
||||
transport_t ti3410_open(const char *devpath, const char *requested_serial)
|
||||
{
|
||||
struct ti3410_transport *tr = malloc(sizeof(*tr));
|
||||
|
@ -545,9 +564,7 @@ transport_t ti3410_open(const char *devpath, const char *requested_serial)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tr->base.destroy = ti3410_destroy;
|
||||
tr->base.send = ti3410_send;
|
||||
tr->base.recv = ti3410_recv;
|
||||
tr->base.ops = &ti3410_transport;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
|
@ -1,5 +1,5 @@
|
|||
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||
* Copyright (C) 2009, 2010 Daniel Beer
|
||||
* Copyright (C) 2009-2012 Daniel Beer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,18 +21,44 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/* This structure is used to provide an interface to a lower-level
|
||||
* transport. The transport mechanism is viewed as a stream by the FET
|
||||
* controller, which handles packet encapsulation, checksums and other
|
||||
* high-level functions.
|
||||
/* This structure is used to provide a consistent interface to a
|
||||
* lower-level serial-port type device.
|
||||
*/
|
||||
struct transport;
|
||||
typedef struct transport *transport_t;
|
||||
|
||||
struct transport {
|
||||
typedef enum {
|
||||
TRANSPORT_MODEM_DTR = 0x01,
|
||||
TRANSPORT_MODEM_RTS = 0x02
|
||||
} transport_modem_t;
|
||||
|
||||
struct transport_class {
|
||||
/* Close the port and free resources */
|
||||
void (*destroy)(transport_t tr);
|
||||
|
||||
/* Send a block of data. Returns 0 on success, or -1 if an error
|
||||
* occurs.
|
||||
*/
|
||||
int (*send)(transport_t tr, const uint8_t *data, int len);
|
||||
|
||||
/* Receive a block of data, up to the maximum size. Returns the
|
||||
* number of bytes received on success (which must be non-zero),
|
||||
* or -1 if an error occurs. Read timeouts are treated as
|
||||
* errors.
|
||||
*/
|
||||
int (*recv)(transport_t tr, uint8_t *data, int max_len);
|
||||
|
||||
/* Flush any lingering data in either direction. */
|
||||
int (*flush)(transport_t tr);
|
||||
|
||||
/* Set modem control lines. Returns 0 on success or -1 if an
|
||||
* error occurs.
|
||||
*/
|
||||
int (*set_modem)(transport_t tr, transport_modem_t state);
|
||||
};
|
||||
|
||||
struct transport {
|
||||
const struct transport_class *ops;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -75,6 +75,45 @@ static void serial_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
static int serial_flush(transport_t tr_base)
|
||||
{
|
||||
struct uif_transport *tr = (struct uif_transport *)tr_base;
|
||||
|
||||
if (sport_flush(tr->serial_fd) < 0) {
|
||||
pr_error("uif: flush failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_set_modem(transport_t tr_base, transport_modem_t state)
|
||||
{
|
||||
struct uif_transport *tr = (struct uif_transport *)tr_base;
|
||||
int bits = 0;
|
||||
|
||||
if (state & TRANSPORT_MODEM_DTR)
|
||||
bits |= SPORT_MC_DTR;
|
||||
|
||||
if (state & TRANSPORT_MODEM_RTS)
|
||||
bits |= SPORT_MC_RTS;
|
||||
|
||||
if (sport_set_modem(tr->serial_fd, bits) < 0) {
|
||||
pr_error("uif: failed to set modem control lines\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct transport_class uif_transport = {
|
||||
.destroy = serial_destroy,
|
||||
.send = serial_send,
|
||||
.recv = serial_recv,
|
||||
.flush = serial_flush,
|
||||
.set_modem = serial_set_modem
|
||||
};
|
||||
|
||||
transport_t uif_open(const char *device, uif_type_t type)
|
||||
{
|
||||
struct uif_transport *tr = malloc(sizeof(*tr));
|
||||
|
@ -84,9 +123,7 @@ transport_t uif_open(const char *device, uif_type_t type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tr->base.send = serial_send;
|
||||
tr->base.recv = serial_recv;
|
||||
tr->base.destroy = serial_destroy;
|
||||
tr->base.ops = &uif_transport;
|
||||
|
||||
switch (type) {
|
||||
case UIF_TYPE_FET:
|
Loading…
Reference in New Issue