From f177b994be61142be9e6284c2eeed40bb763064c Mon Sep 17 00:00:00 2001 From: Rene Liebscher Date: Wed, 30 Jan 2013 17:58:48 +0000 Subject: [PATCH] =?UTF-8?q?patch=20#7723=20Bus=20Pirate=20=E2=80=9Craw-wir?= =?UTF-8?q?e=E2=80=9D=20mode=20which=20can=20run=20down=20to=205=20kHz=20?= =?UTF-8?q?=09*=20buspirate.c:=20added=20raw=20wire=20mode=20=09*=20avrdud?= =?UTF-8?q?e.1:=20added=20doc=20for=20rawfreq=20parameter=20=09*=20doc/avr?= =?UTF-8?q?dude.texi:=20added=20doc=20for=20rawfreq=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@1136 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avrdude/ChangeLog | 7 ++++ avrdude/avrdude.1 | 20 +++++++-- avrdude/buspirate.c | 91 ++++++++++++++++++++++++++++------------ avrdude/doc/avrdude.texi | 21 ++++++++-- 4 files changed, 106 insertions(+), 33 deletions(-) diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog index e014fb63..13ff069a 100644 --- a/avrdude/ChangeLog +++ b/avrdude/ChangeLog @@ -1,3 +1,10 @@ +2013-01-30 Rene Liebscher + + 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 bug #37977 Support for Openmoko Debug Board diff --git a/avrdude/avrdude.1 b/avrdude/avrdude.1 index 8fe1ae5f..a8789a93 100644 --- a/avrdude/avrdude.1 +++ b/avrdude/avrdude.1 @@ -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 with programming the AVR in the other design. .It Ar spifreq=<0..7> -BusPirate to AVR SPI speed: +The SPI speed for the Bus Pirate's binary SPI mode: .Bd -literal 0 .. 30 kHz (default) 1 .. 125 kHz @@ -918,14 +918,26 @@ BusPirate to AVR SPI speed: 6 .. 4 MHz 7 .. 8 MHz .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 -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 have BinMode or their BinMode is buggy. ASCII mode is slower and makes the above -.Ar reset= +.Ar reset= , spifreq= and -.Ar spifreq= +.Ar rawfreq= 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. diff --git a/avrdude/buspirate.c b/avrdude/buspirate.c index b5d98381..b1515c2c 100644 --- a/avrdude/buspirate.c +++ b/avrdude/buspirate.c @@ -64,15 +64,14 @@ #define BP_FLAG_XPARM_SPIFREQ (1<<3) #define BP_FLAG_NOPAGEDWRITE (1<<4) #define BP_FLAG_XPARM_CPUFREQ (1<<5) +#define BP_FLAG_XPARM_RAWFREQ (1<<6) struct pdata { - char hw_version[10]; - int fw_version; /* = 100*fw_major + fw_minor */ int binmode_version; - int bin_spi_version; + int submode_version; 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 serial_recv_timeout; /* timeout in ms, default 100 */ 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"); return -1; } + pgm->flag = (pgm->flag & ~BP_FLAG_XPARM_RAWFREQ) | + BP_FLAG_XPARM_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; } @@ -371,7 +384,8 @@ buspirate_verifyconfig(struct programmer_t *pgm) 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"); 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"); } -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' }; /* == 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; - /* == Enter SPI mode == */ - buf[0] = 0x01; /* Enter raw SPI mode */ + /* == Set protocol sub-mode of binary mode == */ + buf[0] = submode->enter; buspirate_send_bin(pgm, buf, 1); memset(buf, 0, sizeof(buf)); buspirate_recv_bin(pgm, buf, 4); - if (sscanf(buf, "SPI%d", &PDATA(pgm)->bin_spi_version) != 1) { - fprintf(stderr, "SPI mode not confirmed: '%s'\n", buf); + if (sscanf(buf, submode->entered_format, + &PDATA(pgm)->submode_version) != 1) { + fprintf(stderr, "%s mode not confirmed: '%s'\n", + submode->name, buf); buspirate_reset_from_binmode(pgm); return -1; } if (verbose) - fprintf(stderr, "BusPirate SPI version: %d\n", - PDATA(pgm)->bin_spi_version); + fprintf(stderr, "BusPirate %s version: %d\n", + submode->name, PDATA(pgm)->submode_version); if (pgm->flag & BP_FLAG_NOPAGEDWRITE) { 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); usleep(50000); // sleep for 50ms after power up - /* 01100xxx - SPI speed - * xxx = 000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz, - * 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz - * use 30kHz = 0x60 */ + /* 01100xxx - Set speed */ 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 - * we want: 3.3V(1), idle low(0), data change on trailing edge (1), - * sample in the middle of the pulse (0) - * => 0b10001010 = 0x8a */ - buspirate_expect_bin_byte(pgm, 0x8A, 0x01); + /* Submode config */ + buspirate_expect_bin_byte(pgm, submode->config, 0x01); return 0; } @@ -600,10 +639,10 @@ static void buspirate_enable(struct programmer_t *pgm) serial_drain(&pgm->fd, 0); /* Attempt to enter binary mode: */ - if (buspirate_start_spi_mode_bin(pgm) >= 0) + if (buspirate_start_mode_bin(pgm) >= 0) return; 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"); @@ -665,7 +704,7 @@ static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p) static void buspirate_powerup(struct programmer_t *pgm) { 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; } else { 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 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 */ if (!buspirate_expect_bin_byte(pgm, 0x13, 0x01)) return -1; diff --git a/avrdude/doc/avrdude.texi b/avrdude/doc/avrdude.texi index e28c50ae..fe2a90fe 100644 --- a/avrdude/doc/avrdude.texi +++ b/avrdude/doc/avrdude.texi @@ -805,14 +805,29 @@ with programming the AVR in the other design. @item @code{7} @tab 8 MHz @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} -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 have BinMode or their BinMode is buggy. ASCII mode is slower and makes the above -@samp{reset=} +@samp{reset=}, @samp{spifreq=} and -@samp{spifreq=} +@samp{rawfreq=} 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.