From b6e241a9e313c07bd359d56e91ad71f057f84620 Mon Sep 17 00:00:00 2001 From: Daniel Beer Date: Tue, 15 Mar 2011 14:20:06 +1300 Subject: [PATCH] Implemented uniform device constructor functions. --- bsl.c | 14 +++-- bsl.h | 2 +- device.h | 11 ++++ fet.c | 113 ++++++++++++++++++++++++++++++------- fet.h | 13 ++--- flash_bsl.c | 16 ++++-- flash_bsl.h | 2 +- main.c | 157 ++++++++-------------------------------------------- sim.c | 2 +- sim.h | 2 +- 10 files changed, 158 insertions(+), 174 deletions(-) diff --git a/bsl.c b/bsl.c index 3d92589..1d27847 100644 --- a/bsl.c +++ b/bsl.c @@ -361,10 +361,16 @@ static int enter_via_fet(struct bsl_device *dev) return 0; } -device_t bsl_open(const char *device) +device_t bsl_open(const struct device_args *args) { - struct bsl_device *dev = malloc(sizeof(*dev)); + struct bsl_device *dev; + if (!(args->flags & DEVICE_FLAG_TTY)) { + printc_err("This driver does not support raw USB access.\n"); + return NULL; + } + + dev = malloc(sizeof(*dev)); if (!dev) { pr_error("bsl: can't allocate memory"); return NULL; @@ -381,10 +387,10 @@ device_t bsl_open(const char *device) dev->base.ctl = bsl_ctl; dev->base.poll = bsl_poll; - dev->serial_fd = open_serial(device, B460800); + dev->serial_fd = open_serial(args->path, B460800); if (dev->serial_fd < 0) { printc_err("bsl: can't open %s: %s\n", - device, strerror(errno)); + args->path, strerror(errno)); free(dev); return NULL; } diff --git a/bsl.h b/bsl.h index 58f9a89..b5bd67f 100644 --- a/bsl.h +++ b/bsl.h @@ -22,6 +22,6 @@ #include "device.h" /* MSP430 FET Bootloader implementation. */ -device_t bsl_open(const char *devpath); +device_t bsl_open(const struct device_args *args); #endif diff --git a/device.h b/device.h index 3274fea..983d920 100644 --- a/device.h +++ b/device.h @@ -56,6 +56,17 @@ struct device_breakpoint { int flags; }; +#define DEVICE_FLAG_JTAG 0x01 /* default is SBW */ +#define DEVICE_FLAG_LONG_PW 0x02 +#define DEVICE_FLAG_TTY 0x04 /* default is USB */ + +struct device_args { + int flags; + int vcc_mv; + const char *path; + const char *forced_chip_id; +}; + struct device { /* Breakpoint table. This should not be modified directly. * Instead, you should use the device_setbrk() helper function. This diff --git a/fet.c b/fet.c index d299c2b..c371a3f 100644 --- a/fet.c +++ b/fet.c @@ -34,6 +34,16 @@ #include "output.h" #include "opdb.h" +#include "uif.h" +#include "olimex.h" +#include "rf2500.h" + +typedef enum { + PROTOCOL_UIF, + PROTOCOL_RF2500, + PROTOCOL_OLIMEX +} protocol_t; + #define MAX_PARAMS 16 #define MAX_BLOCK_SIZE 4096 @@ -41,7 +51,7 @@ struct fet_device { struct device base; transport_t transport; - int proto_flags; + protocol_t protocol; int version; /* Device-specific information */ @@ -324,7 +334,7 @@ too_short: */ static int recv_packet(struct fet_device *dev) { - int pkt_extra = (dev->proto_flags & FET_PROTO_OLIMEX) ? 3 : 2; + int pkt_extra = (dev->protocol == PROTOCOL_OLIMEX) ? 3 : 2; int plen = LE_WORD(dev->fet_buf, 0); /* If there's a packet still here from last time, get rid of it */ @@ -414,7 +424,7 @@ static int send_command(struct fet_device *dev, int command_code, /* Copy into buf, escaping special characters and adding * delimeters. */ - if (!(dev->proto_flags & FET_PROTO_OLIMEX)) + if (dev->protocol != PROTOCOL_OLIMEX) buf[i++] = 0x7e; for (j = 0; j < len; j++) { @@ -449,7 +459,7 @@ static int xfer(struct fet_device *dev, params[i] = va_arg(ap, uint32_t); va_end(ap); - if (data && (dev->proto_flags & FET_PROTO_RF2500)) { + if (data && (dev->protocol == PROTOCOL_RF2500)) { assert (nparams + 1 <= MAX_PARAMS); params[nparams++] = datalen; @@ -557,7 +567,7 @@ static int identify_new(struct fet_device *dev, const char *force_id) static int do_identify(struct fet_device *dev, const char *force_id) { - if (dev->proto_flags & FET_PROTO_OLIMEX) + if (dev->protocol == PROTOCOL_OLIMEX) return identify_new(dev, force_id); if (dev->version < 20300000) @@ -899,9 +909,10 @@ static int fet_setregs(device_t dev_base, const address_t *regs) return 0; } -static int do_configure(struct fet_device *dev) +static int do_configure(struct fet_device *dev, + const struct device_args *args) { - if (dev->proto_flags & FET_PROTO_SPYBIWIRE) { + if (!(args->flags & DEVICE_FLAG_JTAG)) { if (!xfer(dev, C_CONFIGURE, NULL, 0, 2, FET_CONFIG_PROTOCOL, 1)) { printc_dbg("Configured for Spy-Bi-Wire\n"); @@ -931,12 +942,12 @@ static int do_configure(struct fet_device *dev) return -1; } -int try_open(struct fet_device *dev, int proto_flags, int vcc_mv, - const char *force_id, int send_reset) +int try_open(struct fet_device *dev, const struct device_args *args, + protocol_t protocol, int send_reset) { transport_t transport = dev->transport; - if (proto_flags & FET_PROTO_OLIMEX) { + if (protocol == PROTOCOL_OLIMEX) { printc("Resetting Olimex command processor...\n"); transport->send(dev->transport, (const uint8_t *)"\x7e", 1); usleep(5000); @@ -958,7 +969,7 @@ int try_open(struct fet_device *dev, int proto_flags, int vcc_mv, return -1; } - if (do_configure(dev) < 0) + if (do_configure(dev, args) < 0) return -1; if (send_reset) { @@ -968,13 +979,13 @@ int try_open(struct fet_device *dev, int proto_flags, int vcc_mv, } /* set VCC */ - if (xfer(dev, C_VCC, NULL, 0, 1, vcc_mv) < 0) + if (xfer(dev, C_VCC, NULL, 0, 1, args->vcc_mv) < 0) printc_err("warning: fet: set VCC failed\n"); else - printc_dbg("Set Vcc: %d mV\n", vcc_mv); + printc_dbg("Set Vcc: %d mV\n", args->vcc_mv); /* Identify the chip */ - if (do_identify(dev, force_id) < 0) { + if (do_identify(dev, args->forced_chip_id) < 0) { printc_err("fet: identify failed\n"); return -1; } @@ -982,8 +993,8 @@ int try_open(struct fet_device *dev, int proto_flags, int vcc_mv, return 0; } -device_t fet_open(transport_t transport, int proto_flags, int vcc_mv, - const char *force_id) +device_t fet_open(const struct device_args *args, + protocol_t protocol, transport_t transport) { struct fet_device *dev = malloc(sizeof(*dev)); int i; @@ -1005,12 +1016,12 @@ device_t fet_open(transport_t transport, int proto_flags, int vcc_mv, dev->base.erase = fet_erase; dev->transport = transport; - dev->proto_flags = proto_flags; + dev->protocol = protocol; - if (try_open(dev, proto_flags, vcc_mv, force_id, 0) < 0) { + if (try_open(dev, args, protocol, 0) < 0) { usleep(500000); printc("Trying again...\n"); - if (try_open(dev, proto_flags, vcc_mv, force_id, 1) < 0) + if (try_open(dev, args, protocol, 1) < 0) goto fail; } @@ -1023,6 +1034,70 @@ device_t fet_open(transport_t transport, int proto_flags, int vcc_mv, return (device_t)dev; fail: + transport->destroy(transport); free(dev); return NULL; } + +device_t fet_open_rf2500(const struct device_args *args) +{ + transport_t trans; + + if (args->flags & DEVICE_FLAG_TTY) { + printc_err("This driver does not support TTY devices.\n"); + return NULL; + } + + trans = rf2500_open(args->path); + if (!trans) + return NULL; + + return fet_open(args, PROTOCOL_RF2500, trans); +} + +device_t fet_open_olimex(const struct device_args *args) +{ + transport_t trans; + + if (args->flags & DEVICE_FLAG_TTY) + trans = uif_open(args->path, UIF_TYPE_OLIMEX); + else + trans = olimex_open(args->path); + + if (!trans) + return NULL; + + return fet_open(args, PROTOCOL_OLIMEX, trans); +} + +device_t fet_open_olimex_iso(const struct device_args *args) +{ + transport_t trans; + + if (!(args->flags & DEVICE_FLAG_TTY)) { + printc_err("This driver does not support raw USB access.\n"); + return NULL; + } + + trans = uif_open(args->path, UIF_TYPE_OLIMEX_ISO); + if (!trans) + return NULL; + + return fet_open(args, PROTOCOL_OLIMEX, trans); +} + +device_t fet_open_uif(const struct device_args *args) +{ + transport_t trans; + + if (!(args->flags & DEVICE_FLAG_TTY)) { + printc_err("This driver does not support raw USB access.\n"); + return NULL; + } + + trans = uif_open(args->path, UIF_TYPE_FET); + if (!trans) + return NULL; + + return fet_open(args, PROTOCOL_UIF, trans); +} diff --git a/fet.h b/fet.h index 0a2baaf..52d64a9 100644 --- a/fet.h +++ b/fet.h @@ -20,14 +20,11 @@ #define FET_H_ #include "device.h" -#include "transport.h" -/* MSP430 FET protocol implementation. */ -#define FET_PROTO_SPYBIWIRE 0x01 -#define FET_PROTO_RF2500 0x02 -#define FET_PROTO_OLIMEX 0x04 - -device_t fet_open(transport_t transport, int proto_flags, int vcc_mv, - const char *force_id); +/* Open UIF devices and variants */ +device_t fet_open_rf2500(const struct device_args *args); +device_t fet_open_olimex(const struct device_args *args); +device_t fet_open_uif(const struct device_args *args); +device_t fet_open_olimex_iso(const struct device_args *args); #endif diff --git a/flash_bsl.c b/flash_bsl.c index e01e538..c71fb69 100644 --- a/flash_bsl.c +++ b/flash_bsl.c @@ -621,12 +621,18 @@ static void flash_bsl_destroy(device_t dev_base) free(dev); } -device_t flash_bsl_open(const char *device, int long_password) +device_t flash_bsl_open(const struct device_args *args) { - struct flash_bsl_device *dev = malloc(sizeof(*dev)); + struct flash_bsl_device *dev; uint8_t tx_bsl_version_command[] = { TX_BSL_VERSION }; uint8_t tx_bsl_version_response[5]; + if (!(args->flags & DEVICE_FLAG_TTY)) { + printc_err("This driver does not support raw USB access.\n"); + return NULL; + } + + dev = malloc(sizeof(*dev)); if (!dev) { pr_error("flash_bsl: can't allocate memory"); return NULL; @@ -646,15 +652,15 @@ device_t flash_bsl_open(const char *device, int long_password) dev->base.poll = flash_bsl_poll; dev->base.erase = flash_bsl_erase; - dev->serial_fd = open_serial_even_parity(device, B9600); + dev->serial_fd = open_serial_even_parity(args->path, B9600); if (dev->serial_fd < 0) { printc_err("flash_bsl: can't open %s: %s\n", - device, strerror(errno)); + args->path, strerror(errno)); free(dev); return NULL; } - dev->long_password = long_password; + dev->long_password = args->flags & DEVICE_FLAG_LONG_PW; /* enter bootloader */ if (enter_via_dtr_rts(dev) < 0) { diff --git a/flash_bsl.h b/flash_bsl.h index 8d38fde..9883a23 100644 --- a/flash_bsl.h +++ b/flash_bsl.h @@ -23,6 +23,6 @@ #include "device.h" /* MSP430 Flash bootloader implementation. */ -device_t flash_bsl_open(const char *devpath, int long_password); +device_t flash_bsl_open(const struct device_args *args); #endif diff --git a/main.c b/main.c index 790b88d..55c6c96 100644 --- a/main.c +++ b/main.c @@ -52,165 +52,51 @@ #include "rf2500.h" struct cmdline_args { - const char *driver_name; - const char *serial_device; - const char *usb_device; - const char *fet_force_id; - int want_jtag; - int no_rc; - int vcc_mv; - int long_password; + const char *driver_name; + int no_rc; + struct device_args devarg; }; struct driver { const char *name; const char *help; - device_t (*func)(const struct cmdline_args *args); + device_t (*func)(const struct device_args *args); }; -static device_t driver_open_fet(const struct cmdline_args *args, - int flags, transport_t trans) -{ - device_t dev; - - if (!args->want_jtag) - flags |= FET_PROTO_SPYBIWIRE; - - dev = fet_open(trans, flags, args->vcc_mv, args->fet_force_id); - if (!dev) { - trans->destroy(trans); - return NULL; - } - - return dev; -} - -static device_t driver_open_rf2500(const struct cmdline_args *args) -{ - transport_t trans; - - if (args->serial_device) { - printc_err("This driver does not support tty devices.\n"); - return NULL; - } - - trans = rf2500_open(args->usb_device); - if (!trans) - return NULL; - - return driver_open_fet(args, FET_PROTO_RF2500, trans); -} - -static device_t driver_open_olimex(const struct cmdline_args *args) -{ - transport_t trans; - - if (args->serial_device) - trans = uif_open(args->serial_device, UIF_TYPE_OLIMEX); - else - trans = olimex_open(args->usb_device); - - if (!trans) - return NULL; - - return driver_open_fet(args, FET_PROTO_OLIMEX, trans); -} - -static device_t driver_open_olimex_iso(const struct cmdline_args *args) -{ - transport_t trans; - - if (!args->serial_device) { - printc_err("This driver does not support USB access. " - "Specify a tty device using -d.\n"); - return NULL; - } - - trans = uif_open(args->serial_device, UIF_TYPE_OLIMEX_ISO); - if (!trans) - return NULL; - - return driver_open_fet(args, FET_PROTO_OLIMEX, trans); -} - -static device_t driver_open_sim(const struct cmdline_args *args) -{ - return sim_open(); -} - -static device_t driver_open_uif(const struct cmdline_args *args) -{ - transport_t trans; - - if (!args->serial_device) { - printc_err("This driver does not support USB access. " - "Specify a tty device using -d.\n"); - return NULL; - } - - trans = uif_open(args->serial_device, UIF_TYPE_FET); - if (!trans) - return NULL; - - return driver_open_fet(args, 0, trans); -} - -static device_t driver_open_uif_bsl(const struct cmdline_args *args) -{ - if (!args->serial_device) { - printc_err("This driver does not support USB access. " - "Specify a tty device using -d.\n"); - return NULL; - } - - return bsl_open(args->serial_device); -} - -static device_t driver_open_flash_bsl(const struct cmdline_args *args) -{ - if (!args->serial_device) { - printc_err("This driver does not support USB access. " - "Specify a tty device using -d.\n"); - return NULL; - } - - return flash_bsl_open(args->serial_device, args->long_password); -} - static const struct driver driver_table[] = { { .name = "rf2500", .help = "eZ430-RF2500 devices. Only USB connection is " "supported.", - driver_open_rf2500 + .func = fet_open_rf2500 }, { .name = "olimex", .help = "Olimex MSP-JTAG-TINY.", - .func = driver_open_olimex + .func = fet_open_olimex }, { .name = "olimex-iso", .help = "Olimex MSP-JTAG-ISO.", - .func = driver_open_olimex_iso + .func = fet_open_olimex_iso }, { .name = "sim", .help = "Simulation mode.", - .func = driver_open_sim + .func = sim_open }, { .name = "uif", .help = "TI FET430UIF and compatible devices (e.g. eZ430).", - .func = driver_open_uif + .func = fet_open_uif }, { .name = "uif-bsl", .help = "TI FET430UIF bootloader.", - .func = driver_open_uif_bsl + .func = bsl_open }, { .name = "flash-bsl", .help = "TI generic flash-based bootloader via RS-232", - .func = driver_open_flash_bsl + .func = flash_bsl_open } }; @@ -318,6 +204,7 @@ static int parse_cmdline_args(int argc, char **argv, {"long-password", 0, 0, 'P'}, {NULL, 0, 0, 0} }; + int want_usb = 0; while ((opt = getopt_long(argc, argv, "d:jv:nU:q", longopts, NULL)) >= 0) @@ -340,18 +227,20 @@ static int parse_cmdline_args(int argc, char **argv, exit(0); case 'd': - args->serial_device = optarg; + args->devarg.path = optarg; + args->devarg.flags |= DEVICE_FLAG_TTY; break; case 'U': - args->usb_device = optarg; + args->devarg.path = optarg; + want_usb = 1; break; case 'L': exit(list_devices()); case 'F': - args->fet_force_id = optarg; + args->devarg.forced_chip_id = optarg; break; case 'H': @@ -363,11 +252,11 @@ static int parse_cmdline_args(int argc, char **argv, exit(0); case 'v': - args->vcc_mv = atoi(optarg); + args->devarg.vcc_mv = atoi(optarg); break; case 'j': - args->want_jtag = 1; + args->devarg.flags |= DEVICE_FLAG_JTAG; break; case 'n': @@ -375,7 +264,7 @@ static int parse_cmdline_args(int argc, char **argv, break; case 'P': - args->long_password = 1; + args->devarg.flags |= DEVICE_FLAG_LONG_PW; break; case '?': @@ -383,7 +272,7 @@ static int parse_cmdline_args(int argc, char **argv, return -1; } - if (args->usb_device && args->serial_device) { + if (want_usb && (args->devarg.flags & DEVICE_FLAG_TTY)) { printc_err("You can't simultaneously specify a serial and " "a USB device.\n"); return -1; @@ -419,7 +308,7 @@ int setup_driver(struct cmdline_args *args) if (!stab_default) return -1; - device_default = driver_table[i].func(args); + device_default = driver_table[i].func(&args->devarg); if (!device_default) { stab_destroy(stab_default); return -1; @@ -435,7 +324,7 @@ int main(int argc, char **argv) opdb_reset(); - args.vcc_mv = 3000; + args.devarg.vcc_mv = 3000; if (parse_cmdline_args(argc, argv, &args) < 0) return -1; diff --git a/sim.c b/sim.c index a49e139..ce9a9c4 100644 --- a/sim.c +++ b/sim.c @@ -722,7 +722,7 @@ static device_status_t sim_poll(device_t dev_base) return DEVICE_STATUS_RUNNING; } -device_t sim_open(void) +device_t sim_open(const struct device_args *args) { struct sim_device *dev = malloc(sizeof(*dev)); diff --git a/sim.h b/sim.h index ed77204..8484411 100644 --- a/sim.h +++ b/sim.h @@ -22,6 +22,6 @@ #include "device.h" /* Dummy/simulation implementation. */ -device_t sim_open(void); +device_t sim_open(const struct device_args *args); #endif