flash_bsl: allow specification of custom entry/exit sequences.

This commit is contained in:
Daniel Beer 2014-04-02 12:37:43 +13:00
parent 2c7df22f4a
commit 4417bf82a7
4 changed files with 63 additions and 55 deletions

View File

@ -80,6 +80,7 @@ struct device_args {
const char *forced_chip_id;
const char *requested_serial;
const char *require_fwupdate;
const char *bsl_entry_seq;
};
struct device_class {

View File

@ -35,6 +35,8 @@ struct flash_bsl_device {
sport_t serial_fd;
int long_password;
const char *seq;
};
#define MAX_BLOCK 256
@ -547,72 +549,56 @@ static int flash_bsl_writemem(device_t dev_base,
return 0;
}
static int enter_via_dtr_rts(struct flash_bsl_device *dev)
static int do_pattern(sport_t fd, const char *seq)
{
sport_t fd = dev->serial_fd;
int status = SPORT_MC_RTS;
int state = 0;
if (sport_set_modem(fd, status) != 0)
{
return -1;
while (*seq && *seq != ':') {
const char c = *(seq++);
switch (c) {
case 'R':
state |= SPORT_MC_RTS;
break;
case 'r':
state &= ~SPORT_MC_RTS;
break;
case 'D':
state |= SPORT_MC_DTR;
break;
case 'd':
state &= ~SPORT_MC_DTR;
break;
case ',':
if (sport_set_modem(fd, state) < 0)
return -1;
delay_ms(50);
break;
}
}
delay_ms(250);
status &= ~SPORT_MC_RTS;
if (sport_set_modem(fd, status) != 0)
{
return -1;
}
delay_ms(10);
if (sport_set_modem(fd, state) < 0)
return -1;
delay_ms(50);
status |= SPORT_MC_RTS;
if (sport_set_modem(fd, status) != 0)
{
return -1;
}
delay_ms(10);
status &= ~SPORT_MC_RTS;
if (sport_set_modem(fd, status) != 0)
{
return -1;
}
delay_ms(10);
status |= SPORT_MC_RTS;
if (sport_set_modem(fd, status) != 0)
{
return -1;
}
delay_ms(10);
status |= SPORT_MC_DTR;
if (sport_set_modem(fd, status) != 0)
{
return -1;
}
delay_ms(10);
sport_flush(fd);
delay_ms(10);
/* BSL should now be running! */
return 0;
}
static void exit_via_dtr_rts(struct flash_bsl_device *dev)
{
sport_t fd = dev->serial_fd;
const char *seq = dev->seq;
/* Pulse RST# low */
sport_set_modem(fd, SPORT_MC_RTS);
while (*seq && *seq != ':')
seq++;
/* wait a brief period */
delay_ms(10);
if (*seq == ':')
seq++;
/* RST# HIGH */
sport_set_modem(fd, SPORT_MC_DTR | SPORT_MC_RTS);
do_pattern(dev->serial_fd, seq);
}
static void flash_bsl_destroy(device_t dev_base)
@ -656,11 +642,17 @@ static device_t flash_bsl_open(const struct device_args *args)
return NULL;
}
dev->seq = args->bsl_entry_seq;
if (!dev->seq)
dev->seq = "dR,r,R,r,R,D:dR,DR";
dev->long_password = args->flags & DEVICE_FLAG_LONG_PW;
/* enter bootloader */
if (enter_via_dtr_rts(dev) < 0)
if (do_pattern(dev->serial_fd, dev->seq) < 0) {
printc_err("BSL entry sequence failed\n");
goto fail;
}
delay_ms(500);

View File

@ -94,6 +94,11 @@ Show program version and copyright information.
.IP "\-\-embedded"
Start mspdebug as an embedded subprocess. See the documentation
accompanying the source release for more information on embedded mode.
.IP "\-\-bsl\-entry\-sequence \fIseq\fR"
Specify a BSL entry sequence. Each character specifies a modem control
line transition (R: RTS on, r: RTS off, D: DTR on, d: DTR off). A comma
indicates a delay. The entry and exit sequences are separated by a
colon. The default value is \fBdR,r,R,r,R,D:dR,DR\fR.
.SH DRIVERS
For drivers supporting both USB and tty access, USB is the default,
unless specified otherwise (see \fB-d\fR above).

View File

@ -142,6 +142,10 @@ static void usage(const char *progname)
" Show copyright and version information.\n"
" --embedded\n"
" Run in embedded mode.\n"
" --bsl-entry-sequence <seq>\n"
" Specify a BSL entry sequence. Each character specifies a modem\n"
" control line transition (R: RTS on, r: RTS off, D: DTR on, \n"
" d: DTR off).\n"
"\n"
"Most drivers connect by default via USB, unless told otherwise via the\n"
"-d option. By default, the first USB device found is opened.\n"
@ -239,7 +243,8 @@ static int parse_cmdline_args(int argc, char **argv,
LOPT_FORCE_RESET,
LOPT_ALLOW_FW_UPDATE,
LOPT_REQUIRE_FW_UPDATE,
LOPT_EMBEDDED
LOPT_EMBEDDED,
LOPT_BSL_ENTRY_SEQUENCE,
};
static const struct option longopts[] = {
@ -254,6 +259,7 @@ static int parse_cmdline_args(int argc, char **argv,
{"allow-fw-update", 0, 0, LOPT_ALLOW_FW_UPDATE},
{"require-fw-update", 1, 0, LOPT_REQUIRE_FW_UPDATE},
{"embedded", 0, 0, LOPT_EMBEDDED},
{"bsl-entry-sequence", 1, 0, LOPT_BSL_ENTRY_SEQUENCE},
{NULL, 0, 0, 0}
};
@ -277,6 +283,10 @@ static int parse_cmdline_args(int argc, char **argv,
}
break;
case LOPT_BSL_ENTRY_SEQUENCE:
args->devarg.bsl_entry_seq = optarg;
break;
case LOPT_EMBEDDED:
args->flags |= OPT_EMBEDDED;
break;