diff --git a/avrdude/CHANGELOG b/avrdude/CHANGELOG index 6062f4f0..c2868642 100644 --- a/avrdude/CHANGELOG +++ b/avrdude/CHANGELOG @@ -4,6 +4,20 @@ Approximate change log for AVRPROG by version ---------------------------------------------------------------------- +Version 3.0.0 + + * Rewrite parts of the code to make it easy to support other types + of programmers besides the directly connected parallel port + programmer (PPI). + + * Add support for Atmel's STK500 programmer/development board. The + STK500's "paged mode" read/write is supported which makes this + programmer very fast. This is sorely needed on parts with large + memories such as the ATmega128. My 12K test program burns in + about 5 seconds, add another 5 to read it back out for + verification. + + Version 2.1.5: * When getting ready to initiate communications with the AVR device, diff --git a/avrdude/stk500.c b/avrdude/stk500.c index 972ec294..7a8b86c4 100644 --- a/avrdude/stk500.c +++ b/avrdude/stk500.c @@ -57,7 +57,7 @@ extern int do_cycles; char * stk500_version = "$Id$"; -int static send(PROGRAMMER * pgm, char * buf, int buflen) +int static stk500_send(PROGRAMMER * pgm, char * buf, int buflen) { struct timeval timeout; fd_set wfds; @@ -77,7 +77,8 @@ int static send(PROGRAMMER * pgm, char * buf, int buflen) reselect: nfds = select(pgm->fd+1, NULL, &wfds, NULL, &timeout); if (nfds == 0) { - fprintf(stderr, "%s: send(): programmer is not responding on %s\n", + fprintf(stderr, + "%s: stk500_send(): programmer is not responding on %s\n", progname, pgm->port); exit(1); } @@ -86,7 +87,7 @@ int static send(PROGRAMMER * pgm, char * buf, int buflen) goto reselect; } else { - fprintf(stderr, "%s: send(): select(): %s\n", + fprintf(stderr, "%s: stk500_send(): select(): %s\n", progname, strerror(errno)); exit(1); } @@ -94,7 +95,7 @@ int static send(PROGRAMMER * pgm, char * buf, int buflen) rc = write(pgm->fd, buf, 1); if (rc < 0) { - fprintf(stderr, "%s: send(): write error: %s\n", + fprintf(stderr, "%s: stk500_send(): write error: %s\n", progname, strerror(errno)); exit(1); } @@ -107,7 +108,7 @@ int static send(PROGRAMMER * pgm, char * buf, int buflen) -int static recv(PROGRAMMER * pgm, char * buf, int n) +int static stk500_recv(PROGRAMMER * pgm, char * buf, int n) { struct timeval timeout; fd_set rfds; @@ -124,7 +125,8 @@ int static recv(PROGRAMMER * pgm, char * buf, int n) reselect: nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout); if (nfds == 0) { - fprintf(stderr, "%s: recv(): programmer is not responding on %s\n", + fprintf(stderr, + "%s: stk500_recv(): programmer is not responding on %s\n", progname, pgm->port); exit(1); } @@ -133,7 +135,7 @@ int static recv(PROGRAMMER * pgm, char * buf, int n) goto reselect; } else { - fprintf(stderr, "%s: recv(): select(): %s\n", + fprintf(stderr, "%s: stk500_recv(): select(): %s\n", progname, strerror(errno)); exit(1); } @@ -141,7 +143,7 @@ int static recv(PROGRAMMER * pgm, char * buf, int n) rc = read(pgm->fd, buf, 1); if (rc < 0) { - fprintf(stderr, "%s: recv(): read error: %s\n", + fprintf(stderr, "%s: stk500_recv(): read error: %s\n", progname, strerror(errno)); exit(1); } @@ -153,7 +155,7 @@ int static recv(PROGRAMMER * pgm, char * buf, int n) } -int static drain(PROGRAMMER * pgm, int display) +int static stk500_drain(PROGRAMMER * pgm, int display) { struct timeval timeout; fd_set rfds; @@ -186,7 +188,7 @@ int static drain(PROGRAMMER * pgm, int display) goto reselect; } else { - fprintf(stderr, "%s: drain(): select(): %s\n", + fprintf(stderr, "%s: stk500_drain(): select(): %s\n", progname, strerror(errno)); exit(1); } @@ -194,7 +196,7 @@ int static drain(PROGRAMMER * pgm, int display) rc = read(pgm->fd, &buf, 1); if (rc < 0) { - fprintf(stderr, "%s: drain(): read error: %s\n", + fprintf(stderr, "%s: stk500_drain(): read error: %s\n", progname, strerror(errno)); exit(1); } @@ -205,7 +207,7 @@ int static drain(PROGRAMMER * pgm, int display) } -static int getsync(PROGRAMMER * pgm) +static int stk500_getsync(PROGRAMMER * pgm) { unsigned char buf[32], resp[32]; @@ -213,20 +215,21 @@ static int getsync(PROGRAMMER * pgm) * get in sync */ buf[0] = Cmnd_STK_GET_SYNC; buf[1] = Sync_CRC_EOP; - send(pgm, buf, 2); - recv(pgm, resp, 1); + stk500_send(pgm, buf, 2); + stk500_recv(pgm, resp, 1); if (resp[0] != Resp_STK_INSYNC) { fprintf(stderr, - "%s: stk500_open(): not in sync: resp=0x%02x\n", + "%s: stk500_getsync(): not in sync: resp=0x%02x\n", progname, resp[0]); - drain(pgm, 0); + stk500_drain(pgm, 0); exit(1); } - recv(pgm, resp, 1); + stk500_recv(pgm, resp, 1); if (resp[0] != Resp_STK_OK) { fprintf(stderr, - "%s: stk500_open(): can't communicate with device: resp=0x%02x\n", + "%s: stk500_getsync(): can't communicate with device: " + "resp=0x%02x\n", progname, resp[0]); exit(1); } @@ -271,22 +274,22 @@ int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res[4]) buf[4] = cmd[3]; buf[5] = Sync_CRC_EOP; - send(pgm, buf, 6); + stk500_send(pgm, buf, 6); - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] != Resp_STK_INSYNC) { - fprintf(stderr, "%s: programmer is out of sync\n", progname); + fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n", progname); exit(1); } res[0] = cmd[1]; res[1] = cmd[2]; res[2] = cmd[3]; - recv(pgm, &res[3], 1); + stk500_recv(pgm, &res[3], 1); - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] != Resp_STK_OK) { - fprintf(stderr, "%s: protocol error\n", progname); + fprintf(stderr, "%s: stk500_cmd(): protocol error\n", progname); exit(1); } @@ -363,26 +366,26 @@ int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p) buf[0] = Cmnd_STK_ENTER_PROGMODE; buf[1] = Sync_CRC_EOP; - send(pgm, buf, 2); - recv(pgm, buf, 1); + stk500_send(pgm, buf, 2); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "%s: stk500_program_enable(): can't get into sync\n", progname); return -1; } - getsync(pgm); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { fprintf(stderr, - "%s: stk500_initialize(): (a) protocol error, " + "%s: stk500_program_enable(): protocol error, " "expect=0x%02x, resp=0x%02x\n", progname, Resp_STK_INSYNC, buf[0]); return -1; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_OK) { return 0; } @@ -426,6 +429,11 @@ int stk500_initialize(PROGRAMMER * pgm, AVRPART * p) AVRMEM * m; int tries; + tries = 0; + + retry: + tries++; + /* * set device programming parameters */ @@ -501,18 +509,15 @@ int stk500_initialize(PROGRAMMER * pgm, AVRPART * p) buf[21] = Sync_CRC_EOP; - tries = 0; - retry: - tries++; - send(pgm, buf, 22); - recv(pgm, buf, 1); + stk500_send(pgm, buf, 22); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_NOSYNC) { fprintf(stderr, "%s: stk500_initialize(): programmer not in sync, resp=0x%02x\n", progname, buf[0]); if (tries > 33) return -1; - getsync(pgm); + stk500_getsync(pgm); goto retry; return -1; } @@ -524,7 +529,7 @@ int stk500_initialize(PROGRAMMER * pgm, AVRPART * p) return -1; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "%s: stk500_initialize(): (b) protocol error, " @@ -559,15 +564,15 @@ void stk500_disable(PROGRAMMER * pgm) buf[0] = Cmnd_STK_LEAVE_PROGMODE; buf[1] = Sync_CRC_EOP; - send(pgm, buf, 2); - recv(pgm, buf, 1); + stk500_send(pgm, buf, 2); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "%s: stk500_program_enable(): can't get into sync\n", progname); return; } - getsync(pgm); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -578,7 +583,7 @@ void stk500_disable(PROGRAMMER * pgm) return; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_OK) { return; } @@ -600,7 +605,7 @@ void stk500_enable(PROGRAMMER * pgm) } -int static set_tty_attr(int fd) +int static stk500_setattr(int fd) { int rc; struct termios termios; @@ -613,12 +618,12 @@ int static set_tty_attr(int fd) */ rc = tcgetattr(fd, &termios); if (rc < 0) { - fprintf(stderr, "%s: tcgetattr() failed, %s", + fprintf(stderr, "%s: stk500_setattr(): tcgetattr() failed, %s", progname, strerror(errno)); return -errno; } -#if 1 +#if 0 termios.c_iflag &= ~(INPCK | IXOFF | IXON); termios.c_cflag &= ~(HUPCL | CSTOPB | CRTSCTS); termios.c_cflag |= (CLOCAL | CREAD); @@ -628,7 +633,7 @@ int static set_tty_attr(int fd) termios.c_iflag = 0; termios.c_oflag = 0; termios.c_cflag &= ~ (PARENB | CSIZE | CSTOPB); - termios.c_cflag |= (CS8 | HUPCL | CREAD | CLOCAL); + termios.c_cflag |= (CS8 | CREAD | CLOCAL); termios.c_lflag = 0; termios.c_cc[VMIN] = 1; termios.c_cc[VTIME] = 0; @@ -639,7 +644,8 @@ int static set_tty_attr(int fd) rc = tcsetattr(fd, TCSANOW, &termios); if (rc < 0) { - fprintf(stderr, "%s: tcsetattr() failed, %s", progname, strerror(errno)); + fprintf(stderr, "%s: stk500_setattr(): tcsetattr() failed, %s", + progname, strerror(errno)); return -errno; } @@ -658,7 +664,7 @@ void stk500_open(PROGRAMMER * pgm, char * port) */ pgm->fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/); if (pgm->fd < 0) { - fprintf(stderr, "%s: can't open device \"%s\": %s\n", + fprintf(stderr, "%s: stk500_open(): can't open device \"%s\": %s\n", progname, port, strerror(errno)); exit(1); } @@ -666,9 +672,10 @@ void stk500_open(PROGRAMMER * pgm, char * port) /* * set serial line attributes */ - rc = set_tty_attr(pgm->fd); + rc = stk500_setattr(pgm->fd); if (rc) { - fprintf(stderr, "%s: can't set attributes for device \"%s\"\n", + fprintf(stderr, + "%s: stk500_open(): can't set attributes for device \"%s\"\n", progname, port); exit(1); } @@ -676,11 +683,11 @@ void stk500_open(PROGRAMMER * pgm, char * port) /* * drain any extraneous input */ - drain(pgm, 0); + stk500_drain(pgm, 0); - getsync(pgm); + stk500_getsync(pgm); - drain(pgm, 0); + stk500_drain(pgm, 0); } @@ -691,7 +698,7 @@ void stk500_close(PROGRAMMER * pgm) } -static int loadaddr(PROGRAMMER * pgm, uint16_t addr) +static int stk500_loadaddr(PROGRAMMER * pgm, uint16_t addr) { unsigned char buf[16]; int tries; @@ -704,35 +711,36 @@ static int loadaddr(PROGRAMMER * pgm, uint16_t addr) buf[2] = (addr >> 8) & 0xff; buf[3] = Sync_CRC_EOP; - send(pgm, buf, 4); + stk500_send(pgm, buf, 4); - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { - fprintf(stderr, "%s: loadaddr(): can't get into sync\n", + fprintf(stderr, "%s: stk500_loadaddr(): can't get into sync\n", progname); return -1; } - getsync(pgm); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { fprintf(stderr, - "%s: loadaddr(): (a) protocol error, " + "%s: stk500_loadaddr(): (a) protocol error, " "expect=0x%02x, resp=0x%02x\n", progname, Resp_STK_INSYNC, buf[0]); return -1; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_OK) { return 0; } fprintf(stderr, - "%s: loadaddr(): (a) protocol error, " + "%s: loadaddr(): (b) protocol error, " "expect=0x%02x, resp=0x%02x\n", progname, Resp_STK_INSYNC, buf[0]); + return -1; } @@ -781,27 +789,27 @@ int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, tries = 0; retry: tries++; - loadaddr(pgm, addr/a_div); + stk500_loadaddr(pgm, addr/a_div); buf[0] = Cmnd_STK_PROG_PAGE; buf[1] = (page_size >> 8) & 0xff; buf[2] = page_size & 0xff; buf[3] = memtype; - send(pgm, buf, 4); + stk500_send(pgm, buf, 4); for (i=0; ibuf[addr + i]; - send(pgm, buf, 1); + stk500_send(pgm, buf, 1); } buf[0] = Sync_CRC_EOP; - send(pgm, buf, 1); + stk500_send(pgm, buf, 1); - recv(pgm, buf, 1); + stk500_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); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -812,7 +820,7 @@ int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return -4; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "\n%s: stk500_paged_write(): (a) protocol error, " @@ -866,30 +874,27 @@ int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, } } - fprintf(stderr, "%s: stk500_paged_load(): n=%d, a_div=%d\n", - progname, n, a_div); - for (addr = 0; addr < n; addr += page_size) { fprintf(stderr, "\r \r%6u", addr); tries = 0; retry: tries++; - loadaddr(pgm, addr/a_div); + stk500_loadaddr(pgm, addr/a_div); buf[0] = Cmnd_STK_READ_PAGE; buf[1] = (page_size >> 8) & 0xff; buf[2] = page_size & 0xff; buf[3] = memtype; buf[4] = Sync_CRC_EOP; - send(pgm, buf, 5); + stk500_send(pgm, buf, 5); - recv(pgm, buf, 1); + stk500_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); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -900,9 +905,9 @@ int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return -4; } - recv(pgm, &m->buf[addr], page_size); + stk500_recv(pgm, &m->buf[addr], page_size); - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "\n%s: stk500_paged_load(): (a) protocol error, " @@ -918,7 +923,7 @@ int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, } -static int getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) +static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) { unsigned char buf[16]; unsigned v; @@ -930,16 +935,16 @@ static int getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) buf[1] = parm; buf[2] = Sync_CRC_EOP; - send(pgm, buf, 3); + stk500_send(pgm, buf, 3); - recv(pgm, buf, 1); + stk500_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); + stk500_getsync(pgm); goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -950,10 +955,10 @@ static int getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) return -2; } - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); v = buf[0]; - recv(pgm, buf, 1); + stk500_recv(pgm, buf, 1); if (buf[0] == Resp_STK_FAILED) { fprintf(stderr, "\n%s: getparm(): parameter 0x%02x failed\n", @@ -978,9 +983,9 @@ 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); + stk500_getparm(pgm, Parm_STK_HW_VER, &hdw); + stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj); + stk500_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);