Submitted by John Voltz: add AVR053 oscillator calibration.

* main.c: Add the -O option.
* pgm.c: Add the hook for the perform_osccal() method.
* pgm.h: (Ditto.)
* stk500v2.c: Implement perform_osccal().
* avrdude.1: Document the -O option.
* doc/avrdude.texi: (Ditto.)
Partially closes bug #17487: AVR RC oscillator calibration
routine not supported (feature request)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@671 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2006-10-09 14:34:24 +00:00
parent 57028107ff
commit 2cfccda03d
7 changed files with 127 additions and 38 deletions

View File

@ -1,3 +1,15 @@
2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by John Voltz: add AVR053 oscillator calibration.
* main.c: Add the -O option.
* pgm.c: Add the hook for the perform_osccal() method.
* pgm.h: (Ditto.)
* stk500v2.c: Implement perform_osccal().
* avrdude.1: Document the -O option.
* doc/avrdude.texi: (Ditto.)
Partially closes bug #17487: AVR RC oscillator calibration
routine not supported (feature request)
2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by freckle@sf.net:

View File

@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE September 10, 2006
.Dd DATE October 9, 2006
.Os
.Dt AVRDUDE 1
.Sh NAME
@ -40,6 +40,7 @@
.Op Fl F
.Op Fl i Ar delay
.Op Fl n
.Op Fl O
.Op Fl P Ar port
.Op Fl q
.Op Fl s
@ -360,6 +361,12 @@ slow machines.
No-write - disables actually writing data to the MCU (useful for debugging
.Nm avrdude
).
.It Fl O
Perform a RC oscillator run-time calibration according to Atmel
application note AVR053.
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
hardware.
Note that the result will be stored in the EEPROM cell at address 0.
.It Fl P Ar port
Use
.Ar port

View File

@ -505,6 +505,13 @@ slow machines.
No-write - disables actually writing data to the MCU (useful for
debugging AVRDUDE).
@item -O
Perform a RC oscillator run-time calibration according to Atmel
application note AVR053.
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
hardware.
Note that the result will be stored in the EEPROM cell at address 0.
@item -P @var{port}
Use port to identify the device to which the programmer is attached.
Normally, the default parallel port is used, but if the programmer type

24
main.c
View File

@ -110,6 +110,7 @@ void usage(void)
" -P <port> Specify connection port.\n"
" -F Override invalid signature check.\n"
" -e Perform a chip erase.\n"
" -O Perform RC oscillator calibration (see AVR053). \n"
" -U <memtype>:r|w|v:<filename>[:format]\n"
" Memory operation specification.\n"
" Multiple -U options are allowed, each request\n"
@ -682,6 +683,7 @@ int main(int argc, char * argv [])
/* options / operating mode variables */
int erase; /* 1=erase chip, 0=don't */
int calibrate; /* 1=calibrate RC oscillator, 0=don't */
int auto_erase; /* 0=never erase unless explicity told to do
so, 1=erase if we are going to program flash */
char * port; /* device port (/dev/xxx) */
@ -739,6 +741,7 @@ int main(int argc, char * argv [])
partdesc = NULL;
port = default_parallel;
erase = 0;
calibrate = 0;
auto_erase = 1;
p = NULL;
ovsigck = 0;
@ -805,7 +808,7 @@ int main(int argc, char * argv [])
/*
* process command line arguments
*/
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:np:P:qstU:uvVyY:")) != -1) {
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:np:OP:qstU:uvVyY:")) != -1) {
switch (ch) {
case 'b': /* override default programmer baud rate */
@ -864,6 +867,10 @@ int main(int argc, char * argv [])
nowrite = 1;
break;
case 'O': /* perform RC oscillator calibration */
calibrate = 1;
break;
case 'p' : /* specify AVR part */
partdesc = optarg;
break;
@ -1151,6 +1158,21 @@ int main(int argc, char * argv [])
goto main_exit;
}
if (calibrate) {
/*
* perform an RC oscillator calibration
* as outlined in appnote AVR053
*/
fprintf(stderr, "%s: performing RC oscillator calibration\n", progname);
exitrc = pgm->perform_osccal(pgm);
if (exitrc == 0 && quell_progress < 2) {
fprintf(stderr,
"%s: calibration value is now stored in EEPROM at address 0\n",
progname);
}
goto main_exit;
}
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");

1
pgm.c
View File

@ -123,6 +123,7 @@ PROGRAMMER * pgm_new(void)
pgm->set_vtarget = NULL;
pgm->set_varef = NULL;
pgm->set_fosc = NULL;
pgm->perform_osccal = NULL;
return pgm;
}

1
pgm.h
View File

@ -100,6 +100,7 @@ typedef struct programmer_t {
int (*getpin) (struct programmer_t * pgm, int pin);
int (*highpulsepin) (struct programmer_t * pgm, int pin);
int (*parseexitspecs) (struct programmer_t * pgm, char *s);
int (*perform_osccal) (struct programmer_t * pgm);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
char flag; /* for private use of the programmer */

View File

@ -329,7 +329,7 @@ static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char msg[],
return -1;
}
memcpy(msg, jtagmsg + 1, rv - 1);
return 0;
return rv;
}
static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize) {
@ -524,8 +524,8 @@ retry:
return 0;
}
static int stk500v2_command
(PROGRAMMER * pgm, unsigned char * buf, size_t len, size_t maxlen) {
static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf,
size_t len, size_t maxlen) {
int i;
int tries = 0;
int status;
@ -539,14 +539,24 @@ retry:
// send the command to the programmer
stk500v2_send(pgm,buf,len);
// attempt to read the status back
status = stk500v2_recv(pgm,buf,maxlen);
// if we got a successful readback, return
if (status > 0) {
DEBUG(" = %d\n",status);
return status;
if (status < 2) {
fprintf(stderr, "%s: stk500v2_command(): short reply\n", progname);
return -1;
}
if (buf[1] == STATUS_CMD_OK)
return status;
if (buf[1] == STATUS_CMD_FAILED)
fprintf(stderr, "%s: stk500v2_command(): command failed\n", progname);
else
fprintf(stderr, "%s: stk500v2_command(): unknown status 0x%02x\n",
progname, buf[1]);
return -1;
}
// otherwise try to sync up again
@ -582,10 +592,14 @@ static int stk500v2_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
buf[7] = cmd[3];
result = stk500v2_command(pgm, buf, 8, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
if (result < 0) {
fprintf(stderr, "%s: stk500v2_cmd(): failed to send command\n",
progname);
return -1;
} else if (result < 6) {
fprintf(stderr, "%s: stk500v2_cmd(): short reply, len = %d\n",
progname, result);
return -1;
}
res[0] = buf[2];
@ -782,11 +796,11 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
result = stk500v2_command(pgm, buf, CTL_STACK_SIZE + 1, sizeof(buf));
if (result < 0 || buf[1] != STATUS_CMD_OK) {
if (result < 0) {
fprintf(stderr,
"%s: stk500pp_initalize(): "
"failed to set control stack, got 0x%02x\n",
progname, buf[1]);
"failed to set control stack\n",
progname);
return -1;
}
@ -852,9 +866,10 @@ static void stk500v2_disable(PROGRAMMER * pgm)
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_disable(): failed to leave programming mode, got 0x%02x\n",
progname,buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500v2_disable(): failed to leave programming mode\n",
progname);
}
return;
@ -879,11 +894,11 @@ static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
if (result < 0 || buf[1] != STATUS_CMD_OK) {
if (result < 0) {
fprintf(stderr,
"%s: stk500hv_disable(): "
"failed to leave programming mode, got 0x%02x\n",
progname,buf[1]);
"failed to leave programming mode\n",
progname);
exit(1);
}
@ -986,9 +1001,10 @@ static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
result = stk500v2_command(pgm, buf, 5, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_loadaddr(): failed to set load address, got 0x%02x\n",
progname,buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500v2_loadaddr(): failed to set load address\n",
progname);
return -1;
}
@ -1090,11 +1106,11 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
if (result < 0 || buf[1] != STATUS_CMD_OK) {
if (result < 0) {
fprintf(stderr,
"%s: stk500hv_read_byte(): "
"timeout/error communicating with programmer (status %d)\n",
progname, result);
"timeout/error communicating with programmer\n",
progname);
return -1;
}
@ -1254,11 +1270,11 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
if (result < 0 || buf[1] != STATUS_CMD_OK) {
if (result < 0) {
fprintf(stderr,
"%s: stk500hv_write_byte(): "
"timeout/error communicating with programmer (status %d)\n",
progname, result);
"timeout/error communicating with programmer\n",
progname);
return -1;
}
@ -1411,9 +1427,10 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
memcpy(buf+10,m->buf+addr, block_size);
result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr,"%s: stk500v2_paged_write: write command failed with %d\n",
progname,buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500v2_paged_write: write command failed\n",
progname);
return -1;
}
}
@ -1508,9 +1525,10 @@ static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
memset(buf + 5 + block_size, 0xff, page_size - block_size);
result = stk500v2_command(pgm, buf, page_size + 5, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500hv_paged_write: write command failed with %d\n",
progname, buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500hv_paged_write: write command failed\n",
progname);
return -1;
}
}
@ -1621,9 +1639,10 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
result = stk500v2_command(pgm,buf,4,sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr,"%s: stk500v2_paged_load: read command failed with %d\n",
progname,buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500v2_paged_load: read command failed\n",
progname);
return -1;
}
#if 0
@ -1699,9 +1718,10 @@ static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500hv_paged_load: read command failed with %d\n",
progname, buf[1]);
if (result < 0) {
fprintf(stderr,
"%s: stk500hv_paged_load: read command failed\n",
progname);
return -1;
}
#if 0
@ -2088,6 +2108,23 @@ static void stk500v2_print_parms(PROGRAMMER * pgm)
stk500v2_print_parms1(pgm, "");
}
static int stk500v2_perform_osccal(PROGRAMMER * pgm)
{
unsigned char buf[32];
int rv;
buf[0] = CMD_OSCCAL;
rv = stk500v2_command(pgm, buf, 1, sizeof(buf));
if (rv < 0) {
fprintf(stderr, "%s: stk500v2_perform_osccal(): failed\n",
progname);
return -1;
}
return 0;
}
/*
* Wrapper functions for the JTAG ICE mkII in ISP mode. This mode
@ -2183,6 +2220,7 @@ void stk500v2_initpgm(PROGRAMMER * pgm)
pgm->set_varef = stk500v2_set_varef;
pgm->set_fosc = stk500v2_set_fosc;
pgm->set_sck_period = stk500v2_set_sck_period;
pgm->perform_osccal = stk500v2_perform_osccal;
pgm->page_size = 256;
}
@ -2274,5 +2312,6 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
pgm->paged_load = stk500v2_paged_load;
pgm->print_parms = stk500v2_print_parms;
pgm->set_sck_period = stk500v2_set_sck_period_mk2;
pgm->perform_osccal = stk500v2_perform_osccal;
pgm->page_size = 256;
}