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
This commit is contained in:
Joerg Wunsch 2006-09-19 22:27:30 +00:00
parent 9747c576a3
commit bf388ff428
9 changed files with 215 additions and 44 deletions

View File

@ -1,3 +1,23 @@
2006-09-20 Joerg Wunsch <j@uriah.heep.sax.de>
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 <j@uriah.heep.sax.de>
* avrdude.conf.in: Various fixes for ancient processors and their

View File

@ -121,6 +121,8 @@ avrdude_SOURCES = \
stk500v2.c \
stk500v2.h \
stk500v2_private.h \
stk500generic.c \
stk500generic.h \
term.c \
term.h \
usbasp.c \

View File

@ -15,7 +15,7 @@
# programmer
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
# desc = <description> ; # 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 = <num> ; # 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

View File

@ -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);

View File

@ -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

View File

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

114
stk500.c
View File

@ -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",

72
stk500generic.c Normal file
View File

@ -0,0 +1,72 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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 <stdio.h>
#include <string.h>
#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;
}

29
stk500generic.h Normal file
View File

@ -0,0 +1,29 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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