patch #7723 Bus Pirate “raw-wire” mode which can run down to 5 kHz

* buspirate.c: added raw wire mode
	* avrdude.1: added doc for rawfreq parameter
	* doc/avrdude.texi: added doc for rawfreq parameter

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1136 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Rene Liebscher 2013-01-30 17:58:48 +00:00
parent 2b25eba671
commit fa4ab4941f
4 changed files with 106 additions and 33 deletions

View File

@ -1,3 +1,10 @@
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
patch #7723 Bus Pirate “raw-wire” mode which can run down to 5 kHz
* buspirate.c: added raw wire mode
* avrdude.1: added doc for rawfreq parameter
* doc/avrdude.texi: added doc for rawfreq parameter
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de> 2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
bug #37977 Support for Openmoko Debug Board bug #37977 Support for Openmoko Debug Board

View File

@ -907,7 +907,7 @@ 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 spifreq=<0..7> .It Ar spifreq=<0..7>
BusPirate to AVR SPI speed: The SPI speed for the Bus Pirate's binary SPI mode:
.Bd -literal .Bd -literal
0 .. 30 kHz (default) 0 .. 30 kHz (default)
1 .. 125 kHz 1 .. 125 kHz
@ -918,14 +918,26 @@ BusPirate to AVR SPI speed:
6 .. 4 MHz 6 .. 4 MHz
7 .. 8 MHz 7 .. 8 MHz
.Ed .Ed
.It Ar rawfreq=<0..3>
Sets the SPI speed and uses the Bus Pirate's binary "raw-wire" mode:
.Bd -literal
0 .. 5 kHz
1 .. 50 kHz
2 .. 100 kHz (Firmware v4.2+ only)
3 .. 400 kHz (v4.2+)
.Ed
.Pp
The only advantage of the "raw-wire" mode is the different SPI frequencies
available. Paged writing is not implemented in this mode.
.It Ar ascii .It Ar ascii
Attempt to ASCII mode even when the firmware supports BinMode (binary mode). Attempt to use 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= , spifreq=
and and
.Ar spifreq= .Ar rawfreq=
parameters unavailable. Be aware that ASCII mode is not guaranteed to work parameters unavailable. Be aware that ASCII mode is not guaranteed to work
with newer firmware versions, and is retained only to maintain compatability with newer firmware versions, and is retained only to maintain compatability
with older firmware versions. with older firmware versions.

View File

