patch #8504 buspirate: Also support "cpufreq" extended parameter in binary mode
* buspirate.c: applied patch + switch off at disable (even when a reset follows) + some general whitespace/tab cleanup git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1339 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
83ff6d306d
commit
58f509cb54
|
@ -1,3 +1,10 @@
|
|||
2014-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8504 buspirate: Also support "cpufreq" extended parameter
|
||||
in binary mode
|
||||
* buspirate.c: applied patch + switch off at disable (even when
|
||||
a reset follows) + some general whitespace/tab cleanup
|
||||
|
||||
2014-10-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37441: lockbits in ATxmega + avrdude = problem
|
||||
|
|
|
@ -1001,9 +1001,7 @@ This sets the AUX pin to output a frequency of
|
|||
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.)
|
||||
Make sure the CPU frequency is at least four times the SPI frequency.
|
||||
.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.
|
||||
|
|
116
buspirate.c
116
buspirate.c
|
@ -227,6 +227,7 @@ static char *buspirate_readline(struct programmer_t *pgm, char *buf, size_t len)
|
|||
static int buspirate_send(struct programmer_t *pgm, const char *str)
|
||||
{
|
||||
int rc;
|
||||
const char * readline;
|
||||
|
||||
avrdude_message(MSG_DEBUG, "%s: buspirate_send(): %s", progname, str);
|
||||
|
||||
|
@ -238,9 +239,13 @@ static int buspirate_send(struct programmer_t *pgm, const char *str)
|
|||
rc = serial_send(&pgm->fd, (const unsigned char*)str, strlen(str));
|
||||
if (rc)
|
||||
return rc;
|
||||
while (strcmp(buspirate_readline(pgm, NULL, 0), str) != 0)
|
||||
do {
|
||||
readline = buspirate_readline(pgm, NULL, 0);
|
||||
if (readline == NULL)
|
||||
return -1;
|
||||
/* keep reading until we get what we sent there */
|
||||
;
|
||||
} while (strcmp(readline, str) != 0);
|
||||
|
||||
/* by now we should be in sync */
|
||||
return 0;
|
||||
}
|
||||
|
@ -263,7 +268,9 @@ static int buspirate_expect(struct programmer_t *pgm, char *send,
|
|||
buspirate_send(pgm, send);
|
||||
while (1) {
|
||||
rcvd = buspirate_readline(pgm, NULL, 0);
|
||||
|
||||
if (rcvd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(rcvd, expect, expect_len) == 0) {
|
||||
if (! wait_for_prompt) {
|
||||
serial_drain(&pgm->fd, 0);
|
||||
|
@ -280,8 +287,7 @@ static int buspirate_expect(struct programmer_t *pgm, char *send,
|
|||
}
|
||||
|
||||
/* ====== Do-nothing functions ====== */
|
||||
static void buspirate_dummy_6(struct programmer_t *pgm,
|
||||
const char *p)
|
||||
static void buspirate_dummy_6(struct programmer_t *pgm, const char *p)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -293,8 +299,9 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
|||
const char *extended_param;
|
||||
char reset[10];
|
||||
char *preset = reset; /* for strtok() */
|
||||
int spifreq;
|
||||
int cpufreq;
|
||||
unsigned int spifreq;
|
||||
unsigned int rawfreq;
|
||||
unsigned int cpufreq;
|
||||
int serial_recv_timeout;
|
||||
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
|
@ -303,32 +310,38 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
|||
pgm->flag |= BP_FLAG_XPARM_FORCE_ASCII;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(extended_param, "spifreq=%d", &spifreq) == 1) {
|
||||
|
||||
if (sscanf(extended_param, "spifreq=%u", &spifreq) == 1) {
|
||||
if (spifreq & (~0x07)) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: spifreq must be between 0 and 7.\n");
|
||||
avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
|
||||
return -1;
|
||||
}
|
||||
pgm->flag = (pgm->flag & ~BP_FLAG_XPARM_RAWFREQ) |
|
||||
BP_FLAG_XPARM_SPIFREQ;
|
||||
if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
|
||||
return -1;
|
||||
}
|
||||
pgm->flag |= BP_FLAG_XPARM_SPIFREQ;
|
||||
PDATA(pgm)->spifreq = spifreq;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned rawfreq;
|
||||
if (sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) {
|
||||
if (rawfreq >= 4) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: rawfreq must be "
|
||||
"between 0 and 3.\n");
|
||||
return -1;
|
||||
}
|
||||
pgm->flag = (pgm->flag & ~BP_FLAG_XPARM_SPIFREQ) |
|
||||
BP_FLAG_XPARM_RAWFREQ;
|
||||
if (pgm->flag & BP_FLAG_XPARM_SPIFREQ) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
|
||||
return -1;
|
||||
}
|
||||
pgm->flag |= BP_FLAG_XPARM_RAWFREQ;
|
||||
PDATA(pgm)->spifreq = rawfreq;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(extended_param, "cpufreq=%d", &cpufreq) == 1) {
|
||||
if (sscanf(extended_param, "cpufreq=%u", &cpufreq) == 1) {
|
||||
/* lower limit comes from 'cpufreq > 4 * spifreq', spifreq in ascii mode is 30kHz. */
|
||||
if (cpufreq < 125 || cpufreq > 4000) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: cpufreq must be between 125 and 4000 kHz.\n");
|
||||
|
@ -368,6 +381,7 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
|||
pgm->flag |= BP_FLAG_NOPAGEDREAD;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) {
|
||||
if (serial_recv_timeout < 1) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: serial_recv_timeout must be greater 0.\n");
|
||||
|
@ -376,6 +390,9 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
|
|||
PDATA(pgm)->serial_recv_timeout = serial_recv_timeout;
|
||||
continue;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_INFO, "BusPirate: do not understand extended param '%s'.\n", extended_param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -393,17 +410,12 @@ buspirate_verifyconfig(struct programmer_t *pgm)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (( (pgm->flag & BP_FLAG_XPARM_SPIFREQ) ||
|
||||
(pgm->flag & BP_FLAG_XPARM_RAWFREQ) ) && buspirate_uses_ascii(pgm)) {
|
||||
if ( ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) || (pgm->flag & BP_FLAG_XPARM_RAWFREQ))
|
||||
&& buspirate_uses_ascii(pgm)) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((pgm->flag & BP_FLAG_XPARM_CPUFREQ) && !buspirate_uses_ascii(pgm)) {
|
||||
avrdude_message(MSG_INFO, "BusPirate: Setting cpufreq is only supported in ASCII mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -437,8 +449,21 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
|
|||
{
|
||||
unsigned char buf[10];
|
||||
|
||||
buf[0] = 0x00; /* BinMode: revert to HiZ */
|
||||
buf[0] = 0x00; /* BinMode: revert to raw bitbang mode */
|
||||
buspirate_send_bin(pgm, buf, 1);
|
||||
buspirate_recv_bin(pgm, buf, 5);
|
||||
|
||||
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
|
||||
/* disable pwm */
|
||||
if (buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) {
|
||||
avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
|
||||
}
|
||||
}
|
||||
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS
|
||||
* we want everything off -- 0b01000000 = 0x40 */
|
||||
if (buspirate_expect_bin_byte(pgm, 0x40, 0x00) == 1) {
|
||||
avrdude_message(MSG_INFO, "%s: warning: did not get a response to power off command.\n", progname);
|
||||
}
|
||||
|
||||
buf[0] = 0x0F; /* BinMode: reset */
|
||||
buspirate_send_bin(pgm, buf, 1);
|
||||
|
@ -474,6 +499,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
|||
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",
|
||||
|
@ -516,13 +542,35 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
|||
|
||||
pgm->flag |= BP_FLAG_IN_BINMODE;
|
||||
|
||||
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
|
||||
unsigned short pwm_duty;
|
||||
unsigned short pwm_period;
|
||||
|
||||
pwm_period = 16000/(PDATA(pgm)->cpufreq) - 1; // oscillator runs at 32MHz, we don't use a prescaler
|
||||
pwm_duty = pwm_period/2; // 50% duty cycle
|
||||
|
||||
avrdude_message(MSG_NOTICE, "Setting up PWM for cpufreq\n");
|
||||
avrdude_message(MSG_DEBUG, "PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period);
|
||||
|
||||
buf[0] = 0x12; // pwm setup
|
||||
buf[1] = 0; // prescaler 1
|
||||
buf[2] = (char) ((pwm_duty >> 8) & 0xff); // duty cycle register, high byte
|
||||
buf[3] = (char) pwm_duty & 0xff; // duty cycle register, low byte
|
||||
buf[4] = (char) ((pwm_period >> 8) & 0xff); // period register, high byte
|
||||
buf[5] = (char) pwm_period & 0xff; // period register, low byte
|
||||
buspirate_send_bin(pgm, buf, 6);
|
||||
|
||||
buspirate_recv_bin(pgm, buf, 1);
|
||||
if (buf[0] != 0x01)
|
||||
avrdude_message(MSG_INFO, "cpufreq (PWM) setup failed\n");
|
||||
}
|
||||
|
||||
/* == 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((const char*)buf, submode->entered_format,
|
||||
&PDATA(pgm)->submode_version) != 1) {
|
||||
if (sscanf((const char*)buf, submode->entered_format, &PDATA(pgm)->submode_version) != 1) {
|
||||
avrdude_message(MSG_INFO, "%s mode not confirmed: '%s'\n",
|
||||
submode->name, buf);
|
||||
buspirate_reset_from_binmode(pgm);
|
||||
|
@ -609,6 +657,9 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
|
|||
buspirate_send(pgm, "m\n");
|
||||
while(1) {
|
||||
rcvd = buspirate_readline(pgm, NULL, 0);
|
||||
if (rcvd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (spi_cmd == -1 && sscanf(rcvd, "%2d. %10s", &cmd, mode)) {
|
||||
if (strcmp(mode, "SPI") == 0)
|
||||
spi_cmd = cmd;
|
||||
|
@ -628,6 +679,9 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
|
|||
buf[0] = '\0';
|
||||
while (1) {
|
||||
rcvd = buspirate_readline(pgm, NULL, 0);
|
||||
if (rcvd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (strstr(rcvd, "Normal (H=3.3V, L=GND)")) {
|
||||
/* BP firmware 2.1 defaults to Open-drain output.
|
||||
* That doesn't work on my board, even with pull-up
|
||||
|
@ -724,8 +778,9 @@ static void buspirate_disable(struct programmer_t *pgm)
|
|||
if (pgm->flag & BP_FLAG_IN_BINMODE) {
|
||||
serial_recv_timeout = 100;
|
||||
buspirate_reset_from_binmode(pgm);
|
||||
} else
|
||||
} else {
|
||||
buspirate_expect(pgm, "#\n", "RESET", 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p)
|
||||
|
@ -741,7 +796,7 @@ static void buspirate_powerup(struct programmer_t *pgm)
|
|||
/* Powerup in BinMode is handled in binary mode init */
|
||||
return;
|
||||
} 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;
|
||||
|
@ -768,9 +823,7 @@ static void buspirate_powerup(struct programmer_t *pgm)
|
|||
static void buspirate_powerdown(struct programmer_t *pgm)
|
||||
{
|
||||
if (pgm->flag & BP_FLAG_IN_BINMODE) {
|
||||
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS
|
||||
* we want everything off -- 0b01000000 = 0x40 */
|
||||
if (buspirate_expect_bin_byte(pgm, 0x40, 0x01))
|
||||
/* Powerdown in BinMode is handled in binary mode init */
|
||||
return;
|
||||
} else {
|
||||
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
|
||||
|
@ -778,7 +831,7 @@ static void buspirate_powerdown(struct programmer_t *pgm)
|
|||
avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
|
||||
}
|
||||
}
|
||||
if (buspirate_expect(pgm, "w\n", "Power supplies OFF", 1))
|
||||
if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -816,6 +869,9 @@ static int buspirate_cmd_ascii(struct programmer_t *pgm,
|
|||
buspirate_send(pgm, buf);
|
||||
while (i < 4) {
|
||||
rcvd = buspirate_readline(pgm, NULL, 0);
|
||||
if (rcvd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* WRITE: 0xAC READ: 0x04 */
|
||||
if (sscanf(rcvd, "WRITE: 0x%2x READ: 0x%2x", &spi_write, &spi_read) == 2) {
|
||||
res[i++] = spi_read;
|
||||
|
|
|
@ -858,9 +858,7 @@ reason, this option disables it.
|
|||
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.)
|
||||
Make sure the CPU frequency is at least four times the SPI frequency.
|
||||
|
||||
@item @samp{serial_recv_timeout=@var{1...}}
|
||||
This sets the serial receive timeout to the given value.
|
||||
|
|
Loading…
Reference in New Issue