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:
bsd
2002-12-01 06:35:18 +00:00
parent da6e6490a4
commit b3cc1535b6
7 changed files with 370 additions and 28 deletions

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;
}