patch #7437 modifications to Bus Pirate module
patch #7686 Updating buspirate ascii mode to current firmware, use AUX as clock generator, and setting of serial receive timeout * buspirate.c: added paged_write, changed binary mode setup/detection, added clock output on AUX pin * avrdude.1: updated documentation * doc/avrdude.texi: updated documentation git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1052 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
c1095de822
commit
fa5e2bb849
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||||
|
|
||||||
|
patch #7437 modifications to Bus Pirate module
|
||||||
|
patch #7686 Updating buspirate ascii mode to current firmware, use AUX
|
||||||
|
as clock generator, and setting of serial receive timeout
|
||||||
|
* buspirate.c: added paged_write, changed binary mode setup/detection,
|
||||||
|
added clock output on AUX pin
|
||||||
|
* avrdude.1: updated documentation
|
||||||
|
* doc/avrdude.texi: updated documentation
|
||||||
|
|
||||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||||
|
|
||||||
Parser does not need to know all programmer types now, new programmers
|
Parser does not need to know all programmer types now, new programmers
|
||||||
|
|
30
avrdude.1
30
avrdude.1
|
@ -882,7 +882,7 @@ each other using a 3-state bus buffer. For example 74HC125 or 74HC244 are some
|
||||||
good candidates with the latches driven by the appropriate reset pin (cs,
|
good candidates with the latches driven by the appropriate reset pin (cs,
|
||||||
aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
|
aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
|
||||||
with programming the AVR in the other design.
|
with programming the AVR in the other design.
|
||||||
.It Ar speed=<0..7>
|
.It Ar spifreq=<0..7>
|
||||||
BusPirate to AVR SPI speed:
|
BusPirate to AVR SPI speed:
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
0 .. 30 kHz (default)
|
0 .. 30 kHz (default)
|
||||||
|
@ -895,14 +895,36 @@ BusPirate to AVR SPI speed:
|
||||||
7 .. 8 MHz
|
7 .. 8 MHz
|
||||||
.Ed
|
.Ed
|
||||||
.It Ar ascii
|
.It Ar ascii
|
||||||
Use ASCII mode even when the firmware supports BinMode (binary mode).
|
Attempt to ASCII mode even when the firmware supports BinMode (binary mode).
|
||||||
BinMode is supported in firmware 2.7 and newer, older FW's either don't
|
BinMode is supported in firmware 2.7 and newer, older FW's either don't
|
||||||
have BinMode or their BinMode is buggy. ASCII mode is slower and makes
|
have BinMode or their BinMode is buggy. ASCII mode is slower and makes
|
||||||
the above
|
the above
|
||||||
.Ar reset=
|
.Ar reset=
|
||||||
and
|
and
|
||||||
.Ar speed=
|
.Ar spifreq=
|
||||||
parameters unavailable.
|
parameters unavailable. Be aware that ASCII mode is not guaranteed to work
|
||||||
|
with newer firmware versions, and is retained only to maintain compatability
|
||||||
|
with older firmware versions.
|
||||||
|
.It Ar nopagedwrite
|
||||||
|
Firmware versions 5.10 and newer support a binary mode SPI command that enables
|
||||||
|
whole pages to be written to AVR flash memory at once, resulting in a
|
||||||
|
significant write speed increase. If use of this mode is not desirable for some
|
||||||
|
reason, this option disables it.
|
||||||
|
.It Ar cpufreq=<125..4000>
|
||||||
|
This sets the AUX pin to output a frequency of
|
||||||
|
.Ar n
|
||||||
|
kHz. Connecting
|
||||||
|
the AUX pin to the XTAL1 pin of your MCU, you can provide it a clock,
|
||||||
|
for example when it needs an external clock because of wrong fuses settings.
|
||||||
|
This setting is only available in ASCII mode. (The lower limit was chosen so
|
||||||
|
the CPU frequency is at least for four times the SPI frequency which is in
|
||||||
|
ASCII mode 30kHz.)
|
||||||
|
.It Ar serial_recv_timeout=<1...>
|
||||||
|
This sets the serial receive timeout to the given value.
|
||||||
|
The timeout happens every time avrdude waits for the BusPirate prompt.
|
||||||
|
Especially in ascii mode this happens very often, so setting a smaller value
|
||||||
|
can speed up programming a lot.
|
||||||
|
The default value is 100ms. Using 10ms might work in most cases.
|
||||||
.El
|
.El
|
||||||
.It Ar Wiring
|
.It Ar Wiring
|
||||||
When using the Wiring programmer type, the
|
When using the Wiring programmer type, the
|
||||||
|
|
303
buspirate.c
303
buspirate.c
|
@ -29,6 +29,7 @@
|
||||||
* MOSI <-> MOSI
|
* MOSI <-> MOSI
|
||||||
* MISO <-> MISO
|
* MISO <-> MISO
|
||||||
* SCL/CLK <-> SCK
|
* SCL/CLK <-> SCK
|
||||||
|
* ( AUX <-> XTAL1 )
|
||||||
*
|
*
|
||||||
* Tested with BusPirate PTH, firmware version 2.1 programming ATmega328P
|
* Tested with BusPirate PTH, firmware version 2.1 programming ATmega328P
|
||||||
*/
|
*/
|
||||||
|
@ -61,6 +62,8 @@
|
||||||
#define BP_FLAG_XPARM_FORCE_ASCII (1<<1)
|
#define BP_FLAG_XPARM_FORCE_ASCII (1<<1)
|
||||||
#define BP_FLAG_XPARM_RESET (1<<2)
|
#define BP_FLAG_XPARM_RESET (1<<2)
|
||||||
#define BP_FLAG_XPARM_SPIFREQ (1<<3)
|
#define BP_FLAG_XPARM_SPIFREQ (1<<3)
|
||||||
|
#define BP_FLAG_NOPAGEDWRITE (1<<4)
|
||||||
|
#define BP_FLAG_XPARM_CPUFREQ (1<<5)
|
||||||
|
|
||||||
struct pdata
|
struct pdata
|
||||||
{
|
{
|
||||||
|
@ -70,26 +73,17 @@ struct pdata
|
||||||
int bin_spi_version;
|
int bin_spi_version;
|
||||||
int current_peripherals_config;
|
int current_peripherals_config;
|
||||||
int spifreq; /* 0..7 - see buspirate manual for what freq each value means */
|
int spifreq; /* 0..7 - see buspirate manual for what freq each value means */
|
||||||
|
int cpufreq; /* (125)..4000 kHz - see buspirate manual */
|
||||||
|
int serial_recv_timeout; /* timeout in ms, default 100 */
|
||||||
int reset; /* See BP_RESET_* above */
|
int reset; /* See BP_RESET_* above */
|
||||||
};
|
};
|
||||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||||
|
|
||||||
/* Binary mode is available from firmware v2.7 on */
|
|
||||||
#define FW_BINMODE_VER 207
|
|
||||||
|
|
||||||
/* ====== Feature checks ====== */
|
/* ====== Feature checks ====== */
|
||||||
static inline int
|
|
||||||
buspirate_has_aux2(struct programmer_t *pgm)
|
|
||||||
{
|
|
||||||
return ((PDATA(pgm)->fw_version >= 300) &&
|
|
||||||
strcmp(PDATA(pgm)->hw_version, "v1a") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
buspirate_uses_ascii(struct programmer_t *pgm)
|
buspirate_uses_ascii(struct programmer_t *pgm)
|
||||||
{
|
{
|
||||||
return (pgm->flag & BP_FLAG_XPARM_FORCE_ASCII) ||
|
return (pgm->flag & BP_FLAG_XPARM_FORCE_ASCII);
|
||||||
(PDATA(pgm)->fw_version < FW_BINMODE_VER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====== Serial talker functions - binmode ====== */
|
/* ====== Serial talker functions - binmode ====== */
|
||||||
|
@ -206,7 +200,7 @@ static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf_p++;
|
buf_p++;
|
||||||
serial_recv_timeout = 100;
|
serial_recv_timeout = PDATA(pgm)->serial_recv_timeout;
|
||||||
}
|
}
|
||||||
serial_recv_timeout = orig_serial_recv_timeout;
|
serial_recv_timeout = orig_serial_recv_timeout;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
@ -296,6 +290,8 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
||||||
char reset[10];
|
char reset[10];
|
||||||
char *preset = reset; /* for strtok() */
|
char *preset = reset; /* for strtok() */
|
||||||
int spifreq;
|
int spifreq;
|
||||||
|
int cpufreq;
|
||||||
|
int serial_recv_timeout;
|
||||||
|
|
||||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||||
extended_param = ldata(ln);
|
extended_param = ldata(ln);
|
||||||
|
@ -314,6 +310,18 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sscanf(extended_param, "cpufreq=%d", &cpufreq) == 1) {
|
||||||
|
/* lower limit comes from 'cpufreq > 4 * spifreq', spifreq in ascii mode is 30kHz. */
|
||||||
|
if (cpufreq < 125 || cpufreq > 4000) {
|
||||||
|
fprintf(stderr, "BusPirate: cpufreq must be between 125 and 4000 kHz.\n");
|
||||||
|
fprintf(stderr, "BusPirate: see BusPirate manual for details.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PDATA(pgm)->cpufreq = cpufreq;
|
||||||
|
pgm->flag |= BP_FLAG_XPARM_CPUFREQ;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (sscanf(extended_param, "reset=%s", reset) == 1) {
|
if (sscanf(extended_param, "reset=%s", reset) == 1) {
|
||||||
char *resetpin;
|
char *resetpin;
|
||||||
while ((resetpin = strtok(preset, ","))) {
|
while ((resetpin = strtok(preset, ","))) {
|
||||||
|
@ -332,6 +340,20 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
||||||
pgm->flag |= BP_FLAG_XPARM_RESET;
|
pgm->flag |= BP_FLAG_XPARM_RESET;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(extended_param, "nopagedwrite") == 0) {
|
||||||
|
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) {
|
||||||
|
if (serial_recv_timeout < 1) {
|
||||||
|
fprintf(stderr, "BusPirate: serial_recv_timeout must be greater 0.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PDATA(pgm)->serial_recv_timeout = serial_recv_timeout;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -344,15 +366,6 @@ buspirate_verifyconfig(struct programmer_t *pgm)
|
||||||
if (PDATA(pgm)->reset == 0x00)
|
if (PDATA(pgm)->reset == 0x00)
|
||||||
PDATA(pgm)->reset |= BP_RESET_CS;
|
PDATA(pgm)->reset |= BP_RESET_CS;
|
||||||
|
|
||||||
/* reset=AUX2 is only available on HW=v1a and FW>=3.0 */
|
|
||||||
if ((PDATA(pgm)->reset & BP_RESET_AUX2) && !buspirate_has_aux2(pgm)) {
|
|
||||||
fprintf(stderr, "BusPirate: Pin AUX2 is only available in binary mode\n");
|
|
||||||
fprintf(stderr, "BusPirate: with hardware==v1a && firmware>=3.0\n");
|
|
||||||
fprintf(stderr, "BusPirate: Your hardware==%s and firmware==%d.%d\n",
|
|
||||||
PDATA(pgm)->hw_version, PDATA(pgm)->fw_version/100, PDATA(pgm)->fw_version%100);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((PDATA(pgm)->reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) {
|
if ((PDATA(pgm)->reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) {
|
||||||
fprintf(stderr, "BusPirate: RESET pin other than CS is not supported in ASCII mode\n");
|
fprintf(stderr, "BusPirate: RESET pin other than CS is not supported in ASCII mode\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -363,6 +376,11 @@ buspirate_verifyconfig(struct programmer_t *pgm)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((pgm->flag & BP_FLAG_XPARM_CPUFREQ) && !buspirate_uses_ascii(pgm)) {
|
||||||
|
fprintf(stderr, "BusPirate: Setting cpufreq is only supported in ASCII mode\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,13 +477,37 @@ static int buspirate_start_spi_mode_bin(struct programmer_t *pgm)
|
||||||
fprintf(stderr, "BusPirate SPI version: %d\n",
|
fprintf(stderr, "BusPirate SPI version: %d\n",
|
||||||
PDATA(pgm)->bin_spi_version);
|
PDATA(pgm)->bin_spi_version);
|
||||||
|
|
||||||
|
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s: Paged flash write disabled.\n", progname);
|
||||||
|
} else {
|
||||||
|
/* Check for write-then-read without !CS/CS and disable paged_write if absent: */
|
||||||
|
strncpy(buf, "\x5\x0\x0\x0\x0", 5);
|
||||||
|
buspirate_send_bin(pgm, buf, 5);
|
||||||
|
buspirate_recv_bin(pgm, buf, 1);
|
||||||
|
if (buf[0] != 0x01) {
|
||||||
|
|
||||||
|
/* Disable paged write: */
|
||||||
|
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
|
||||||
|
|
||||||
|
/* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */
|
||||||
|
buf[0] = 0x1;
|
||||||
|
buspirate_send_bin(pgm, buf, 1);
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s: Disabling paged flash write. (Need BusPirate firmware >=v5.10.)\n", progname);
|
||||||
|
|
||||||
|
/* Flush serial buffer: */
|
||||||
|
serial_drain(&pgm->fd, 0);
|
||||||
|
} else {
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s: Paged flash write enabled.\n", progname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS
|
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS
|
||||||
* we want power (0x48) and all reset pins high. */
|
* we want power (0x48) and all reset pins high. */
|
||||||
PDATA(pgm)->current_peripherals_config = 0x48;
|
PDATA(pgm)->current_peripherals_config = 0x48 | PDATA(pgm)->reset;
|
||||||
PDATA(pgm)->current_peripherals_config |= BP_RESET_CS;
|
|
||||||
PDATA(pgm)->current_peripherals_config |= BP_RESET_AUX;
|
|
||||||
if (buspirate_has_aux2(pgm))
|
|
||||||
PDATA(pgm)->current_peripherals_config |= BP_RESET_AUX2;
|
|
||||||
buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01);
|
buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01);
|
||||||
usleep(50000); // sleep for 50ms after power up
|
usleep(50000); // sleep for 50ms after power up
|
||||||
|
|
||||||
|
@ -490,7 +532,7 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
|
||||||
int cmd;
|
int cmd;
|
||||||
char *rcvd, mode[11], buf[5];
|
char *rcvd, mode[11], buf[5];
|
||||||
|
|
||||||
buspirate_send(pgm, "M\n");
|
buspirate_send(pgm, "m\n");
|
||||||
while(1) {
|
while(1) {
|
||||||
rcvd = buspirate_readline(pgm, NULL, 0);
|
rcvd = buspirate_readline(pgm, NULL, 0);
|
||||||
if (spi_cmd == -1 && sscanf(rcvd, "%d. %10s", &cmd, mode)) {
|
if (spi_cmd == -1 && sscanf(rcvd, "%d. %10s", &cmd, mode)) {
|
||||||
|
@ -541,10 +583,30 @@ static void buspirate_enable(struct programmer_t *pgm)
|
||||||
unsigned char *reset_str = "#\n";
|
unsigned char *reset_str = "#\n";
|
||||||
unsigned char *accept_str = "y\n";
|
unsigned char *accept_str = "y\n";
|
||||||
char *rcvd;
|
char *rcvd;
|
||||||
int fw_v1 = 0, fw_v2 = 0;
|
|
||||||
int rc, print_banner = 0;
|
int rc, print_banner = 0;
|
||||||
|
|
||||||
fprintf(stderr, "Detecting BusPirate...\n");
|
/* Ensure configuration is self-consistant: */
|
||||||
|
if (buspirate_verifyconfig(pgm)<0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
/* Attempt to start binary SPI mode unless explicitly told otherwise: */
|
||||||
|
if (!buspirate_uses_ascii(pgm)) {
|
||||||
|
fprintf(stderr, "Attempting to initiate BusPirate binary mode...\n");
|
||||||
|
|
||||||
|
/* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */
|
||||||
|
buspirate_send_bin(pgm, "\n\n", 2);
|
||||||
|
|
||||||
|
/* Clear input buffer: */
|
||||||
|
serial_drain(&pgm->fd, 0);
|
||||||
|
|
||||||
|
/* Attempt to enter binary mode: */
|
||||||
|
if (buspirate_start_spi_mode_bin(pgm) >= 0)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s: Failed to start binary SPI mode, falling back to ASCII...\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Attempting to initiate BusPirate ASCII mode...\n");
|
||||||
|
|
||||||
/* Call buspirate_send_bin() instead of buspirate_send()
|
/* Call buspirate_send_bin() instead of buspirate_send()
|
||||||
* because we don't know if BP is in text or bin mode */
|
* because we don't know if BP is in text or bin mode */
|
||||||
|
@ -557,11 +619,8 @@ static void buspirate_enable(struct programmer_t *pgm)
|
||||||
while(1) {
|
while(1) {
|
||||||
rcvd = buspirate_readline_noexit(pgm, NULL, 0);
|
rcvd = buspirate_readline_noexit(pgm, NULL, 0);
|
||||||
if (! rcvd) {
|
if (! rcvd) {
|
||||||
fprintf(stderr, "BusPirate is not responding. Attempting reset.\n");
|
fprintf(stderr, "%s: Fatal: Programmer is not responding.\n", progname);
|
||||||
buspirate_reset_from_binmode(pgm);
|
exit(1);
|
||||||
/* re-run buspirate_enable() */
|
|
||||||
buspirate_enable(pgm);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (strncmp(rcvd, "Are you sure?", 13) == 0) {
|
if (strncmp(rcvd, "Are you sure?", 13) == 0) {
|
||||||
buspirate_send_bin(pgm, accept_str, strlen(accept_str));
|
buspirate_send_bin(pgm, accept_str, strlen(accept_str));
|
||||||
|
@ -574,27 +633,11 @@ static void buspirate_enable(struct programmer_t *pgm)
|
||||||
puts("**");
|
puts("**");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sscanf(rcvd, "Bus Pirate %9s", PDATA(pgm)->hw_version);
|
|
||||||
sscanf(rcvd, "Firmware v%d.%d", &fw_v1, &fw_v2);
|
|
||||||
if (print_banner)
|
if (print_banner)
|
||||||
fprintf(stderr, "** %s", rcvd);
|
fprintf(stderr, "** %s", rcvd);
|
||||||
}
|
}
|
||||||
|
|
||||||
PDATA(pgm)->fw_version = 100 * fw_v1 + fw_v2;
|
if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
|
||||||
if (PDATA(pgm)->hw_version[0] == 0 || PDATA(pgm)->fw_version == 0) {
|
|
||||||
fprintf(stderr, "BusPirate not detected. Aborting.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buspirate_verifyconfig(pgm) < 0)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if (PDATA(pgm)->fw_version >= FW_BINMODE_VER && !(pgm->flag & BP_FLAG_XPARM_FORCE_ASCII)) {
|
|
||||||
fprintf(stderr, "BusPirate: using BINARY mode\n");
|
|
||||||
if (buspirate_start_spi_mode_bin(pgm) < 0)
|
|
||||||
fprintf(stderr, "%s: Failed to start binary SPI mode\n", progname);
|
|
||||||
}
|
|
||||||
if (!pgm->flag & BP_FLAG_IN_BINMODE) {
|
|
||||||
fprintf(stderr, "BusPirate: using ASCII mode\n");
|
fprintf(stderr, "BusPirate: using ASCII mode\n");
|
||||||
if (buspirate_start_spi_mode_ascii(pgm) < 0) {
|
if (buspirate_start_spi_mode_ascii(pgm) < 0) {
|
||||||
fprintf(stderr, "%s: Failed to start ascii SPI mode\n", progname);
|
fprintf(stderr, "%s: Failed to start ascii SPI mode\n", progname);
|
||||||
|
@ -624,9 +667,26 @@ static void buspirate_powerup(struct programmer_t *pgm)
|
||||||
if (pgm->flag & BP_FLAG_IN_BINMODE) {
|
if (pgm->flag & BP_FLAG_IN_BINMODE) {
|
||||||
/* Powerup in BinMode is handled in SPI init */
|
/* Powerup in BinMode is handled in SPI init */
|
||||||
return;
|
return;
|
||||||
} else
|
} else {
|
||||||
if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1))
|
if (buspirate_expect(pgm, "W\n", "Power supplies ON", 1)) {
|
||||||
|
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
|
||||||
|
char buf[25];
|
||||||
|
int ok = 0;
|
||||||
|
snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq);
|
||||||
|
if (buspirate_expect(pgm, "g\n", "Frequency in KHz", 1)) {
|
||||||
|
if (buspirate_expect(pgm, buf, "Duty cycle in %", 1)) {
|
||||||
|
if (buspirate_expect(pgm, "50\n", "PWM active", 1)) {
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ok) {
|
||||||
|
fprintf(stderr, "%s: warning: did not get a response to start PWM command.\n", progname);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: warning: did not get a response to PowerUp command.\n", progname);
|
fprintf(stderr, "%s: warning: did not get a response to PowerUp command.\n", progname);
|
||||||
fprintf(stderr, "%s: warning: Trying to continue anyway...\n", progname);
|
fprintf(stderr, "%s: warning: Trying to continue anyway...\n", progname);
|
||||||
|
@ -639,9 +699,15 @@ static void buspirate_powerdown(struct programmer_t *pgm)
|
||||||
* we want everything off -- 0b01000000 = 0x40 */
|
* we want everything off -- 0b01000000 = 0x40 */
|
||||||
if (buspirate_expect_bin_byte(pgm, 0x40, 0x01))
|
if (buspirate_expect_bin_byte(pgm, 0x40, 0x01))
|
||||||
return;
|
return;
|
||||||
} else
|
} else {
|
||||||
if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1))
|
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
|
||||||
|
if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) {
|
||||||
|
fprintf(stderr, "%s: warning: did not get a response to stop PWM command.\n", progname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buspirate_expect(pgm, "w\n", "Power supplies OFF", 1))
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: warning: did not get a response to PowerDown command.\n", progname);
|
fprintf(stderr, "%s: warning: did not get a response to PowerDown command.\n", progname);
|
||||||
}
|
}
|
||||||
|
@ -704,6 +770,127 @@ static int buspirate_cmd(struct programmer_t *pgm,
|
||||||
return buspirate_cmd_ascii(pgm, cmd, res);
|
return buspirate_cmd_ascii(pgm, cmd, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */
|
||||||
|
static int buspirate_paged_write(struct programmer_t *pgm,
|
||||||
|
AVRPART *p,
|
||||||
|
AVRMEM *m,
|
||||||
|
unsigned int page_size,
|
||||||
|
unsigned int base_addr,
|
||||||
|
unsigned int n_data_bytes)
|
||||||
|
{
|
||||||
|
int page, i;
|
||||||
|
int addr = base_addr;
|
||||||
|
int n_page_writes;
|
||||||
|
int this_page_size;
|
||||||
|
char cmd_buf[4096] = {'\0'};
|
||||||
|
char send_byte, recv_byte;
|
||||||
|
|
||||||
|
if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
|
||||||
|
/* Return if we are not in binary mode. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
|
||||||
|
/* Return if we've nominated not to use paged writes. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page_size>1024) {
|
||||||
|
/* Page sizes greater than 1kB not yet supported. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(m->desc,"flash") != 0) {
|
||||||
|
/* Only flash memory currently supported. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pre-check opcodes */
|
||||||
|
if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s failure: %s command not defined for %s\n",
|
||||||
|
progname, "AVR_OP_LOADPAGE_LO", p->desc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (m->op[AVR_OP_LOADPAGE_HI] == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s failure: %s command not defined for %s\n",
|
||||||
|
progname, "AVR_OP_LOADPAGE_HI", p->desc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate total number of page writes needed: */
|
||||||
|
n_page_writes = n_data_bytes/page_size;
|
||||||
|
if (n_data_bytes%page_size >0)
|
||||||
|
n_page_writes++;
|
||||||
|
|
||||||
|
/* Ensure error LED is off: */
|
||||||
|
pgm->err_led(pgm, OFF);
|
||||||
|
|
||||||
|
/* Loop over pages: */
|
||||||
|
for (page=0; page<n_page_writes; page++) {
|
||||||
|
|
||||||
|
/* Determine bytes to write in this page: */
|
||||||
|
this_page_size = page_size;
|
||||||
|
if (page == n_page_writes-1)
|
||||||
|
this_page_size = n_data_bytes - page_size*page;
|
||||||
|
|
||||||
|
/* Set up command buffer: */
|
||||||
|
memset(cmd_buf, 0, 4*this_page_size);
|
||||||
|
for (i=0; i<this_page_size; i++) {
|
||||||
|
|
||||||
|
addr = base_addr + page*page_size + i;
|
||||||
|
|
||||||
|
if (i%2 == 0) {
|
||||||
|
avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]));
|
||||||
|
avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2);
|
||||||
|
avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]);
|
||||||
|
} else {
|
||||||
|
avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]));
|
||||||
|
avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2);
|
||||||
|
avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 00000100 - Write then read */
|
||||||
|
send_byte = 0x05;
|
||||||
|
buspirate_send_bin(pgm, &send_byte, 1);
|
||||||
|
|
||||||
|
/* Number of bytes to write: */
|
||||||
|
send_byte = (4*this_page_size)/0x100;
|
||||||
|
buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
|
||||||
|
send_byte = (4*this_page_size)%0x100;
|
||||||
|
buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */
|
||||||
|
|
||||||
|
/* Number of bytes to read: */
|
||||||
|
send_byte = 0x0;
|
||||||
|
buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
|
||||||
|
buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */
|
||||||
|
|
||||||
|
/* Set programming LED: */
|
||||||
|
pgm->pgm_led(pgm, ON);
|
||||||
|
|
||||||
|
/* Send command buffer: */
|
||||||
|
buspirate_send_bin(pgm, cmd_buf, 4*this_page_size);
|
||||||
|
|
||||||
|
/* Check for write failure: */
|
||||||
|
if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) {
|
||||||
|
fprintf(stderr, "BusPirate: Fatal error: Write Then Read did not succeed.\n");
|
||||||
|
pgm->pgm_led(pgm, OFF);
|
||||||
|
pgm->err_led(pgm, ON);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unset programming LED: */
|
||||||
|
pgm->pgm_led(pgm, OFF);
|
||||||
|
|
||||||
|
/* Write loaded page to flash: */
|
||||||
|
avr_write_page(pgm, p, m, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return n_data_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
|
static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
|
||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
|
@ -769,6 +956,7 @@ static void buspirate_setup(struct programmer_t *pgm)
|
||||||
progname);
|
progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
PDATA(pgm)->serial_recv_timeout = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buspirate_teardown(struct programmer_t *pgm)
|
static void buspirate_teardown(struct programmer_t *pgm)
|
||||||
|
@ -799,10 +987,11 @@ void buspirate_initpgm(struct programmer_t *pgm)
|
||||||
pgm->read_byte = avr_read_byte_default;
|
pgm->read_byte = avr_read_byte_default;
|
||||||
pgm->write_byte = avr_write_byte_default;
|
pgm->write_byte = avr_write_byte_default;
|
||||||
|
|
||||||
|
pgm->paged_write = buspirate_paged_write;
|
||||||
|
|
||||||
/* Support functions */
|
/* Support functions */
|
||||||
pgm->parseextparams = buspirate_parseextparms;
|
pgm->parseextparams = buspirate_parseextparms;
|
||||||
|
|
||||||
pgm->setup = buspirate_setup;
|
pgm->setup = buspirate_setup;
|
||||||
pgm->teardown = buspirate_teardown;
|
pgm->teardown = buspirate_teardown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -919,35 +919,51 @@ good candidates with the latches driven by the appropriate reset pin (cs,
|
||||||
aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
|
aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
|
||||||
with programming the AVR in the other design.
|
with programming the AVR in the other design.
|
||||||
|
|
||||||
@item @samp{speed=@var{0..7}}
|
@item @samp{spifreq=@var{0..7}}
|
||||||
@table @code
|
@multitable @columnfractions .05 .3
|
||||||
@item 0
|
@item @code{0} @tab 30 kHz (default)
|
||||||
30 kHz (default)
|
@item @code{1} @tab 125 kHz
|
||||||
@item 1
|
@item @code{2} @tab 250 kHz
|
||||||
125 kHz
|
@item @code{3} @tab 1 MHz
|
||||||
@item 2
|
@item @code{4} @tab 2 MHz
|
||||||
250 kHz
|
@item @code{5} @tab 2.6 MHz
|
||||||
@item 3
|
@item @code{6} @tab 4 MHz
|
||||||
1 MHz
|
@item @code{7} @tab 8 MHz
|
||||||
@item 4
|
@end multitable
|
||||||
2 MHz
|
|
||||||
@item 5
|
|
||||||
2.6 MHz
|
|
||||||
@item 6
|
|
||||||
4 MHz
|
|
||||||
@item 7
|
|
||||||
8 MHz
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item @samp{ascii}
|
@item @samp{ascii}
|
||||||
Use ASCII mode even when the firmware supports BinMode (binary mode).
|
Attempt to ASCII mode even when the firmware supports BinMode (binary mode).
|
||||||
BinMode is supported in firmware 2.7 and newer, older FW's either don't
|
BinMode is supported in firmware 2.7 and newer, older FW's either don't
|
||||||
have BinMode or their BinMode is buggy. ASCII mode is slower and makes
|
have BinMode or their BinMode is buggy. ASCII mode is slower and makes
|
||||||
the above
|
the above
|
||||||
@samp{reset=}
|
@samp{reset=}
|
||||||
and
|
and
|
||||||
@samp{speed=}
|
@samp{spifreq=}
|
||||||
parameters unavailable.
|
parameters unavailable. Be aware that ASCII mode is not guaranteed to work
|
||||||
|
with newer firmware versions, and is retained only to maintain compatability
|
||||||
|
with older firmware versions.
|
||||||
|
|
||||||
|
@item @samp{nopagedwrite}
|
||||||
|
Firmware versions 5.10 and newer support a binary mode SPI command that enables
|
||||||
|
whole pages to be written to AVR flash memory at once, resulting in a
|
||||||
|
significant write speed increase. If use of this mode is not desirable for some
|
||||||
|
reason, this option disables it.
|
||||||
|
|
||||||
|
@item @samp{cpufreq=@var{125..4000}}
|
||||||
|
This sets the @emph{AUX} pin to output a frequency of @var{n} kHz. Connecting
|
||||||
|
the @emph{AUX} pin to the XTAL1 pin of your MCU, you can provide it a clock,
|
||||||
|
for example when it needs an external clock because of wrong fuses settings.
|
||||||
|
This setting is only available in ASCII mode. (The lower limit was chosen so
|
||||||
|
the CPU frequency is at least for four times the SPI frequency which is in
|
||||||
|
ASCII mode 30kHz.)
|
||||||
|
|
||||||
|
@item @samp{serial_recv_timeout=@var{1...}}
|
||||||
|
This sets the serial receive timeout to the given value.
|
||||||
|
The timeout happens every time avrdude waits for the BusPirate prompt.
|
||||||
|
Especially in ascii mode this happens very often, so setting a smaller value
|
||||||
|
can speed up programming a lot.
|
||||||
|
The default value is 100ms. Using 10ms might work in most cases.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item Wiring
|
@item Wiring
|
||||||
|
|
Loading…
Reference in New Issue