Extracted general IO routines from UIF.

This commit is contained in:
Daniel Beer 2010-01-11 16:54:36 +13:00
parent 5a84cbf7f5
commit 8ce134c04c
7 changed files with 146 additions and 97 deletions

81
bsl.c
View File

@ -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;
}
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 <sys/ioctl.h>
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 */

View File

@ -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);

17
main.c
View File

@ -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);
}

View File

@ -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.

58
uif.c
View File

@ -21,10 +21,8 @@
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <termios.h>
#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,20 +38,11 @@ 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");
if (write_all(serial_fd, data, len) < 0) {
perror("uif: write error");
return -1;
}
data += result;
len -= result;
}
return 0;
}
@ -65,32 +52,12 @@ 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) {
r = read_with_timeout(serial_fd, data, max_len);
if (r < 0) {
perror("uif: read error");
return -1;
}
if (!r) {
fprintf(stderr, "uif: read timeout\n");
return -1;
}
} while (r <= 0);
#ifdef DEBUG_SERIAL
puts("Serial transfer in:");
hexdump(0, data, r);
@ -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;
}

66
util.c
View File

@ -17,6 +17,11 @@
*/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#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;
}

4
util.h
View File

@ -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