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 *forced_chip_id;
const char *requested_serial; const char *requested_serial;
const char *require_fwupdate; const char *require_fwupdate;
const char *bsl_entry_seq;
}; };
struct device_class { struct device_class {

View File

@ -35,6 +35,8 @@ struct flash_bsl_device {
sport_t serial_fd; sport_t serial_fd;
int long_password; int long_password;
const char *seq;
}; };
#define MAX_BLOCK 256 #define MAX_BLOCK 256
@ -547,72 +549,56 @@ static int flash_bsl_writemem(device_t dev_base,
return 0; return 0;
} }
static int do_pattern(sport_t fd, const char *seq)
static int enter_via_dtr_rts(struct flash_bsl_device *dev)
{ {
sport_t fd = dev->serial_fd; int state = 0;
int status = SPORT_MC_RTS;
if (sport_set_modem(fd, status) != 0) while (*seq && *seq != ':') {
{ const char c = *(seq++);
return -1;
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, state) < 0)
if (sport_set_modem(fd, status) != 0) return -1;
{ delay_ms(50);
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_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; return 0;
} }
static void exit_via_dtr_rts(struct flash_bsl_device *dev) 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 */ while (*seq && *seq != ':')
sport_set_modem(fd, SPORT_MC_RTS); seq++;
/* wait a brief period */ if (*seq == ':')
delay_ms(10); seq++;
/* RST# HIGH */ do_pattern(dev->serial_fd, seq);
sport_set_modem(fd, SPORT_MC_DTR | SPORT_MC_RTS);
} }
static void flash_bsl_destroy(device_t dev_base) 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; 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; dev->long_password = args->flags & DEVICE_FLAG_LONG_PW;
/* enter bootloader */ /* 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; goto fail;
}
delay_ms(500); delay_ms(500);

View File

@ -94,6 +94,11 @@ Show program version and copyright information.
.IP "\-\-embedded" .IP "\-\-embedded"
Start mspdebug as an embedded subprocess. See the documentation Start mspdebug as an embedded subprocess. See the documentation
accompanying the source release for more information on embedded mode. 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 .SH DRIVERS
For drivers supporting both USB and tty access, USB is the default, For drivers supporting both USB and tty access, USB is the default,
unless specified otherwise (see \fB-d\fR above). 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" " Show copyright and version information.\n"
" --embedded\n" " --embedded\n"
" Run in embedded mode.\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" "\n"
"Most drivers connect by default via USB, unless told otherwise via the\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" "-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_FORCE_RESET,
LOPT_ALLOW_FW_UPDATE, LOPT_ALLOW_FW_UPDATE,
LOPT_REQUIRE_FW_UPDATE, LOPT_REQUIRE_FW_UPDATE,
LOPT_EMBEDDED LOPT_EMBEDDED,
LOPT_BSL_ENTRY_SEQUENCE,
}; };
static const struct option longopts[] = { 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}, {"allow-fw-update", 0, 0, LOPT_ALLOW_FW_UPDATE},
{"require-fw-update", 1, 0, LOPT_REQUIRE_FW_UPDATE}, {"require-fw-update", 1, 0, LOPT_REQUIRE_FW_UPDATE},
{"embedded", 0, 0, LOPT_EMBEDDED}, {"embedded", 0, 0, LOPT_EMBEDDED},
{"bsl-entry-sequence", 1, 0, LOPT_BSL_ENTRY_SEQUENCE},
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
@ -277,6 +283,10 @@ static int parse_cmdline_args(int argc, char **argv,
} }
break; break;
case LOPT_BSL_ENTRY_SEQUENCE:
args->devarg.bsl_entry_seq = optarg;
break;
case LOPT_EMBEDDED: case LOPT_EMBEDDED:
args->flags |= OPT_EMBEDDED; args->flags |= OPT_EMBEDDED;
break; break;