From bf388ff428c0428a224fcdcd5365b50cf0dd2919 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Tue, 19 Sep 2006 22:27:30 +0000 Subject: [PATCH] Add the "stk500generic" programmer that auto-probes for STK500 either firmware version 1 or 2. * Makefile.am (avrdude_SOURCES): add the new files stk500generic.c and stk500generic.h. * avrdude.conf.in: Add the stk500generic programmer type, and change the "stk500" entry to point to this programmer. * config_gram.y: Add the stk500generic keyword. * lexer.l: (Ditto.) * stk500.c: Change the stk500v1 code to not call exit() prematurely when failing to open the programmer, but instead return an error status. * stk500generic.c: (New file.) Stub programmer implementation. Probe for either stk500v1 or stk500v2, and adjust the current pgm appropriately. * stk500generic.h: (New file.) Declare the public interface(s) of stk500generic.c. * doc/avrdude.texi: Document the changed behaviour of stk500. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@663 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 20 +++++++++ Makefile.am | 2 + avrdude.conf.in | 9 ++-- config_gram.y | 8 ++++ doc/avrdude.texi | 4 +- lexer.l | 1 + stk500.c | 114 +++++++++++++++++++++++++++++++---------------- stk500generic.c | 72 ++++++++++++++++++++++++++++++ stk500generic.h | 29 ++++++++++++ 9 files changed, 215 insertions(+), 44 deletions(-) create mode 100644 stk500generic.c create mode 100644 stk500generic.h diff --git a/ChangeLog b/ChangeLog index b6d65577..dd721e80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2006-09-20 Joerg Wunsch + + Add the "stk500generic" programmer that auto-probes for STK500 + either firmware version 1 or 2. + * Makefile.am (avrdude_SOURCES): add the new files + stk500generic.c and stk500generic.h. + * avrdude.conf.in: Add the stk500generic programmer type, and + change the "stk500" entry to point to this programmer. + * config_gram.y: Add the stk500generic keyword. + * lexer.l: (Ditto.) + * stk500.c: Change the stk500v1 code to not call exit() + prematurely when failing to open the programmer, but instead + return an error status. + * stk500generic.c: (New file.) Stub programmer implementation. + Probe for either stk500v1 or stk500v2, and adjust the current pgm + appropriately. + * stk500generic.h: (New file.) Declare the public interface(s) + of stk500generic.c. + * doc/avrdude.texi: Document the changed behaviour of stk500. + 2006-09-18 Joerg Wunsch * avrdude.conf.in: Various fixes for ancient processors and their diff --git a/Makefile.am b/Makefile.am index b640e6ce..b2300a07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,6 +121,8 @@ avrdude_SOURCES = \ stk500v2.c \ stk500v2.h \ stk500v2_private.h \ + stk500generic.c \ + stk500generic.h \ term.c \ term.h \ usbasp.c \ diff --git a/avrdude.conf.in b/avrdude.conf.in index a0a51c27..6b1ff2c2 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -15,7 +15,7 @@ # programmer # id = [, [, ] ...] ; # are quoted strings # desc = ; # quoted string -# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | +# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic | # avr910 | butterfly | usbasp | # jtagmki | jtagmkii | jtagmkii_isp; # programmer type # baudrate = ; # baudrate for avr910-programmer @@ -316,12 +316,13 @@ programmer ; # This is supposed to be the "default" STK500 entry. -# Refers to V1 by now, might be changed to V2 in a -# future release. +# Attempts to select the correct firmware version +# by probing for it. Better use one of the entries +# below instead. programmer id = "stk500"; desc = "Atmel STK500"; - type = stk500; + type = stk500generic; ; programmer diff --git a/config_gram.y b/config_gram.y index 785f2e27..10dc23f2 100644 --- a/config_gram.y +++ b/config_gram.y @@ -36,6 +36,7 @@ #include "pgm.h" #include "stk500.h" #include "stk500v2.h" +#include "stk500generic.h" #include "avr910.h" #include "butterfly.h" #include "usbasp.h" @@ -126,6 +127,7 @@ static int parse_cmdbits(OPCODE * op); %token K_STK500HVSP %token K_STK500PP %token K_STK500V2 +%token K_STK500GENERIC %token K_AVR910 %token K_USBASP %token K_BUTTERFLY @@ -393,6 +395,12 @@ prog_parm : } } | + K_TYPE TKN_EQUAL K_STK500GENERIC { + { + stk500generic_initpgm(current_prog); + } + } | + K_TYPE TKN_EQUAL K_AVR910 { { avr910_initpgm(current_prog); diff --git a/doc/avrdude.texi b/doc/avrdude.texi index c3a05ab8..27265c1e 100644 --- a/doc/avrdude.texi +++ b/doc/avrdude.texi @@ -401,7 +401,9 @@ Steve Bolt's Programmer @item @code{stk200} @tab STK200 @item @code{stk500} @tab -Atmel STK500 +Atmel STK500, probing for either version 1.x or 2.x firmware +@item @code{stk500v1} @tab +Atmel STK500, running a version 1.x firmware @item @code{stk500hvsp} @tab Atmel STK500 in high-voltage serial programming mode(version 2.x firmware only) @item @code{stk500pp} @tab diff --git a/lexer.l b/lexer.l index 867149a3..32ccc928 100644 --- a/lexer.l +++ b/lexer.l @@ -176,6 +176,7 @@ stk500 { yylval=NULL; return K_STK500; } stk500hvsp { yylval=NULL; return K_STK500HVSP; } stk500pp { yylval=NULL; return K_STK500PP; } stk500v2 { yylval=NULL; return K_STK500V2; } +stk500generic { yylval=NULL; return K_STK500GENERIC; } stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; } type { yylval=NULL; return K_TYPE; } vcc { yylval=NULL; return K_VCC; } diff --git a/stk500.c b/stk500.c index 170962dd..a17f301b 100644 --- a/stk500.c +++ b/stk500.c @@ -70,7 +70,7 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) fprintf(stderr, "%s: stk500_recv(): programmer is not responding\n", progname); - exit(1); + return -1; } return 0; } @@ -101,22 +101,24 @@ static int stk500_getsync(PROGRAMMER * pgm) stk500_drain(pgm, 0); stk500_send(pgm, buf, 2); - stk500_recv(pgm, resp, 1); + if (stk500_recv(pgm, resp, 1) < 0) + return -1; if (resp[0] != Resp_STK_INSYNC) { fprintf(stderr, "%s: stk500_getsync(): not in sync: resp=0x%02x\n", progname, resp[0]); stk500_drain(pgm, 0); - exit(1); + return -1; } - stk500_recv(pgm, resp, 1); + if (stk500_recv(pgm, resp, 1) < 0) + return -1; if (resp[0] != Resp_STK_OK) { fprintf(stderr, "%s: stk500_getsync(): can't communicate with device: " "resp=0x%02x\n", progname, resp[0]); - exit(1); + return -1; } return 0; @@ -141,7 +143,8 @@ static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4], stk500_send(pgm, buf, 6); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] != Resp_STK_INSYNC) { fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n", progname); exit(1); @@ -150,9 +153,11 @@ static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4], res[0] = cmd[1]; res[1] = cmd[2]; res[2] = cmd[3]; - stk500_recv(pgm, &res[3], 1); + if (stk500_recv(pgm, &res[3], 1) < 0) + exit(1); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "%s: stk500_cmd(): protocol error\n", progname); exit(1); @@ -207,14 +212,16 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p) buf[1] = Sync_CRC_EOP; stk500_send(pgm, buf, 2); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(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; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -225,7 +232,8 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p) return -1; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_OK) { return 0; } @@ -271,14 +279,16 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n, buf[i] = Sync_CRC_EOP; stk500_send(pgm, buf, i+1); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "%s: stk500_set_extended_parms(): can't get into sync\n", progname); return -1; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -289,7 +299,8 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n, return -1; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_OK) { return 0; } @@ -436,14 +447,16 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p) buf[21] = Sync_CRC_EOP; stk500_send(pgm, buf, 22); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(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; - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; return -1; } @@ -455,7 +468,8 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p) return -1; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "%s: stk500_initialize(): (b) protocol error, " @@ -517,14 +531,16 @@ static void stk500_disable(PROGRAMMER * pgm) buf[1] = Sync_CRC_EOP; stk500_send(pgm, buf, 2); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "%s: stk500_disable(): can't get into sync\n", progname); return; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -535,7 +551,8 @@ static void stk500_disable(PROGRAMMER * pgm) return; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_OK) { return; } @@ -570,7 +587,8 @@ static int stk500_open(PROGRAMMER * pgm, char * port) */ stk500_drain(pgm, 0); - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; stk500_drain(pgm, 0); @@ -600,14 +618,16 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr) stk500_send(pgm, buf, 4); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "%s: stk500_loadaddr(): can't get into sync\n", progname); return -1; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -618,7 +638,8 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr) return -1; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_OK) { return 0; } @@ -718,14 +739,16 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, buf[0] = Sync_CRC_EOP; stk500_send(pgm, buf, 1); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(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; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -736,7 +759,8 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return -4; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "\n%s: stk500_paged_write(): (a) protocol error, " @@ -824,14 +848,16 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, buf[4] = Sync_CRC_EOP; stk500_send(pgm, buf, 5); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(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; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -842,9 +868,11 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return -4; } - stk500_recv(pgm, &m->buf[addr], block_size); + if (stk500_recv(pgm, &m->buf[addr], block_size) < 0) + exit(1); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] != Resp_STK_OK) { fprintf(stderr, "\n%s: stk500_paged_load(): (a) protocol error, " @@ -1003,14 +1031,16 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) stk500_send(pgm, buf, 3); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "\n%s: stk500_getparm(): can't get into sync\n", progname); return -1; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -1021,10 +1051,12 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value) return -2; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); v = buf[0]; - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_FAILED) { fprintf(stderr, "\n%s: stk500_getparm(): parameter 0x%02x failed\n", @@ -1059,14 +1091,16 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value) stk500_send(pgm, buf, 4); - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_NOSYNC) { if (tries > 33) { fprintf(stderr, "\n%s: stk500_setparm(): can't get into sync\n", progname); return -1; } - stk500_getsync(pgm); + if (stk500_getsync(pgm) < 0) + return -1; goto retry; } else if (buf[0] != Resp_STK_INSYNC) { @@ -1077,12 +1111,14 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value) return -2; } - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_OK) return 0; parm = buf[0]; /* if not STK_OK, we've been echoed parm here */ - stk500_recv(pgm, buf, 1); + if (stk500_recv(pgm, buf, 1) < 0) + exit(1); if (buf[0] == Resp_STK_FAILED) { fprintf(stderr, "\n%s: stk500_setparm(): parameter 0x%02x failed\n", diff --git a/stk500generic.c b/stk500generic.c new file mode 100644 index 00000000..db334f23 --- /dev/null +++ b/stk500generic.c @@ -0,0 +1,72 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2006 Joerg Wunsch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id$ */ + +/* + * avrdude interface for Atmel STK500 programmer + * + * This is a wrapper around the STK500[v1] and STK500v2 programmers. + * Try to select the programmer type that actually responds, and + * divert to the actual programmer implementation if successful. + */ + +#include "ac_cfg.h" + +#include +#include + +#include "pgm.h" +#include "stk500.h" +#include "stk500v2.h" + +extern char *progname; + +static int stk500generic_open(PROGRAMMER * pgm, char * port) +{ + stk500_initpgm(pgm); + if (pgm->open(pgm, port) >= 0) + { + fprintf(stderr, + "%s: successfully opened stk500v1 device -- please use -c stk500v1\n", + progname); + return 0; + } + + stk500v2_initpgm(pgm); + if (pgm->open(pgm, port) >= 0) + { + fprintf(stderr, + "%s: successfully opened stk500v2 device -- please use -c stk500v2\n", + progname); + return 0; + } + + fprintf(stderr, + "%s: cannot open either stk500v1 or stk500v2 programmer\n", + progname); + return -1; +} + +void stk500generic_initpgm(PROGRAMMER * pgm) +{ + strcpy(pgm->type, "STK500GENERIC"); + + pgm->open = stk500generic_open; +} diff --git a/stk500generic.h b/stk500generic.h new file mode 100644 index 00000000..89af83b1 --- /dev/null +++ b/stk500generic.h @@ -0,0 +1,29 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2006 Joerg Wunsch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id$ */ + +#ifndef stk500generic_h__ +#define stk500generic_h__ + +void stk500generic_initpgm (PROGRAMMER * pgm); + +#endif + +