Added support for Olimex MSP430-JTAG-TINY.
This commit is contained in:
parent
ccc5df8fd9
commit
cf4ec417ff
4
AUTHORS
4
AUTHORS
|
@ -11,3 +11,7 @@ Robert Kavaler <kavaler@diva.com>:
|
||||||
|
|
||||||
Hans Nieuwenhuis <vzzbx@xs4all.nl>:
|
Hans Nieuwenhuis <vzzbx@xs4all.nl>:
|
||||||
* Support for MSP430F2132.
|
* Support for MSP430F2132.
|
||||||
|
|
||||||
|
Peter Jansen <pwjansen@yahoo.com>:
|
||||||
|
* Support for MSP430F169.
|
||||||
|
* Testing and analysis for Olimex MSP430-JTAG-TINY.
|
||||||
|
|
45
fet.c
45
fet.c
|
@ -38,7 +38,7 @@ struct fet_device {
|
||||||
struct device base;
|
struct device base;
|
||||||
|
|
||||||
transport_t transport;
|
transport_t transport;
|
||||||
int is_rf2500;
|
int proto_flags;
|
||||||
int version;
|
int version;
|
||||||
int have_breakpoint;
|
int have_breakpoint;
|
||||||
|
|
||||||
|
@ -314,15 +314,22 @@ too_short:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Receive a packet from the FET. The usual format is:
|
||||||
|
* <length (2 bytes)> <data> <checksum>
|
||||||
|
*
|
||||||
|
* The length is that of the data + checksum. Olimex JTAG adapters follow
|
||||||
|
* all packets with a trailing 0x7e byte, which must be discarded.
|
||||||
|
*/
|
||||||
static int recv_packet(struct fet_device *dev)
|
static int recv_packet(struct fet_device *dev)
|
||||||
{
|
{
|
||||||
|
int pkt_extra = (dev->proto_flags & FET_PROTO_OLIMEX) ? 3 : 2;
|
||||||
int plen = LE_WORD(dev->fet_buf, 0);
|
int plen = LE_WORD(dev->fet_buf, 0);
|
||||||
|
|
||||||
/* If there's a packet still here from last time, get rid of it */
|
/* If there's a packet still here from last time, get rid of it */
|
||||||
if (dev->fet_len >= plen + 2) {
|
if (dev->fet_len >= plen + pkt_extra) {
|
||||||
memmove(dev->fet_buf, dev->fet_buf + plen + 2,
|
memmove(dev->fet_buf, dev->fet_buf + plen + pkt_extra,
|
||||||
dev->fet_len - plen - 2);
|
dev->fet_len - plen - pkt_extra);
|
||||||
dev->fet_len -= plen + 2;
|
dev->fet_len -= plen + pkt_extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep adding data to the buffer until we have a complete packet */
|
/* Keep adding data to the buffer until we have a complete packet */
|
||||||
|
@ -330,7 +337,7 @@ static int recv_packet(struct fet_device *dev)
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
plen = LE_WORD(dev->fet_buf, 0);
|
plen = LE_WORD(dev->fet_buf, 0);
|
||||||
if (dev->fet_len >= plen + 2)
|
if (dev->fet_len >= plen + pkt_extra)
|
||||||
return parse_packet(dev, plen);
|
return parse_packet(dev, plen);
|
||||||
|
|
||||||
len = dev->transport->recv(dev->transport,
|
len = dev->transport->recv(dev->transport,
|
||||||
|
@ -405,7 +412,9 @@ static int send_command(struct fet_device *dev, int command_code,
|
||||||
/* Copy into buf, escaping special characters and adding
|
/* Copy into buf, escaping special characters and adding
|
||||||
* delimeters.
|
* delimeters.
|
||||||
*/
|
*/
|
||||||
buf[i++] = 0x7e;
|
if (!(dev->proto_flags & FET_PROTO_OLIMEX))
|
||||||
|
buf[i++] = 0x7e;
|
||||||
|
|
||||||
for (j = 0; j < len; j++) {
|
for (j = 0; j < len; j++) {
|
||||||
char c = datapkt[j];
|
char c = datapkt[j];
|
||||||
|
|
||||||
|
@ -438,7 +447,7 @@ static int xfer(struct fet_device *dev,
|
||||||
params[i] = va_arg(ap, unsigned int);
|
params[i] = va_arg(ap, unsigned int);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (data && dev->is_rf2500) {
|
if (data && (dev->proto_flags & FET_PROTO_RF2500)) {
|
||||||
assert (nparams + 1 <= MAX_PARAMS);
|
assert (nparams + 1 <= MAX_PARAMS);
|
||||||
params[nparams++] = datalen;
|
params[nparams++] = datalen;
|
||||||
|
|
||||||
|
@ -539,6 +548,9 @@ static int identify_new(struct fet_device *dev, const char *force_id)
|
||||||
|
|
||||||
static int do_identify(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)
|
||||||
|
return identify_new(dev, force_id);
|
||||||
|
|
||||||
if (dev->version < 20300000)
|
if (dev->version < 20300000)
|
||||||
return identify_old(dev);
|
return identify_old(dev);
|
||||||
|
|
||||||
|
@ -775,9 +787,9 @@ static int fet_breakpoint(device_t dev_base, int enabled, uint16_t addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_configure(struct fet_device *dev, int proto_flags)
|
static int do_configure(struct fet_device *dev)
|
||||||
{
|
{
|
||||||
if (proto_flags & FET_PROTO_SPYBIWIRE) {
|
if (dev->proto_flags & FET_PROTO_SPYBIWIRE) {
|
||||||
if (!xfer(dev, C_CONFIGURE, NULL, 0,
|
if (!xfer(dev, C_CONFIGURE, NULL, 0,
|
||||||
2, FET_CONFIG_PROTOCOL, 1)) {
|
2, FET_CONFIG_PROTOCOL, 1)) {
|
||||||
printf("Configured for Spy-Bi-Wire\n");
|
printf("Configured for Spy-Bi-Wire\n");
|
||||||
|
@ -827,11 +839,20 @@ device_t fet_open(transport_t transport, int proto_flags, int vcc_mv,
|
||||||
dev->base.poll = fet_poll;
|
dev->base.poll = fet_poll;
|
||||||
|
|
||||||
dev->transport = transport;
|
dev->transport = transport;
|
||||||
dev->is_rf2500 = proto_flags & FET_PROTO_RF2500;
|
dev->proto_flags = proto_flags;
|
||||||
dev->have_breakpoint = 0;
|
dev->have_breakpoint = 0;
|
||||||
|
|
||||||
dev->fet_len = 0;
|
dev->fet_len = 0;
|
||||||
|
|
||||||
|
if (proto_flags & FET_PROTO_OLIMEX) {
|
||||||
|
printf("Resetting Olimex command processor...\n");
|
||||||
|
transport->send(dev->transport, (const uint8_t *)"\x7e", 1);
|
||||||
|
usleep(5000);
|
||||||
|
transport->send(dev->transport, (const uint8_t *)"\x7e", 1);
|
||||||
|
usleep(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Initializing FET...\n");
|
||||||
if (xfer(dev, C_INITIALIZE, NULL, 0, 0) < 0) {
|
if (xfer(dev, C_INITIALIZE, NULL, 0, 0) < 0) {
|
||||||
fprintf(stderr, "fet: open failed\n");
|
fprintf(stderr, "fet: open failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -845,7 +866,7 @@ device_t fet_open(transport_t transport, int proto_flags, int vcc_mv,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_configure(dev, proto_flags) < 0)
|
if (do_configure(dev) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* set VCC */
|
/* set VCC */
|
||||||
|
|
1
fet.h
1
fet.h
|
@ -25,6 +25,7 @@
|
||||||
/* MSP430 FET protocol implementation. */
|
/* MSP430 FET protocol implementation. */
|
||||||
#define FET_PROTO_SPYBIWIRE 0x01
|
#define FET_PROTO_SPYBIWIRE 0x01
|
||||||
#define FET_PROTO_RF2500 0x02
|
#define FET_PROTO_RF2500 0x02
|
||||||
|
#define FET_PROTO_OLIMEX 0x04
|
||||||
|
|
||||||
device_t fet_open(transport_t transport, int proto_flags, int vcc_mv,
|
device_t fet_open(transport_t transport, int proto_flags, int vcc_mv,
|
||||||
const char *force_id);
|
const char *force_id);
|
||||||
|
|
33
main.c
33
main.c
|
@ -122,13 +122,16 @@ static void usage(const char *progname)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [options] -R [-v voltage] [command ...]\n"
|
"Usage: %s [options] -R [-v voltage] [command ...]\n"
|
||||||
" %s [options] -u <device> [-j] [-v voltage] [command ...]\n"
|
" %s [options] -u <device> [-j] [-v voltage] [command ...]\n"
|
||||||
|
" %s [options] -O <device> [-j] [-v voltage] [command ...]\n"
|
||||||
" %s [options] -B <device> [command ...]\n"
|
" %s [options] -B <device> [command ...]\n"
|
||||||
" %s [options] -s [command ...]\n"
|
" %s [options] -s [command ...]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -R\n"
|
" -R\n"
|
||||||
" Open the first available RF2500 device on the USB bus.\n"
|
" Open the first available RF2500 device on the USB bus.\n"
|
||||||
" -u device\n"
|
" -u device\n"
|
||||||
" Open the given tty device (MSP430 UIF compatible devices).\n"
|
" Open the given tty device (FET430UIF compatible devices).\n"
|
||||||
|
" -O device\n"
|
||||||
|
" Open the given tty device (Olimex MSP430-JTAG-TINY).\n"
|
||||||
" -j\n"
|
" -j\n"
|
||||||
" Use JTAG, rather than Spy-Bi-Wire (UIF devices only).\n"
|
" Use JTAG, rather than Spy-Bi-Wire (UIF devices only).\n"
|
||||||
" -v voltage\n"
|
" -v voltage\n"
|
||||||
|
@ -150,7 +153,7 @@ static void usage(const char *progname)
|
||||||
"\n"
|
"\n"
|
||||||
"If commands are given, they will be executed. Otherwise, an interactive\n"
|
"If commands are given, they will be executed. Otherwise, an interactive\n"
|
||||||
"command reader is started.\n",
|
"command reader is started.\n",
|
||||||
progname, progname, progname, progname);
|
progname, progname, progname, progname, progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_rc_file(cproc_t cp)
|
static void process_rc_file(cproc_t cp)
|
||||||
|
@ -170,10 +173,10 @@ static void process_rc_file(cproc_t cp)
|
||||||
#define MODE_UIF 0x02
|
#define MODE_UIF 0x02
|
||||||
#define MODE_UIF_BSL 0x04
|
#define MODE_UIF_BSL 0x04
|
||||||
#define MODE_SIM 0x08
|
#define MODE_SIM 0x08
|
||||||
|
#define MODE_OLIMEX 0x10
|
||||||
|
|
||||||
struct cmdline_args {
|
struct cmdline_args {
|
||||||
const char *uif_device;
|
const char *devpath;
|
||||||
const char *bsl_device;
|
|
||||||
const char *fet_force_id;
|
const char *fet_force_id;
|
||||||
int mode;
|
int mode;
|
||||||
int want_jtag;
|
int want_jtag;
|
||||||
|
@ -226,9 +229,14 @@ static int parse_cmdline_args(int argc, char **argv,
|
||||||
{NULL, 0, 0, 0}
|
{NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "u:jv:B:sR?n",
|
while ((opt = getopt_long(argc, argv, "u:jv:B:O:sR?n",
|
||||||
longopts, NULL)) >= 0)
|
longopts, NULL)) >= 0)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'O':
|
||||||
|
args->devpath = optarg;
|
||||||
|
args->mode |= MODE_OLIMEX;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
exit(list_devices());
|
exit(list_devices());
|
||||||
|
|
||||||
|
@ -245,7 +253,7 @@ static int parse_cmdline_args(int argc, char **argv,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
args->uif_device = optarg;
|
args->devpath = optarg;
|
||||||
args->mode |= MODE_UIF;
|
args->mode |= MODE_UIF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -258,7 +266,7 @@ static int parse_cmdline_args(int argc, char **argv,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
args->bsl_device = optarg;
|
args->devpath = optarg;
|
||||||
args->mode |= MODE_UIF_BSL;
|
args->mode |= MODE_UIF_BSL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -305,13 +313,16 @@ device_t setup_device(const struct cmdline_args *args,
|
||||||
if (args->mode == MODE_SIM) {
|
if (args->mode == MODE_SIM) {
|
||||||
msp430_dev = sim_open(fetch_io, store_io, stab);
|
msp430_dev = sim_open(fetch_io, store_io, stab);
|
||||||
} else if (args->mode == MODE_UIF_BSL) {
|
} else if (args->mode == MODE_UIF_BSL) {
|
||||||
msp430_dev = bsl_open(args->bsl_device);
|
msp430_dev = bsl_open(args->devpath);
|
||||||
} else if (args->mode == MODE_RF2500 || args->mode == MODE_UIF) {
|
} else {
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
/* Open the appropriate transport */
|
/* Open the appropriate transport */
|
||||||
if (args->mode == MODE_UIF) {
|
if (args->mode == MODE_OLIMEX) {
|
||||||
trans = uif_open(args->uif_device);
|
trans = uif_open(args->devpath, 1);
|
||||||
|
flags |= FET_PROTO_OLIMEX;
|
||||||
|
} else if (args->mode == MODE_UIF) {
|
||||||
|
trans = uif_open(args->devpath, 0);
|
||||||
} else {
|
} else {
|
||||||
trans = rf2500_open();
|
trans = rf2500_open();
|
||||||
flags |= FET_PROTO_RF2500;
|
flags |= FET_PROTO_RF2500;
|
||||||
|
|
|
@ -6,6 +6,8 @@ MSPDebug - debugging tool for MSP430 MCUs
|
||||||
.br
|
.br
|
||||||
\fBmspdebug\fR [options] \-u \fIdevice\fR [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
\fBmspdebug\fR [options] \-u \fIdevice\fR [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||||
.br
|
.br
|
||||||
|
\fBmspdebug\fR [options] \-O \fIdevice\fR [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||||
|
.br
|
||||||
\fBmspdebug\fR [options] \-B \fIdevice\fR [\fIcommand\fR ...]
|
\fBmspdebug\fR [options] \-B \fIdevice\fR [\fIcommand\fR ...]
|
||||||
.br
|
.br
|
||||||
\fBmspdebug\fR [options] \-s [\fIcommand\fR ...]
|
\fBmspdebug\fR [options] \-s [\fIcommand\fR ...]
|
||||||
|
@ -49,6 +51,9 @@ Connect to an eZ430-F2013 or a FET430UIF device. The device argument
|
||||||
should be the filename of the appropriate tty device. The TI serial
|
should be the filename of the appropriate tty device. The TI serial
|
||||||
converter chips on these devices are supported by newer versions of the
|
converter chips on these devices are supported by newer versions of the
|
||||||
Linux kernel, and should appear as /dev/tty\fIXX\fR when attached.
|
Linux kernel, and should appear as /dev/tty\fIXX\fR when attached.
|
||||||
|
.IP "\-O \fIdevice\fR"
|
||||||
|
Connect to an Olimex MSP430-JTAG-TINY device. The device argument
|
||||||
|
should be the filename of the appropriate tty device.
|
||||||
.IP "\-j"
|
.IP "\-j"
|
||||||
Use JTAG instead of Spy-Bi-Wire to communicate with the MSP430. This
|
Use JTAG instead of Spy-Bi-Wire to communicate with the MSP430. This
|
||||||
option only works on FET430UIF devices.
|
option only works on FET430UIF devices.
|
||||||
|
|
5
uif.c
5
uif.c
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define B460800 460800
|
#define B460800 460800
|
||||||
|
#define B500000 500000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct uif_transport {
|
struct uif_transport {
|
||||||
|
@ -79,7 +80,7 @@ static void serial_destroy(transport_t tr_base)
|
||||||
free(tr);
|
free(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
transport_t uif_open(const char *device)
|
transport_t uif_open(const char *device, int is_olimex)
|
||||||
{
|
{
|
||||||
struct uif_transport *tr = malloc(sizeof(*tr));
|
struct uif_transport *tr = malloc(sizeof(*tr));
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ transport_t uif_open(const char *device)
|
||||||
|
|
||||||
printf("Trying to open UIF on %s...\n", device);
|
printf("Trying to open UIF on %s...\n", device);
|
||||||
|
|
||||||
tr->serial_fd = open_serial(device, B460800);
|
tr->serial_fd = open_serial(device, is_olimex ? B500000 : B460800);
|
||||||
if (tr->serial_fd < 0) {
|
if (tr->serial_fd < 0) {
|
||||||
fprintf(stderr, "uif: can't open serial device: %s: %s\n",
|
fprintf(stderr, "uif: can't open serial device: %s: %s\n",
|
||||||
device, strerror(errno));
|
device, strerror(errno));
|
||||||
|
|
2
uif.h
2
uif.h
|
@ -25,6 +25,6 @@
|
||||||
* a kernel-supported serial interface. The argument given should be the
|
* a kernel-supported serial interface. The argument given should be the
|
||||||
* filename of the relevant tty device.
|
* filename of the relevant tty device.
|
||||||
*/
|
*/
|
||||||
transport_t uif_open(const char *device);
|
transport_t uif_open(const char *device, int is_olimex);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue