flash_bsl: allow specification of custom entry/exit sequences.
This commit is contained in:
parent
2c7df22f4a
commit
4417bf82a7
|
@ -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 {
|
||||||
|
|
|
@ -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++);
|
||||||
|
|
||||||
|
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;
|
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;
|
return -1;
|
||||||
}
|
delay_ms(50);
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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).
|
||||||
|
|
12
ui/main.c
12
ui/main.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue