From 8ce134c04cbaf5560b5cd1bbba67458c99b1c927 Mon Sep 17 00:00:00 2001 From: Daniel Beer Date: Mon, 11 Jan 2010 16:54:36 +1300 Subject: [PATCH] Extracted general IO routines from UIF. --- bsl.c | 83 ++++++++++++++++++++++++++++++++--------------------- device.h | 2 +- main.c | 17 +++++------ transport.h | 5 ++++ uif.c | 66 +++++++----------------------------------- util.c | 66 ++++++++++++++++++++++++++++++++++++++++++ util.h | 4 +++ 7 files changed, 146 insertions(+), 97 deletions(-) diff --git a/bsl.c b/bsl.c index 0db07a1..c78d3ba 100644 --- a/bsl.c +++ b/bsl.c @@ -28,22 +28,7 @@ #include "device.h" #include "util.h" -static const struct fet_transport *trans; - -static int bufio_get_bytes(u_int8_t *data, int len) -{ - while (len) { - int r = trans->recv(data, len); - - if (r < 0) - return -1; - - data += r; - len -= r; - } - - return 0; -} +static int serial_fd; #define DATA_HDR 0x80 #define DATA_ACK 0x90 @@ -53,7 +38,7 @@ static int bsl_ack(void) { u_int8_t reply; - if (trans->recv(&reply, 1) < 0) { + if (read_with_timeout(serial_fd, &reply, 1) < 0) { fprintf(stderr, "bsl: failed to receive reply\n"); return -1; } @@ -76,10 +61,13 @@ static int bsl_sync(void) static const u_int8_t c = DATA_HDR; int tries = 2; - trans->flush(); + if (tcflush(serial_fd, TCIFLUSH) < 0) { + perror("bsl: tcflush"); + return -1; + } while (tries--) - if (!trans->send(&c, 1) && !bsl_ack()) + if (!(write_all(serial_fd, &c, 1) || bsl_ack())) return 0; fprintf(stderr, "bsl: sync failed\n"); @@ -120,7 +108,7 @@ static int send_command(int code, u_int16_t addr, pktbuf[pktlen + 4] = cklow; pktbuf[pktlen + 5] = ckhigh; - return trans->send(pktbuf, pktlen + 6); + return write_all(serial_fd, pktbuf, pktlen + 6); } static u_int8_t reply_buf[256]; @@ -152,7 +140,7 @@ static int fetch_reply(void) reply_len = 0; for (;;) { - int r = trans->recv(reply_buf + reply_len, + int r = read_with_timeout(serial_fd, reply_buf + reply_len, sizeof(reply_buf) - reply_len); if (r < 0) @@ -204,11 +192,8 @@ static int bsl_xfer(int command_code, u_int16_t addr, const u_int8_t *txdata, static void bsl_close(void) { - if (trans) { - bsl_xfer(CMD_RESET, 0, NULL, 0); - trans->close(); - trans = NULL; - } + bsl_xfer(CMD_RESET, 0, NULL, 0); + close(serial_fd); } static int bsl_control(device_ctl_t type) @@ -281,25 +266,57 @@ const static struct device bsl_device = { .readmem = bsl_readmem }; -const struct device *fet_open_bl(const struct fet_transport *tr) +#include + +static int enter_via_fet(void) { u_int8_t buf[16]; - - trans = tr; + u_int8_t *data = buf; + int len = 8; /* Enter bootloader command */ - if (trans->send((u_int8_t *)"\x7e\x24\x01\x9d\x5a\x7e", 6) < 0 || - bufio_get_bytes(buf, 8) < 0) { - fprintf(stderr, "bsl: failed to init bootloader\n"); - return NULL; + if (write_all(serial_fd, (u_int8_t *)"\x7e\x24\x01\x9d\x5a\x7e", 6)) { + fprintf(stderr, "bsl: couldn't write bootloader transition " + "command\n"); + return -1; } + /* Wait for reply */ + while (len) { + int r = read_with_timeout(serial_fd, data, len); + + if (r < 0) { + fprintf(stderr, "bsl: couldn't read bootloader " + "transition acknowledgement\n"); + return -1; + } + + data += r; + len -= r; + } + + /* Check that it's what we expect */ if (memcmp(buf, "\x06\x00\x24\x00\x00\x00\x61\x01", 8)) { fprintf(stderr, "bsl: bootloader start returned error %d\n", buf[5]); + return -1; + } + + return 0; +} + +const struct device *bsl_open(const char *device) +{ + serial_fd = open_serial(device, B460800); + if (serial_fd < 0) { + fprintf(stderr, "bsl: can't open %s: %s\n", + device, strerror(errno)); return NULL; } + if (enter_via_fet() < 0) + return NULL; + usleep(500000); /* Show chip info */ diff --git a/device.h b/device.h index 083056a..11cca94 100644 --- a/device.h +++ b/device.h @@ -52,7 +52,7 @@ const struct device *fet_open(const struct fet_transport *transport, int proto_flags, int vcc_mv); /* MSP430 FET Bootloader implementation. */ -const struct device *fet_open_bl(const struct fet_transport *transport); +const struct device *bsl_open(const char *device); /* Dummy/simulation implementation. */ const struct device *sim_open(void); diff --git a/main.c b/main.c index 7ff4d2d..c6e9733 100644 --- a/main.c +++ b/main.c @@ -624,7 +624,7 @@ static void usage(const char *progname) " Use JTAG, rather than spy-bi-wire (UIF devices only).\n" " -v voltage\n" " Set the supply voltage, in millivolts.\n" -" -B\n" +" -B device\n" " Debug the FET itself through the bootloader.\n" " -s\n" " Start in simulation mode (only memory IO is allowed).\n" @@ -640,10 +640,10 @@ int main(int argc, char **argv) { const struct fet_transport *trans; const char *uif_device = NULL; + const char *bsl_device = NULL; int opt; int flags = 0; int want_jtag = 0; - int want_bootloader = 0; int want_sim = 0; int vcc_mv = 3000; @@ -654,7 +654,7 @@ int main(int argc, char **argv) "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); /* Parse arguments */ - while ((opt = getopt(argc, argv, "u:jv:Bs")) >= 0) + while ((opt = getopt(argc, argv, "u:jv:B:s")) >= 0) switch (opt) { case 'u': uif_device = optarg; @@ -669,7 +669,7 @@ int main(int argc, char **argv) break; case 'B': - want_bootloader = 1; + bsl_device = optarg; break; case 's': @@ -684,22 +684,23 @@ int main(int argc, char **argv) /* Open a device */ if (want_sim) { msp430_dev = sim_open(); + } else if (bsl_device) { + msp430_dev = bsl_open(bsl_device); } else { /* Open the appropriate transport */ - if (uif_device) + if (uif_device) { trans = uif_open(uif_device); - else { + } else { trans = rf2500_open(); flags |= FET_PROTO_RF2500; } + if (!trans) return -1; /* Then initialize the device */ if (!want_jtag) flags |= FET_PROTO_SPYBIWIRE; - if (want_bootloader) - msp430_dev = fet_open_bl(trans); else msp430_dev = fet_open(trans, flags, vcc_mv); } diff --git a/transport.h b/transport.h index 7a95308..a8364b9 100644 --- a/transport.h +++ b/transport.h @@ -39,6 +39,11 @@ struct fet_transport { */ const struct fet_transport *uif_open(const char *device); +/* This function opens the bootstrap loader on a FET430UIF by using + * the TIUSB's modem control pins to generate the BSL entry sequence. + */ +const struct fet_transport *uif_open_bsl(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. diff --git a/uif.c b/uif.c index 74bf33b..fff02e7 100644 --- a/uif.c +++ b/uif.c @@ -21,10 +21,8 @@ #include #include #include -#include -#include -#include #include +#include #include "transport.h" #include "util.h" @@ -33,8 +31,6 @@ static int serial_fd = -1; static int serial_send(const u_int8_t *data, int len) { - int result; - assert (serial_fd >= 0); #ifdef DEBUG_SERIAL @@ -42,18 +38,9 @@ static int serial_send(const u_int8_t *data, int len) hexdump(0, data, len); #endif - while (len) { - result = write(serial_fd, data, len); - if (result < 0) { - if (errno == EINTR) - continue; - - perror("serial_send"); - return -1; - } - - data += result; - len -= result; + if (write_all(serial_fd, data, len) < 0) { + perror("uif: write error"); + return -1; } return 0; @@ -65,31 +52,11 @@ static int serial_recv(u_int8_t *data, int max_len) assert (serial_fd >= 0); - do { - struct timeval tv = { - .tv_sec = 5, - .tv_usec = 0 - }; - - fd_set set; - - FD_ZERO(&set); - FD_SET(serial_fd, &set); - - r = select(serial_fd + 1, &set, NULL, NULL, &tv); - if (r > 0) - r = read(serial_fd, data, max_len); - - if (r < 0 && errno != EINTR) { - perror("uif: read error"); - return -1; - } - - if (!r) { - fprintf(stderr, "uif: read timeout\n"); - return -1; - } - } while (r <= 0); + r = read_with_timeout(serial_fd, data, max_len); + if (r < 0) { + perror("uif: read error"); + return -1; + } #ifdef DEBUG_SERIAL puts("Serial transfer in:"); @@ -124,22 +91,11 @@ static const struct fet_transport serial_transport = { const struct fet_transport *uif_open(const char *device) { - struct termios attr; - printf("Trying to open UIF on %s...\n", device); - serial_fd = open(device, O_RDWR | O_NOCTTY); + serial_fd = open_serial(device, B460800); if (serial_fd < 0) { - fprintf(stderr, "uif: open: %s: %s\n", - device, strerror(errno)); - return NULL; - } - - tcgetattr(serial_fd, &attr); - cfmakeraw(&attr); - cfsetspeed(&attr, B460800); - if (tcsetattr(serial_fd, TCSAFLUSH, &attr) < 0) { - fprintf(stderr, "uif: tcsetattr: %s: %s\n", + fprintf(stderr, "uif: can't open serial device: %s: %s\n", device, strerror(errno)); return NULL; } diff --git a/util.c b/util.c index c255382..0575429 100644 --- a/util.c +++ b/util.c @@ -17,6 +17,11 @@ */ #include +#include +#include +#include +#include +#include #include "util.h" void hexdump(int addr, const u_int8_t *data, int len) @@ -74,3 +79,64 @@ void print_devid(u_int16_t id) else printf("Unknown device ID: 0x%04x\n", id); } + +int read_with_timeout(int fd, u_int8_t *data, int max_len) +{ + int r; + + do { + struct timeval tv = { + .tv_sec = 5, + .tv_usec = 0 + }; + + fd_set set; + + FD_ZERO(&set); + FD_SET(fd, &set); + + r = select(fd + 1, &set, NULL, NULL, &tv); + if (r > 0) + r = read(fd, data, max_len); + + if (!r) + errno = ETIMEDOUT; + if (r <= 0 && errno != EINTR) + return -1; + } while (r <= 0); + + return r; +} + +int write_all(int fd, const u_int8_t *data, int len) +{ + while (len) { + int result = write(fd, data, len); + + if (result < 0) { + if (errno == EINTR) + continue; + return -1; + } + + data += result; + len -= result; + } + + return 0; +} + +int open_serial(const char *device, int rate) +{ + int fd = open(device, O_RDWR | O_NOCTTY); + struct termios attr; + + tcgetattr(fd, &attr); + cfmakeraw(&attr); + cfsetspeed(&attr, rate); + + if (tcsetattr(fd, TCSAFLUSH, &attr) < 0) + return -1; + + return fd; +} diff --git a/util.h b/util.h index 491dff5..29045ae 100644 --- a/util.h +++ b/util.h @@ -27,4 +27,8 @@ void hexdump(int addr, const u_int8_t *data, int len); void print_devid(const u_int16_t id); +int open_serial(const char *device, int rate); +int read_with_timeout(int fd, u_int8_t *data, int len); +int write_all(int fd, const u_int8_t *data, int len); + #endif