@ -64,15 +64,14 @@
#define BP_FLAG_XPARM_SPIFREQ (1<<3) #define BP_FLAG_XPARM_SPIFREQ (1<<3)
#define BP_FLAG_NOPAGEDWRITE (1<<4) #define BP_FLAG_NOPAGEDWRITE (1<<4)
#define BP_FLAG_XPARM_CPUFREQ (1<<5) #define BP_FLAG_XPARM_CPUFREQ (1<<5)
#define BP_FLAG_XPARM_RAWFREQ (1<<6)
struct pdata struct pdata
{ {
char hw_version[10];
int fw_version; /* = 100*fw_major + fw_minor */
int binmode_version; int binmode_version;
int bin_spi_version; int submode_version;
int current_peripherals_config; int current_peripherals_config;
int spifreq; /* 0..7 - see buspirate manual for what freq each value means */ int spifreq; /* For "set speed" commands */
int cpufreq; /* (125)..4000 kHz - see buspirate manual */ int cpufreq; /* (125)..4000 kHz - see buspirate manual */
int serial_recv_timeout; /* timeout in ms, default 100 */ int serial_recv_timeout; /* timeout in ms, default 100 */
int reset; /* See BP_RESET_* above */ int reset; /* See BP_RESET_* above */
@ -305,8 +304,22 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
fprintf(stderr, "BusPirate: see BusPirate manual for details.\n"); fprintf(stderr, "BusPirate: see BusPirate manual for details.\n");
return -1; return -1;
} }
pgm->flag = (pgm->flag & ~BP_FLAG_XPARM_RAWFREQ) |
BP_FLAG_XPARM_SPIFREQ;
PDATA(pgm)->spifreq = spifreq; PDATA(pgm)->spifreq = spifreq;
pgm->flag |= BP_FLAG_XPARM_SPIFREQ; continue;
}
unsigned rawfreq;
if (sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) {
if (rawfreq >= 4) {
fprintf(stderr, "BusPirate: rawfreq must be "
"between 0 and 3.\n");
return -1;
}
pgm->flag = (pgm->flag & ~BP_FLAG_XPARM_SPIFREQ) |
BP_FLAG_XPARM_RAWFREQ;
PDATA(pgm)->spifreq = rawfreq;
continue; continue;
} }
@ -371,7 +384,8 @@ buspirate_verifyconfig(struct programmer_t *pgm)
return -1; return -1;
} }
if ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) && buspirate_uses_ascii(pgm)) { if (( (pgm->flag & BP_FLAG_XPARM_SPIFREQ) ||
(pgm->flag & BP_FLAG_XPARM_RAWFREQ) ) && buspirate_uses_ascii(pgm)) {
fprintf(stderr, "BusPirate: SPI speed selection is not supported in ASCII mode\n"); fprintf(stderr, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
return -1; return -1;
} }
@ -442,8 +456,37 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
fprintf(stderr, "BusPirate is back in the text mode\n"); fprintf(stderr, "BusPirate is back in the text mode\n");
} }
static int buspirate_start_spi_mode_bin(struct programmer_t *pgm) static int buspirate_start_mode_bin(struct programmer_t *pgm)
{ {
const struct submode {
const char *name; /* Name of mode for user messages */
char enter; /* Command to enter from base binary mode */
const char *entered_format; /* Response, for "scanf" */
char config; /* Command to setup submode parameters */
} *submode;
if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
submode = &(const struct submode){
.name = "Raw-wire",
.enter = 0x05,
.entered_format = "RAW%d",
.config = 0x8C,
};
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
} else {
submode = &(const struct submode){
.name = "SPI",
.enter = 0x01,
.entered_format = "SPI%d",
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
* we want: 3.3V(1), idle low(0), data change on
* trailing edge (1), sample in the middle
* of the pulse (0)
* => 0b10001010 = 0x8a */
.config = 0x8A,
};
}
char buf[20] = { '\0' }; char buf[20] = { '\0' };
/* == Switch to binmode - send 20x '\0' == */ /* == Switch to binmode - send 20x '\0' == */
@ -463,19 +506,21 @@ static int buspirate_start_spi_mode_bin(struct programmer_t *pgm)
pgm->flag |= BP_FLAG_IN_BINMODE; pgm->flag |= BP_FLAG_IN_BINMODE;
/* == Enter SPI mode == */ /* == Set protocol sub-mode of binary mode == */
buf[0] = 0x01; /* Enter raw SPI mode */ buf[0] = submode->enter;
buspirate_send_bin(pgm, buf, 1); buspirate_send_bin(pgm, buf, 1);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
buspirate_recv_bin(pgm, buf, 4); buspirate_recv_bin(pgm, buf, 4);
if (sscanf(buf, "SPI%d", &PDATA(pgm)->bin_spi_version) != 1) { if (sscanf(buf, submode->entered_format,
fprintf(stderr, "SPI mode not confirmed: '%s'\n", buf); &PDATA(pgm)->submode_version) != 1) {
fprintf(stderr, "%s mode not confirmed: '%s'\n",
submode->name, buf);
buspirate_reset_from_binmode(pgm); buspirate_reset_from_binmode(pgm);
return -1; return -1;
} }
if (verbose) if (verbose)
fprintf(stderr, "BusPirate SPI version: %d\n", fprintf(stderr, "BusPirate %s version: %d\n",
PDATA(pgm)->bin_spi_version); submode->name, PDATA(pgm)->submode_version);
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) { if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
if (verbose) if (verbose)
@ -511,17 +556,11 @@ static int buspirate_start_spi_mode_bin(struct programmer_t *pgm)
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
/* 01100xxx - SPI speed /* 01100xxx - Set speed */
* xxx = 000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz,
* 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz
* use 30kHz = 0x60 */
buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01); buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01);
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample /* Submode config */
* we want: 3.3V(1), idle low(0), data change on trailing edge (1), buspirate_expect_bin_byte(pgm, submode->config, 0x01);
* sample in the middle of the pulse (0)
* => 0b10001010 = 0x8a */
buspirate_expect_bin_byte(pgm, 0x8A, 0x01);
return 0; return 0;
} }
@ -600,10 +639,10 @@ static void buspirate_enable(struct programmer_t *pgm)
serial_drain(&pgm->fd, 0); serial_drain(&pgm->fd, 0);
/* Attempt to enter binary mode: */ /* Attempt to enter binary mode: */
if (buspirate_start_spi_mode_bin(pgm) >= 0) if (buspirate_start_mode_bin(pgm) >= 0)
return; return;
else else
fprintf(stderr, "%s: Failed to start binary SPI mode, falling back to ASCII...\n", progname); fprintf(stderr, "%s: Failed to start binary mode, falling back to ASCII...\n", progname);
} }
fprintf(stderr, "Attempting to initiate BusPirate ASCII mode...\n"); fprintf(stderr, "Attempting to initiate BusPirate ASCII mode...\n");
@ -665,7 +704,7 @@ static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p)
static void buspirate_powerup(struct programmer_t *pgm) 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 binary mode 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)) {
@ -716,7 +755,7 @@ static int buspirate_cmd_bin(struct programmer_t *pgm,
unsigned char cmd[4], unsigned char cmd[4],
unsigned char res[4]) unsigned char res[4])
{ {
/* 0001xxxx - Bulk SPI transfer, send/read 1-16 bytes (0=1byte!) /* 0001xxxx - Bulk transfer, send/read 1-16 bytes (0=1byte!)
* we are sending 4 bytes -> 0x13 */ * we are sending 4 bytes -> 0x13 */
if (!buspirate_expect_bin_byte(pgm, 0x13, 0x01)) if (!buspirate_expect_bin_byte(pgm, 0x13, 0x01))
return -1; return -1;

View File

@ -805,14 +805,29 @@ with programming the AVR in the other design.
@item @code{7} @tab 8 MHz @item @code{7} @tab 8 MHz
@end multitable @end multitable
@item @samp{rawfreq=0..3}
Sets the SPI speed and uses the Bus Pirate's binary ``raw-wire'' mode instead
of the default binary SPI mode:
@multitable @columnfractions .05 .3
@item @code{0} @tab 5 kHz
@item @code{1} @tab 50 kHz
@item @code{2} @tab 100 kHz (Firmware v4.2+ only)
@item @code{3} @tab 400 kHz (v4.2+)
@end multitable
The only advantage of the ``raw-wire'' mode is that different SPI frequencies
are available. Paged writing is not implemented in this mode.
@item @samp{ascii} @item @samp{ascii}
Attempt to ASCII mode even when the firmware supports BinMode (binary mode). Attempt to use 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=}, @samp{spifreq=}
and and
@samp{spifreq=} @samp{rawfreq=}
parameters unavailable. Be aware that ASCII mode is not guaranteed to work parameters unavailable. Be aware that ASCII mode is not guaranteed to work
with newer firmware versions, and is retained only to maintain compatability with newer firmware versions, and is retained only to maintain compatability
with older firmware versions. with older firmware versions.