Optimize reading and writing for the STK500 programmer if the part

supports paged reads and writes.  This greatly decreases the
program/verify time from about 4.5 minutes down to about 10 seconds in
a 12K program size test case.

Print out the hardware and firmware version for the STK500 if verbose
is enabled.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@161 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Brian S. Dean 2002-12-01 06:35:18 +00:00
parent dcca02ebbf
commit d36b48d92b
7 changed files with 370 additions and 28 deletions

17
avr.c
View File

@ -374,6 +374,15 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
size = mem->size;
}
if (mem->paged && pgm->paged_load != NULL) {
/*
* the programmer directly supports writing this memory, perhaps
* more efficiently than we can from here
*/
return pgm->paged_load(pgm, p, mem, size);
}
printed = 0;
for (i=0; i<size; i++) {
@ -665,6 +674,14 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
pgm->err_led(pgm, OFF);
if (m->paged && pgm->paged_write != NULL) {
/*
* the programmer directly supports writing this memory, perhaps
* more efficiently than we can from here
*/
return pgm->paged_write(pgm, p, m, size);
}
printed = 0;
werror = 0;

18
avr.h
View File

@ -39,24 +39,6 @@
#include "pgm.h"
#define AVR_MEMDESCLEN 64
typedef struct avrmem {
char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */
int paged; /* page addressed (e.g. ATmega flash) */
int size; /* total memory size in bytes */
int page_size; /* size of memory page (if page addressed) */
int num_pages; /* number of pages (if page addressed) */
int min_write_delay; /* microseconds */
int max_write_delay; /* microseconds */
int pwroff_after_write; /* after this memory type is written to,
the device must be powered off and
back on, see errata
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
unsigned char readback[2]; /* polled read-back values */
unsigned char * buf; /* pointer to memory buffer */
OPCODE * op[AVR_OP_MAX]; /* opcodes */
} AVRMEM;
extern struct avrpart parts[];

View File

@ -56,4 +56,22 @@ typedef struct avrpart {
LISTID mem; /* avr memory definitions */
} AVRPART;
#define AVR_MEMDESCLEN 64
typedef struct avrmem {
char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */
int paged; /* page addressed (e.g. ATmega flash) */
int size; /* total memory size in bytes */
int page_size; /* size of memory page (if page addressed) */
int num_pages; /* number of pages (if page addressed) */
int min_write_delay; /* microseconds */
int max_write_delay; /* microseconds */
int pwroff_after_write; /* after this memory type is written to,
the device must be powered off and
back on, see errata
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
unsigned char readback[2]; /* polled read-back values */
unsigned char * buf; /* pointer to memory buffer */
OPCODE * op[AVR_OP_MAX]; /* opcodes */
} AVRMEM;
#endif

16
main.c
View File

@ -735,14 +735,6 @@ int main(int argc, char * argv [])
p = avr_dup_part(p);
v = avr_dup_part(p);
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
pinconfig_display(progbuf);
}
fprintf(stderr, "\n");
if (strcmp(pgm->type, "PPI") == 0) {
verify_pin_assigned(PIN_AVR_RESET, "AVR RESET");
verify_pin_assigned(PIN_AVR_SCK, "AVR SCK");
@ -755,6 +747,14 @@ int main(int argc, char * argv [])
*/
pgm->open(pgm, port);
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
pinconfig_display(progbuf);
}
fprintf(stderr, "\n");
exitrc = 0;
rc = pgm->save(pgm);

11
pgm.c
View File

@ -69,6 +69,10 @@ PROGRAMMER * pgm_new(void)
for (i=0; i<N_PINS; i++)
pgm->pinno[i] = 0;
/*
* mandatory functions - these are called without checking to see
* whether they are assigned or not
*/
pgm->rdy_led = pgm_default_1;
pgm->err_led = pgm_default_1;
pgm->pgm_led = pgm_default_1;
@ -87,6 +91,13 @@ PROGRAMMER * pgm_new(void)
pgm->open = pgm_default_6;
pgm->close = pgm_default_4;
/*
* optional functions - these are checked to make sure they are
* assigned before they are called
*/
pgm->paged_write = NULL;
pgm->paged_load = NULL;
return pgm;
}

4
pgm.h
View File

@ -71,6 +71,10 @@ typedef struct programmer_t {
unsigned char res[4]);
void (*open) (struct programmer_t * pgm, char * port);
void (*close) (struct programmer_t * pgm);
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int n_bytes);
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int n_bytes);
} PROGRAMMER;

314
stk500.c
View File

@ -29,6 +29,15 @@
/* $Id$ */
/*
* avrprog interface for Atmel STK500 programmer
*
* Note: most commands use the "universal command" feature of the
* programmer in a "pass through" mode, exceptions are "program
* enable", "paged read", and "paged write".
*
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@ -201,8 +210,7 @@ static int getsync(PROGRAMMER * pgm)
unsigned char buf[32], resp[32];
/*
* get in sync
*/
* get in sync */
buf[0] = Cmnd_STK_GET_SYNC;
buf[1] = Sync_CRC_EOP;
send(pgm, buf, 2);
@ -683,8 +691,301 @@ void stk500_close(PROGRAMMER * pgm)
}
static int loadaddr(PROGRAMMER * pgm, uint16_t addr)
{
unsigned char buf[16];
int tries;
tries = 0;
retry:
tries++;
buf[0] = Cmnd_STK_LOAD_ADDRESS;
buf[1] = addr & 0xff;
buf[2] = (addr >> 8) & 0xff;
buf[3] = Sync_CRC_EOP;
send(pgm, buf, 4);
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: loadaddr(): can't get into sync\n",
progname);
return -1;
}
getsync(pgm);
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"%s: loadaddr(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -1;
}
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_OK) {
return 0;
}
fprintf(stderr,
"%s: loadaddr(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -1;
}
int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int n_bytes)
{
unsigned char buf[16];
int memtype;
unsigned int addr;
int a_div;
int i;
int tries;
unsigned int n;
if (!m->paged)
return -1;
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
}
else if (strcmp(m->desc, "flash") == 0) {
memtype = 'E';
}
else {
return -2;
}
if (m->op[AVR_OP_LOADPAGE_LO])
a_div = 2;
else
a_div = 1;
if (n_bytes > m->size) {
n_bytes = m->size;
n = m->size;
}
else {
if ((n_bytes % m->page_size) != 0) {
n = n_bytes + m->page_size - (n_bytes % m->page_size);
}
else {
n = n_bytes;
}
}
for (addr = 0; addr < n; addr += m->page_size) {
fprintf(stderr, "\r \r%6u", addr);
tries = 0;
retry:
tries++;
loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_PROG_PAGE;
buf[1] = (m->page_size >> 8) & 0xff;
buf[2] = m->page_size & 0xff;
buf[3] = memtype;
send(pgm, buf, 4);
for (i=0; i<m->page_size; i++) {
buf[0] = m->buf[addr + i];
send(pgm, buf, 1);
}
buf[0] = Sync_CRC_EOP;
send(pgm, buf, 1);
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_paged_write(): can't get into sync\n",
progname);
return -3;
}
getsync(pgm);
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: stk500_paged_write(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -4;
}
recv(pgm, buf, 1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: stk500_paged_write(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -5;
}
}
fprintf(stderr, "\r \r%6u", addr-1);
fprintf(stderr, "\n");
return n;
}
int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int n_bytes)
{
unsigned char buf[16];
int memtype;
unsigned int addr;
int a_div;
int tries;
unsigned int n;
if (!m->paged)
return -1;
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
}
else if (strcmp(m->desc, "flash") == 0) {
memtype = 'E';
}
else {
return -2;
}
if (m->op[AVR_OP_LOADPAGE_LO])
a_div = 2;
else
a_div = 1;
if (n_bytes > m->size) {
n_bytes = m->size;
n = m->size;
}
else {
if ((n_bytes % m->page_size) != 0) {
n = n_bytes + m->page_size - (n_bytes % m->page_size);
}
else {
n = n_bytes;
}
}
for (addr = 0; addr < n; addr += m->page_size) {
fprintf(stderr, "\r \r%6u", addr);
tries = 0;
retry:
tries++;
loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_READ_PAGE;
buf[1] = (m->page_size >> 8) & 0xff;
buf[2] = m->page_size & 0xff;
buf[3] = memtype;
buf[4] = Sync_CRC_EOP;
send(pgm, buf, 5);
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_paged_load(): can't get into sync\n",
progname);
return -3;
}
getsync(pgm);
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -4;
}
recv(pgm, &m->buf[addr], m->page_size);
recv(pgm, buf, 1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -5;
}
}
fprintf(stderr, "\r \r%6u", addr-1);
fprintf(stderr, "\n");
return n;
}
static int getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
{
unsigned char buf[16];
unsigned v;
int tries = 0;
retry:
tries++;
buf[0] = Cmnd_STK_GET_PARAMETER;
buf[1] = parm;
buf[2] = Sync_CRC_EOP;
send(pgm, buf, 3);
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: getparm(): can't get into sync\n",
progname);
return -1;
}
getsync(pgm);
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: getparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -2;
}
recv(pgm, buf, 1);
v = buf[0];
recv(pgm, buf, 1);
if (buf[0] == Resp_STK_FAILED) {
fprintf(stderr,
"\n%s: getparm(): parameter 0x%02x failed\n",
progname, v);
return -3;
}
else if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: getparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -3;
}
*value = v;
return 0;
}
void stk500_display(PROGRAMMER * pgm, char * p)
{
unsigned maj, min, hdw;
getparm(pgm, Parm_STK_HW_VER, &hdw);
getparm(pgm, Parm_STK_SW_MAJOR, &maj);
getparm(pgm, Parm_STK_SW_MINOR, &min);
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
return;
}
@ -693,6 +994,9 @@ void stk500_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "STK500");
/*
* mandatory functions
*/
pgm->rdy_led = stk500_rdy_led;
pgm->err_led = stk500_err_led;
pgm->pgm_led = stk500_pgm_led;
@ -710,6 +1014,12 @@ void stk500_initpgm(PROGRAMMER * pgm)
pgm->cmd = stk500_cmd;
pgm->open = stk500_open;
pgm->close = stk500_close;
/*
* optional functions
*/
pgm->paged_write = stk500_paged_write;
pgm->paged_load = stk500_paged_load;
}