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:
parent
57028107ff
commit
2cfccda03d
12
ChangeLog
12
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
24
main.c
|
@ -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
1
pgm.c
|
@ -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
1
pgm.h
|
@ -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 */
|
||||
|
|
111
stk500v2.c
111
stk500v2.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue