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:
parent
da6e6490a4
commit
b3cc1535b6
17
avr.c
17
avr.c
|
@ -374,6 +374,15 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||||
size = mem->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;
|
printed = 0;
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
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);
|
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;
|
printed = 0;
|
||||||
werror = 0;
|
werror = 0;
|
||||||
|
|
||||||
|
|
18
avr.h
18
avr.h
|
@ -39,24 +39,6 @@
|
||||||
#include "pgm.h"
|
#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[];
|
extern struct avrpart parts[];
|
||||||
|
|
||||||
|
|
18
avrpart.h
18
avrpart.h
|
@ -56,4 +56,22 @@ typedef struct avrpart {
|
||||||
LISTID mem; /* avr memory definitions */
|
LISTID mem; /* avr memory definitions */
|
||||||
} AVRPART;
|
} 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
|
#endif
|
||||||
|
|
16
main.c
16
main.c
|
@ -735,14 +735,6 @@ int main(int argc, char * argv [])
|
||||||
p = avr_dup_part(p);
|
p = avr_dup_part(p);
|
||||||
v = 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) {
|
if (strcmp(pgm->type, "PPI") == 0) {
|
||||||
verify_pin_assigned(PIN_AVR_RESET, "AVR RESET");
|
verify_pin_assigned(PIN_AVR_RESET, "AVR RESET");
|
||||||
verify_pin_assigned(PIN_AVR_SCK, "AVR SCK");
|
verify_pin_assigned(PIN_AVR_SCK, "AVR SCK");
|
||||||
|
@ -755,6 +747,14 @@ int main(int argc, char * argv [])
|
||||||
*/
|
*/
|
||||||
pgm->open(pgm, port);
|
pgm->open(pgm, port);
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
avr_display(stderr, p, progbuf, verbose);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
pinconfig_display(progbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
exitrc = 0;
|
exitrc = 0;
|
||||||
|
|
||||||
rc = pgm->save(pgm);
|
rc = pgm->save(pgm);
|
||||||
|
|
11
pgm.c
11
pgm.c
|
@ -69,6 +69,10 @@ PROGRAMMER * pgm_new(void)
|
||||||
for (i=0; i<N_PINS; i++)
|
for (i=0; i<N_PINS; i++)
|
||||||
pgm->pinno[i] = 0;
|
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->rdy_led = pgm_default_1;
|
||||||
pgm->err_led = pgm_default_1;
|
pgm->err_led = pgm_default_1;
|
||||||
pgm->pgm_led = pgm_default_1;
|
pgm->pgm_led = pgm_default_1;
|
||||||
|
@ -87,6 +91,13 @@ PROGRAMMER * pgm_new(void)
|
||||||
pgm->open = pgm_default_6;
|
pgm->open = pgm_default_6;
|
||||||
pgm->close = pgm_default_4;
|
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;
|
return pgm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
pgm.h
4
pgm.h
|
@ -71,6 +71,10 @@ typedef struct programmer_t {
|
||||||
unsigned char res[4]);
|
unsigned char res[4]);
|
||||||
void (*open) (struct programmer_t * pgm, char * port);
|
void (*open) (struct programmer_t * pgm, char * port);
|
||||||
void (*close) (struct programmer_t * pgm);
|
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;
|
} PROGRAMMER;
|
||||||
|
|
||||||
|
|
||||||
|
|
314
stk500.c
314
stk500.c
|
@ -29,6 +29,15 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -201,8 +210,7 @@ static int getsync(PROGRAMMER * pgm)
|
||||||
unsigned char buf[32], resp[32];
|
unsigned char buf[32], resp[32];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get in sync
|
* get in sync */
|
||||||
*/
|
|
||||||
buf[0] = Cmnd_STK_GET_SYNC;
|
buf[0] = Cmnd_STK_GET_SYNC;
|
||||||
buf[1] = Sync_CRC_EOP;
|
buf[1] = Sync_CRC_EOP;
|
||||||
send(pgm, buf, 2);
|
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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +994,9 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
strcpy(pgm->type, "STK500");
|
strcpy(pgm->type, "STK500");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mandatory functions
|
||||||
|
*/
|
||||||
pgm->rdy_led = stk500_rdy_led;
|
pgm->rdy_led = stk500_rdy_led;
|
||||||
pgm->err_led = stk500_err_led;
|
pgm->err_led = stk500_err_led;
|
||||||
pgm->pgm_led = stk500_pgm_led;
|
pgm->pgm_led = stk500_pgm_led;
|
||||||
|
@ -710,6 +1014,12 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
||||||
pgm->cmd = stk500_cmd;
|
pgm->cmd = stk500_cmd;
|
||||||
pgm->open = stk500_open;
|
pgm->open = stk500_open;
|
||||||
pgm->close = stk500_close;
|
pgm->close = stk500_close;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* optional functions
|
||||||
|
*/
|
||||||
|
pgm->paged_write = stk500_paged_write;
|
||||||
|
pgm->paged_load = stk500_paged_load;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue