Transports are now objects.

This commit is contained in:
Daniel Beer 2010-04-30 16:57:57 +12:00
parent 204aa31291
commit c981893254
8 changed files with 187 additions and 124 deletions

20
fet.c
View File

@ -35,7 +35,7 @@
struct fet_device {
struct device base;
const struct fet_transport *fet_transport;
transport_t transport;
int is_rf2500;
int version;
int have_breakpoint;
@ -195,7 +195,7 @@ static int send_rf2500_data(struct fet_device *dev,
pbuf[2] = offset >> 8;
pbuf[3] = plen;
memcpy(pbuf + 4, data, plen);
if (dev->fet_transport->send(pbuf, plen + 4) < 0)
if (dev->transport->send(dev->transport, pbuf, plen + 4) < 0)
return -1;
data += plen;
@ -388,9 +388,10 @@ static int recv_packet(struct fet_device *dev)
if (dev->fet_len >= plen + 2)
return parse_packet(dev, plen);
len = dev->fet_transport->recv(dev->fet_buf + dev->fet_len,
sizeof(dev->fet_buf) -
dev->fet_len);
len = dev->transport->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;
@ -474,7 +475,7 @@ static int send_command(struct fet_device *dev, int command_code,
assert (i < sizeof(buf));
return dev->fet_transport->send(buf, i);
return dev->transport->send(dev->transport, buf, i);
}
static int xfer(struct fet_device *dev,
@ -669,7 +670,7 @@ static void fet_destroy(device_t dev_base)
if (xfer(dev, C_CLOSE, NULL, 0, 1, 0) < 0)
fprintf(stderr, "fet: close command failed\n");
dev->fet_transport->close();
dev->transport->destroy(dev->transport);
free(dev);
}
@ -917,8 +918,7 @@ static int do_magic(struct fet_device *dev)
return 0;
}
device_t fet_open(const struct fet_transport *tr,
int proto_flags, int vcc_mv)
device_t fet_open(transport_t transport, int proto_flags, int vcc_mv)
{
struct fet_device *dev = malloc(sizeof(*dev));
@ -936,7 +936,7 @@ device_t fet_open(const struct fet_transport *tr,
dev->base.ctl = fet_ctl;
dev->base.poll = fet_poll;
dev->fet_transport = tr;
dev->transport = transport;
dev->is_rf2500 = proto_flags & FET_PROTO_RF2500;
dev->have_breakpoint = 0;

3
fet.h
View File

@ -26,7 +26,6 @@
#define FET_PROTO_SPYBIWIRE 0x01
#define FET_PROTO_RF2500 0x02
device_t fet_open(const struct fet_transport *transport,
int proto_flags, int vcc_mv);
device_t fet_open(transport_t transport, int proto_flags, int vcc_mv);
#endif

8
main.c
View File

@ -37,6 +37,9 @@
#include "bsl.h"
#include "fet.h"
#include "uif.h"
#include "rf2500.h"
static void io_prefix(const char *prefix, u_int16_t pc,
u_int16_t addr, int is_byte)
{
@ -230,7 +233,7 @@ static int parse_cmdline_args(int argc, char **argv,
device_t setup_device(const struct cmdline_args *args)
{
device_t msp430_dev = NULL;
const struct fet_transport *trans = NULL;
transport_t trans = NULL;
/* Open a device */
if (args->mode == MODE_SIM) {
@ -260,7 +263,7 @@ device_t setup_device(const struct cmdline_args *args)
if (!msp430_dev) {
if (trans)
trans->close();
trans->destroy(trans);
return NULL;
}
@ -315,7 +318,6 @@ int main(int argc, char **argv)
cp = setup_cproc(&args);
if (!cp) {
perror("couldn't set up command parser");
stab_exit();
return -1;
}

122
rf2500.c
View File

@ -20,9 +20,20 @@
#include <string.h>
#include <usb.h>
#include "transport.h"
#include "rf2500.h"
#include "util.h"
struct rf2500_transport {
struct transport base;
int int_number;
struct usb_dev_handle *handle;
u_int8_t buf[64];
int len;
int offset;
};
/*********************************************************************
* USB transport
*
@ -41,35 +52,34 @@
#define USB_FET_IN_EP 0x81
#define USB_FET_OUT_EP 0x01
static int usbtr_int_number;
static struct usb_dev_handle *usbtr_handle;
static int usbtr_open_interface(struct usb_device *dev, int ino)
static int open_interface(struct rf2500_transport *tr,
struct usb_device *dev, int ino)
{
printf("Trying to open interface %d on %s\n", ino, dev->filename);
usbtr_int_number = ino;
tr->int_number = ino;
usbtr_handle = usb_open(dev);
if (!usbtr_handle) {
tr->handle = usb_open(dev);
if (!tr->handle) {
perror("rf2500: can't open device");
return -1;
}
if (usb_detach_kernel_driver_np(usbtr_handle, usbtr_int_number) < 0)
if (usb_detach_kernel_driver_np(tr->handle, tr->int_number) < 0)
perror("rf2500: warning: can't "
"detach kernel driver");
if (usb_claim_interface(usbtr_handle, usbtr_int_number) < 0) {
if (usb_claim_interface(tr->handle, tr->int_number) < 0) {
perror("rf2500: can't claim interface");
usb_close(usbtr_handle);
usb_close(tr->handle);
return -1;
}
return 0;
}
static int usbtr_open_device(struct usb_device *dev)
static int open_device(struct rf2500_transport *tr,
struct usb_device *dev)
{
struct usb_config_descriptor *c = &dev->config[0];
int i;
@ -79,15 +89,17 @@ static int usbtr_open_device(struct usb_device *dev)
struct usb_interface_descriptor *desc = &intf->altsetting[0];
if (desc->bInterfaceClass == USB_FET_INTERFACE_CLASS &&
!usbtr_open_interface(dev, desc->bInterfaceNumber))
!open_interface(tr, dev, desc->bInterfaceNumber))
return 0;
}
return -1;
}
static int usbtr_send(const u_int8_t *data, int len)
static int usbtr_send(transport_t tr_base, const u_int8_t *data, int len)
{
struct rf2500_transport *tr = (struct rf2500_transport *)tr_base;
while (len) {
u_int8_t pbuf[256];
int plen = len > 255 ? 255 : len;
@ -109,7 +121,7 @@ static int usbtr_send(const u_int8_t *data, int len)
#ifdef DEBUG_USBTR
debug_hexdump("USB transfer out", pbuf, txlen);
#endif
if (usb_bulk_write(usbtr_handle, USB_FET_OUT_EP,
if (usb_bulk_write(tr->handle, USB_FET_OUT_EP,
(const char *)pbuf, txlen, 10000) < 0) {
perror("rf2500: can't send data");
return -1;
@ -122,68 +134,61 @@ static int usbtr_send(const u_int8_t *data, int len)
return 0;
}
static u_int8_t usbtr_buf[64];
static int usbtr_len;
static int usbtr_offset;
static int usbtr_flush(void)
{
char buf[64];
while (usb_bulk_read(usbtr_handle, USB_FET_IN_EP,
buf, sizeof(buf), 100) >= 0);
return 0;
}
static int usbtr_recv(u_int8_t *databuf, int max_len)
static int usbtr_recv(transport_t tr_base, u_int8_t *databuf, int max_len)
{
struct rf2500_transport *tr = (struct rf2500_transport *)tr_base;
int rlen;
if (usbtr_offset >= usbtr_len) {
if (usb_bulk_read(usbtr_handle, USB_FET_IN_EP,
(char *)usbtr_buf, sizeof(usbtr_buf),
if (tr->offset >= tr->len) {
if (usb_bulk_read(tr->handle, USB_FET_IN_EP,
(char *)tr->buf, sizeof(tr->buf),
10000) < 0) {
perror("rf2500: can't receive data");
return -1;
}
#ifdef DEBUG_USBTR
debug_hexdump("USB transfer in", usbtr_buf, 64);
debug_hexdump("USB transfer in", tr->buf, 64);
#endif
usbtr_len = usbtr_buf[1] + 2;
if (usbtr_len > sizeof(usbtr_buf))
usbtr_len = sizeof(usbtr_buf);
usbtr_offset = 2;
tr->len = tr->buf[1] + 2;
if (tr->len > sizeof(tr->buf))
tr->len = sizeof(tr->buf);
tr->offset = 2;
}
rlen = usbtr_len - usbtr_offset;
rlen = tr->len - tr->offset;
if (rlen > max_len)
rlen = max_len;
memcpy(databuf, usbtr_buf + usbtr_offset, rlen);
usbtr_offset += rlen;
memcpy(databuf, tr->buf + tr->offset, rlen);
tr->offset += rlen;
return rlen;
}
static void usbtr_close(void)
static void usbtr_destroy(transport_t tr_base)
{
usb_release_interface(usbtr_handle, usbtr_int_number);
usb_close(usbtr_handle);
struct rf2500_transport *tr = (struct rf2500_transport *)tr_base;
usb_release_interface(tr->handle, tr->int_number);
usb_close(tr->handle);
free(tr);
}
static const struct fet_transport usbtr_transport = {
.flush = usbtr_flush,
.send = usbtr_send,
.recv = usbtr_recv,
.close = usbtr_close
};
const struct fet_transport *rf2500_open(void)
transport_t rf2500_open(void)
{
struct rf2500_transport *tr = malloc(sizeof(*tr));
struct usb_bus *bus;
if (!tr) {
perror("rf2500: can't allocate memory");
return NULL;
}
tr->base.destroy = usbtr_destroy;
tr->base.send = usbtr_send;
tr->base.recv = usbtr_recv;
usb_init();
usb_find_busses();
usb_find_devices();
@ -194,13 +199,20 @@ const struct fet_transport *rf2500_open(void)
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == USB_FET_VENDOR &&
dev->descriptor.idProduct == USB_FET_PRODUCT &&
!usbtr_open_device(dev)) {
usbtr_flush();
return &usbtr_transport;
!open_device(tr, dev)) {
char buf[64];
/* Flush out lingering data */
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
buf, sizeof(buf),
100) >= 0);
return (transport_t)tr;
}
}
}
fprintf(stderr, "rf2500: no devices could be found\n");
free(tr);
return NULL;
}

30
rf2500.h Normal file
View File

@ -0,0 +1,30 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef RF2500_H_
#define RF2500_H_
#include "transport.h"
/* Search the USB bus for the first eZ430-RF2500, and initialize it. If
* successful, 0 is returned and the fet_* functions are ready for use.
* If an error occurs, -1 is returned.
*/
transport_t rf2500_open(void);
#endif

View File

@ -1,4 +1,4 @@
/* MSPDebug - debugging tool for the eZ430
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 Daniel Beer
*
* This program is free software; you can redistribute it and/or modify
@ -26,23 +26,13 @@
* controller, which handles packet encapsulation, checksums and other
* high-level functions.
*/
struct fet_transport {
int (*flush)(void);
int (*send)(const u_int8_t *data, int len);
int (*recv)(u_int8_t *data, int max_len);
void (*close)(void);
struct transport;
typedef struct transport *transport_t;
struct transport {
void (*destroy)(transport_t tr);
int (*send)(transport_t tr, const u_int8_t *data, int len);
int (*recv)(transport_t tr, u_int8_t *data, int max_len);
};
/* This function is for opening an eZ430-F2013 or FET430UIF device via
* a kernel-supported serial interface. The argument given should be the
* filename of the relevant tty device.
*/
const struct fet_transport *uif_open(const char *device);
/* Search the USB bus for the first eZ430-RF2500, and initialize it. If
* successful, 0 is returned and the fet_* functions are ready for use.
* If an error occurs, -1 is returned.
*/
const struct fet_transport *rf2500_open(void);
#endif

72
uif.c
View File

@ -17,6 +17,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
@ -24,20 +25,24 @@
#include <unistd.h>
#include <termios.h>
#include "transport.h"
#include "uif.h"
#include "util.h"
static int serial_fd = -1;
struct uif_transport {
struct transport base;
static int serial_send(const u_int8_t *data, int len)
int serial_fd;
};
static int serial_send(transport_t tr_base, const u_int8_t *data, int len)
{
assert (serial_fd >= 0);
struct uif_transport *tr = (struct uif_transport *)tr_base;
#ifdef DEBUG_SERIAL
debug_hexdump("Serial transfer out:", data, len);
#endif
if (write_all(serial_fd, data, len) < 0) {
if (write_all(tr->serial_fd, data, len) < 0) {
perror("uif: write error");
return -1;
}
@ -45,13 +50,12 @@ static int serial_send(const u_int8_t *data, int len)
return 0;
}
static int serial_recv(u_int8_t *data, int max_len)
static int serial_recv(transport_t tr_base, u_int8_t *data, int max_len)
{
struct uif_transport *tr = (struct uif_transport *)tr_base;
int r;
assert (serial_fd >= 0);
r = read_with_timeout(serial_fd, data, max_len);
r = read_with_timeout(tr->serial_fd, data, max_len);
if (r < 0) {
perror("uif: read error");
return -1;
@ -63,40 +67,36 @@ static int serial_recv(u_int8_t *data, int max_len)
return r;
}
static void serial_close(void)
static void serial_destroy(transport_t tr_base)
{
assert (serial_fd >= 0);
struct uif_transport *tr = (struct uif_transport *)tr_base;
close(serial_fd);
close(tr->serial_fd);
free(tr);
}
static int serial_flush(void)
transport_t uif_open(const char *device)
{
if (tcflush(serial_fd, TCIFLUSH) < 0) {
perror("uif: tcflush");
return -1;
}
struct uif_transport *tr = malloc(sizeof(*tr));
return 0;
}
static const struct fet_transport serial_transport = {
.flush = serial_flush,
.send = serial_send,
.recv = serial_recv,
.close = serial_close
};
const struct fet_transport *uif_open(const char *device)
{
printf("Trying to open UIF on %s...\n", device);
serial_fd = open_serial(device, B460800);
if (serial_fd < 0) {
fprintf(stderr, "uif: can't open serial device: %s: %s\n",
device, strerror(errno));
if (!tr) {
perror("uif: couldn't allocate memory");
return NULL;
}
return &serial_transport;
tr->base.send = serial_send;
tr->base.recv = serial_recv;
tr->base.destroy = serial_destroy;
printf("Trying to open UIF on %s...\n", device);
tr->serial_fd = open_serial(device, B460800);
if (tr->serial_fd < 0) {
fprintf(stderr, "uif: can't open serial device: %s: %s\n",
device, strerror(errno));
free(tr);
return NULL;
}
return (transport_t)tr;
}

30
uif.h Normal file
View File

@ -0,0 +1,30 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef UIF_H_
#define UIF_H_
#include "transport.h"
/* This function is for opening an eZ430-F2013 or FET430UIF device via
* a kernel-supported serial interface. The argument given should be the
* filename of the relevant tty device.
*/
transport_t uif_open(const char *device);
#endif