avrdude-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avrdude-dev] First release of stk500v2 patch


From: Erik Walthinsen
Subject: [avrdude-dev] First release of stk500v2 patch
Date: Sat, 12 Feb 2005 19:37:56 -0800
User-agent: Debian Thunderbird 1.0 (X11/20050116)

Attached is the first [early] public release of the stk500v2 patch for avrdude CVS as of 20050213-0330 GMT.

***** WARNING *****
If you value your chips, your programmer, or your life, don't use this patch yet unless you're sure you know what you're getting into. At this point it should be considered developers-only. Error detection is very much not fully implemented.
***** WARNING *****

At this point, it adds two new programmers, 'avrispv2' and 'stk500v2'. This will hopefully change later in the form of firmware autodetection, but for now that's what we got. There is no distinction at all between the two at this point, and there may never be, as the stk500v2 protocol will return a string (currently un-heeded) that says either "avrisp_2" or "stk500_2".

avrdude.conf now has about a dozen new parameters as required by the new protocol, all of which can be found in Atmel's XML part descriptions. I'll see if I can make a script up at some point to import all of the values for all of the chips, but for now the only ones I've updated are the atmega8 and atmega48 (my main reason for doing this work is because I'm running out of atmega8's and just bought 25 atmega48's.....).

WARNING: if you're not using an atmega8 or atmega48, not only

All basic operations succeed except for paged-mode readback, which for some reason I haven't tracked down yet returns the first page correctly, but all subsequent pages are just sequential numbers. However, this is not critical as it does indeed program the chip properly to the best of my knowledge. I've programmed both an atmega8 and an atmega48 many times so far, and they all work (though I can't get the atmega48 serial port to behave properly with my ported code, I'm 99.9% certain it's becuse I've missed some little detail in porting from the atmega8. however, everything else that's visible does work).

So, with those caveats, I'm back to a) trying to get my code ported to the atmega48, and b) getting the readback to work right.

TTYL,
    Omega
    aka Erik Walthinsen
    address@hidden
Index: Makefile.am
===================================================================
RCS file: /cvsroot/avrdude/avrdude/Makefile.am,v
retrieving revision 1.23
diff -u -r1.23 Makefile.am
--- Makefile.am 10 Feb 2005 14:54:57 -0000      1.23
+++ Makefile.am 13 Feb 2005 03:22:11 -0000
@@ -85,6 +85,9 @@
        stk500.c \
        stk500.h \
        stk500_private.h \
+       stk500v2.c \
+       stk500v2.h \
+       stk500v2_private.h \
        term.c \
        term.h
 
Index: avrdude.conf.in
===================================================================
RCS file: /cvsroot/avrdude/avrdude/avrdude.conf.in,v
retrieving revision 1.36
diff -u -r1.36 avrdude.conf.in
--- avrdude.conf.in     22 Dec 2004 01:30:30 -0000      1.36
+++ avrdude.conf.in     13 Feb 2005 03:22:13 -0000
@@ -15,7 +15,7 @@
 #   programmer
 #       id       = <id1> [, <id2> [, <id3>] ...] ;  # <idN> are quoted strings
 #       desc     = <description> ;                  # quoted string
-#       type     = par | stk500 | avr910;           # programmer type
+#       type     = par | stk500 | stk500v2 | avr910; # programmer type
 #       baudrate = <num> ;                          # baudrate for 
avr910-programmer
 #       vcc      = <num1> [, <num2> ... ] ;         # pin number(s)
 #       reset    = <num> ;                          # pin number
@@ -209,12 +209,24 @@
 ;
 
 programmer
+  id    = "avrispv2";
+  desc  = "Atmel AVR ISP V2";
+  type  =  stk500v2;
+;
+
+programmer
   id    = "stk500";
   desc  = "Atmel STK500";
   type  = stk500;
 ;
 
 programmer
+  id    = "stk500v2";
+  desc  = "Atmel STK500 V2";
+  type  = stk500v2;
+;
+
+programmer
   id    = "avr910";
   desc  = "Atmel Low Cost Serial Programmer";
   type  = avr910;
Index: avrpart.c
===================================================================
RCS file: /cvsroot/avrdude/avrdude/avrpart.c,v
retrieving revision 1.4
diff -u -r1.4 avrpart.c
--- avrpart.c   22 Dec 2004 01:52:45 -0000      1.4
+++ avrpart.c   13 Feb 2005 03:22:13 -0000
@@ -292,23 +292,23 @@
   char * optr;
 
   if (m == NULL) {
-    fprintf(f,
-            "%s                          Page                       Polled\n"
-            "%sMemory Type Paged  Size   Size #Pages MinW  MaxW   ReadBack\n"
-            "%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
+      fprintf(f,
+              "%s                       Block Poll               Page          
             Polled\n"
+              "%sMemory Type Mode Delay Size  Indx Paged  Size   Size #Pages 
MinW  MaxW   ReadBack\n"
+              "%s----------- ---- ----- ----- ---- ------ ------ ---- ------ 
----- ----- ---------\n",
             prefix, prefix, prefix);
   }
   else {
     if (verbose > 2) {
       fprintf(f,
-              "%s                          Page                       Polled\n"
-              "%sMemory Type Paged  Size   Size #Pages MinW  MaxW   ReadBack\n"
-              "%s----------- ------ ------ ---- ------ ----- ----- 
---------\n",
+              "%s                       Block Poll               Page          
             Polled\n"
+              "%sMemory Type Mode Delay Size  Indx Paged  Size   Size #Pages 
MinW  MaxW   ReadBack\n"
+              "%s----------- ---- ----- ----- ---- ------ ------ ---- ------ 
----- ----- ---------\n",
               prefix, prefix, prefix);
     }
     fprintf(f,
-            "%s%-11s %-6s %6d %4d %5d %5d %5d 0x%02x 0x%02x\n",
-            prefix, m->desc,
+            "%s%-11s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
+            prefix, m->desc, m->mode, m->delay, m->blocksize, m->pollindex,
             m->paged ? "yes" : "no",
             m->size,
             m->page_size,
@@ -486,6 +486,13 @@
           "%sRETRY pulse           : %s\n"
           "%sserial program mode   : %s\n"
           "%sparallel program mode : %s\n"
+          "%sTimeout               : %d\n"
+          "%sStabDelay             : %d\n"
+          "%sCmdexeDelay           : %d\n"
+          "%sSyncLoops             : %d\n"
+          "%sByteDelay             : %d\n"
+          "%sPollIndex             : %d\n"
+          "%sPollValue             : 0x%02x\n"
           "%sMemory Detail         :\n\n",
           prefix, p->desc,
           prefix, p->chip_erase_delay,
@@ -496,6 +503,13 @@
           prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
           prefix, (p->flags & AVRPART_PARALLELOK) ?
             ((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
+          prefix, p->timeout,
+          prefix, p->stabdelay,
+          prefix, p->cmdexedelay,
+          prefix, p->synchloops,
+          prefix, p->bytedelay,
+          prefix, p->pollindex,
+          prefix, p->pollvalue,
           prefix);
 
   px = prefix;
Index: avrpart.h
===================================================================
RCS file: /cvsroot/avrdude/avrdude/avrpart.h,v
retrieving revision 1.16
diff -u -r1.16 avrpart.h
--- avrpart.h   22 Dec 2004 01:52:45 -0000      1.16
+++ avrpart.h   13 Feb 2005 03:22:13 -0000
@@ -94,6 +94,17 @@
                                        this pin (PIN_AVR_*) */
   unsigned      flags;              /* see AVRPART_ masks */
 
+  int           timeout;            /* stk500 v2 xml file parameter */
+  int           stabdelay;          /* stk500 v2 xml file parameter */
+  int           cmdexedelay;        /* stk500 v2 xml file parameter */
+  int           synchloops;         /* stk500 v2 xml file parameter */
+  int           bytedelay;          /* stk500 v2 xml file parameter */
+  int           pollindex;          /* stk500 v2 xml file parameter */
+  unsigned char pollvalue;          /* stk500 v2 xml file parameter */
+  int           predelay;           /* stk500 v2 xml file parameter */
+  int           postdelay;          /* stk500 v2 xml file parameter */
+  int           pollmethod;         /* stk500 v2 xml file parameter */
+
   OPCODE      * op[AVR_OP_MAX];     /* opcodes */
 
   LISTID        mem;                /* avr memory definitions */
@@ -115,6 +126,12 @@
                                  back on, see errata
                                  
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
   unsigned char readback[2];  /* polled read-back values */
+
+  int mode;                   /* stk500 v2 xml file parameter */
+  int delay;                  /* stk500 v2 xml file parameter */
+  int blocksize;              /* stk500 v2 xml file parameter */
+  int pollindex;              /* stk500 v2 xml file parameter */
+  
   unsigned char * buf;        /* pointer to memory buffer */
   OPCODE * op[AVR_OP_MAX];    /* opcodes */
 } AVRMEM;
Index: config_gram.y
===================================================================
RCS file: /cvsroot/avrdude/avrdude/config_gram.y,v
retrieving revision 1.39
diff -u -r1.39 config_gram.y
--- config_gram.y       22 Dec 2004 01:52:45 -0000      1.39
+++ config_gram.y       13 Feb 2005 03:22:14 -0000
@@ -33,6 +33,7 @@
 #include "ppi.h"
 #include "pgm.h"
 #include "stk500.h"
+#include "stk500v2.h"
 #include "avr910.h"
 #include "butterfly.h"
 #include "avr.h"
@@ -111,6 +112,7 @@
 %token K_SCK
 %token K_SIZE
 %token K_STK500
+%token K_STK500V2
 %token K_AVR910
 %token K_BUTTERFLY
 %token K_TYPE
@@ -121,6 +123,22 @@
 %token K_NO
 %token K_YES
 
+/* stk500 v2 xml file parameters */
+%token K_TIMEOUT
+%token K_STABDELAY
+%token K_CMDEXEDELAY
+%token K_SYNCHLOOPS
+%token K_BYTEDELAY
+%token K_POLLVALUE
+%token K_POLLINDEX
+%token K_PREDELAY
+%token K_POSTDELAY
+%token K_POLLMETHOD
+%token K_MODE
+%token K_DELAY
+%token K_BLOCKSIZE
+
+
 %token TKN_COMMA
 %token TKN_EQUAL
 %token TKN_SEMI
@@ -296,6 +314,12 @@
     }
   } |
 
+  K_TYPE TKN_EQUAL K_STK500V2 {
+    { 
+      stk500v2_initpgm(current_prog);
+    }
+  } |
+
   K_TYPE TKN_EQUAL K_AVR910 {
     { 
       avr910_initpgm(current_prog);
@@ -483,6 +507,69 @@
       free_tokens(2, $1, $3);
     } |
 
+    
+  K_TIMEOUT TKN_EQUAL TKN_NUMBER
+    {
+      current_part->timeout = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_STABDELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_part->stabdelay = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_part->cmdexedelay = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
+    {
+      current_part->synchloops = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_BYTEDELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_part->bytedelay = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_POLLVALUE TKN_EQUAL TKN_NUMBER
+    {
+      current_part->pollvalue = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_POLLINDEX TKN_EQUAL TKN_NUMBER
+    {
+      current_part->pollindex = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_PREDELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_part->predelay = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_POSTDELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_part->postdelay = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_POLLMETHOD TKN_EQUAL TKN_NUMBER
+    {
+      current_part->pollmethod = $3->value.number;
+      free_token($3);
+    } |
+    
+
+    
   K_SERIAL TKN_EQUAL yesno
     {
       if ($3->primary == K_YES)
@@ -630,6 +717,32 @@
       free_token($3);
     } |
 
+    
+  K_MODE TKN_EQUAL TKN_NUMBER
+    {
+      current_mem->mode = $3->value.number;
+      free_token($3);
+    } |
+    
+  K_DELAY TKN_EQUAL TKN_NUMBER
+    {
+      current_mem->delay = $3->value.number;
+      free_token($3);
+    } |
+
+  K_BLOCKSIZE TKN_EQUAL TKN_NUMBER
+    {
+      current_mem->blocksize = $3->value.number;
+      free_token($3);
+    } |
+
+  K_POLLINDEX TKN_EQUAL TKN_NUMBER
+    {
+      current_mem->pollindex = $3->value.number;
+      free_token($3);
+    } |
+
+    
   opcode TKN_EQUAL string_list {
     { 
       int opnum;
Index: lexer.l
===================================================================
RCS file: /cvsroot/avrdude/avrdude/lexer.l,v
retrieving revision 1.30
diff -u -r1.30 lexer.l
--- lexer.l     22 Dec 2004 01:52:45 -0000      1.30
+++ lexer.l     13 Feb 2005 03:22:14 -0000
@@ -115,19 +115,20 @@
          exit(1); }
 }
 
+avr910           { yylval=NULL; return K_AVR910; }
+avr910_devcode   { yylval=NULL; return K_AVR910_DEVCODE; }
 bank_size        { yylval=NULL; return K_PAGE_SIZE; }
 banked           { yylval=NULL; return K_PAGED; }
 baudrate         { yylval=NULL; return K_BAUDRATE; }
 bs2              { yylval=NULL; return K_BS2; }
 buff             { yylval=NULL; return K_BUFF; }
+butterfly        { yylval=NULL; return K_BUTTERFLY; }
 chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
 desc             { yylval=NULL; return K_DESC; }
 default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
 default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
 default_serial   { yylval=NULL; return K_DEFAULT_SERIAL; }
 devicecode       { yylval=NULL; return K_DEVICECODE; }
-stk500_devcode   { yylval=NULL; return K_STK500_DEVCODE; }
-avr910_devcode   { yylval=NULL; return K_AVR910_DEVCODE; }
 eeprom           { yylval=NULL; return K_EEPROM; }
 errled           { yylval=NULL; return K_ERRLED; }
 flash            { yylval=NULL; return K_FLASH; }
@@ -155,12 +156,29 @@
 serial           { yylval=NULL; return K_SERIAL; }
 size             { yylval=NULL; return K_SIZE; }
 stk500           { yylval=NULL; return K_STK500; }
+stk500v2         { yylval=NULL; return K_STK500V2; }
+stk500_devcode   { yylval=NULL; return K_STK500_DEVCODE; }
 avr910           { yylval=NULL; return K_AVR910; }
 butterfly        { yylval=NULL; return K_BUTTERFLY; }
 type             { yylval=NULL; return K_TYPE; }
 vcc              { yylval=NULL; return K_VCC; }
 vfyled           { yylval=NULL; return K_VFYLED; }
 
+timeout          { yylval=NULL; return K_TIMEOUT; }
+stabdelay        { yylval=NULL; return K_STABDELAY; }
+cmdexedelay      { yylval=NULL; return K_CMDEXEDELAY; }
+synchloops       { yylval=NULL; return K_SYNCHLOOPS; }
+bytedelay        { yylval=NULL; return K_BYTEDELAY; }
+pollvalue        { yylval=NULL; return K_POLLVALUE; }
+pollindex        { yylval=NULL; return K_POLLINDEX; }
+predelay         { yylval=NULL; return K_PREDELAY; }
+postdelay        { yylval=NULL; return K_POSTDELAY; }
+pollmethod       { yylval=NULL; return K_POLLMETHOD; }
+mode             { yylval=NULL; return K_MODE; }
+delay            { yylval=NULL; return K_DELAY; }
+blocksize        { yylval=NULL; return K_BLOCKSIZE; }
+
+
 
 dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
 io               { yylval=new_token(K_IO); return K_IO; }
--- stk500v2.c  1969-12-31 16:00:00.000000000 -0800
+++ /stk500v2.c 2005-02-12 19:12:35.000000000 -0800
@@ -0,0 +1,943 @@
+#if 0
+#define DEBUG(format,args...) fprintf(stderr, format, ## args)
+#else
+#define DEBUG(format,args...)
+#endif
+
+#if 0
+#define DEBUGRECV(format,args...) fprintf(stderr, format, ## args)
+#else
+#define DEBUGRECV(format,args...)
+#endif
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <address@hidden>
+ *
+ * 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: stk500v2.c,v 1.46 2004/12/22 01:52:45 bdean Exp $ */
+
+/*
+ * avrdude interface for Atmel STK500V2 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 "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "avr.h"
+#include "pgm.h"
+#include "stk500_private.h"    // temp until all code converted
+#include "stk500v2_private.h"
+#include "serial.h"
+
+#define STK500V2_XTAL 7372800U
+
+
+extern int    verbose;
+extern char * progname;
+extern int do_cycles;
+
+static unsigned char command_sequence = 1;
+
+
+static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned 
char * value);
+static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned 
char value);
+static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p);
+static int stk500v2_is_page_empty(unsigned int address, int page_size, 
+                                  const unsigned char *buf);
+
+
+static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+  unsigned char buf[275 + 6];          // max MESSAGE_BODY of 275 bytes, 6 
bytes overhead
+  int i;
+
+  buf[0] = MESSAGE_START;
+  buf[1] = command_sequence;
+  buf[2] = len / 256;
+  buf[3] = len % 256;
+  buf[4] = TOKEN;
+  memcpy(buf+5, data, len);
+
+  // calculate the XOR checksum
+  buf[5+len] = 0;
+  for (i=0;i<5+len;i++)
+    buf[5+len] ^= buf[i];
+
+  DEBUG("STK500V2: stk500v2_send(");
+  for (i=0;i<len+6;i++) DEBUG("0x%02x ",buf[i]);
+  DEBUG(", %d)\n",len+6);
+
+  if (serial_send(pgm->fd, buf, len+6) != 0) {
+    fprintf(stderr,"%s: stk500_send(): failed to send command to serial 
port\n",progname);
+    exit(1);
+  }
+
+  return 0;
+}
+
+
+static int stk500v2_drain(PROGRAMMER * pgm, int display)
+{
+  return serial_drain(pgm->fd, display);
+}
+
+
+static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t 
maxsize) {
+  enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, 
sDONE }  state = sSTART;
+  int msglen = 0;
+  int curlen = 0;
+  int timeout = 0;
+  unsigned char c, checksum = 0;
+
+  long timeoutval = 5;         // seconds
+  struct timeval tv;
+  double tstart, tnow;
+
+  DEBUG("STK500V2: stk500v2_recv(): ");
+
+  gettimeofday(&tv, NULL);
+  tstart = tv.tv_sec;
+
+  while ( (state != sDONE ) && (!timeout) ) {
+    serial_recv(pgm->fd, &c, 1);
+    DEBUG("0x%02x ",c);
+    checksum ^= c;
+
+    switch (state) {
+      case sSTART:
+        DEBUGRECV("hoping for start token...");
+        if (c == MESSAGE_START) {
+          DEBUGRECV("got it\n");
+          checksum = MESSAGE_START;
+          state = sSEQNUM;
+        } else
+          DEBUGRECV("sorry\n");
+        break;
+      case sSEQNUM:
+        DEBUGRECV("hoping for sequence...\n");
+        if (c == command_sequence) {
+          DEBUGRECV("got it, incrementing\n");
+          state = sSIZE1;
+          command_sequence++;
+        } else {
+          DEBUGRECV("sorry\n");
+          state = sSTART;
+        }
+        break;
+      case sSIZE1:
+        DEBUGRECV("hoping for size LSB\n");
+        msglen = c*256;
+        state = sSIZE2;
+        break;
+      case sSIZE2:
+        DEBUGRECV("hoping for size MSB...");
+        msglen += c;
+        DEBUG(" msg is %d bytes\n",msglen);
+        state = sTOKEN;
+        break;
+      case sTOKEN:
+        if (c == TOKEN) state = sDATA;
+        else state = sSTART;
+        break;
+      case sDATA:
+        if (curlen < maxsize) {
+          msg[curlen] = c;
+        } else {
+          fprintf(stderr, "%s: stk500v2_recv(): buffer too small, received %d 
byte into %d byte buffer\n",
+                  progname,curlen,maxsize);
+          return -2;
+        }
+        if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR)) {
+          fprintf(stderr, "%s: stk500v2_recv(): previous packet sent with 
wrong checksum\n",
+                  progname);
+          return -3;
+        }
+        curlen++;
+        if (curlen == msglen) state = sCSUM;
+        break;
+      case sCSUM:
+        if (checksum == 0) {
+          state = sDONE;
+        } else {
+          state = sSTART;
+          fprintf(stderr, "%s: stk500v2_recv(): checksum error\n",
+                  progname);
+          return -4;
+        }
+        break;
+      default:
+        fprintf(stderr, "%s: stk500v2_recv(): unknown state\n",
+                progname);
+        return -5;
+     } /* switch */
+
+     gettimeofday(&tv, NULL);
+     tnow = tv.tv_sec;
+     if (tnow-tstart > timeoutval) {                   // wuff - 
signed/unsigned/overflow
+       fprintf(stderr, "%s: stk500_2_ReceiveMessage(): timeout\n",
+               progname);
+       return -1;
+     }
+
+  } /* while */
+  DEBUG("\n");
+
+  return msglen+6;
+}
+
+
+
+static int stk500v2_getsync(PROGRAMMER * pgm) {
+  int tries = 0;
+  unsigned char buf[1], resp[32];
+  int status;
+
+  DEBUG("STK500V2: stk500v2_getsync()\n");
+
+retry:
+  tries++;
+
+  // send the sync command and see if we can get there
+  buf[0] = CMD_SIGN_ON;
+  stk500v2_send(pgm, buf, 1);
+
+  // try to get the response back and see where we got
+  status = stk500v2_recv(pgm, resp, sizeof(resp));
+
+  // if we got bytes returned, check to see what came back
+  if (status > 0) {
+    if (resp[0] == STATUS_CMD_OK) {
+      // success!
+      return 0;
+    } else {
+      if (tries > 33) {
+        fprintf(stderr, 
+                "%s: stk500v2_getsync(): can't communicate with device: 
resp=0x%02x\n",
+                progname, resp[0]);
+        return -6;
+      } else
+        goto retry;
+    }
+
+  // or if we got a timeout
+  } else if (status == -1) {
+    if (tries > 33) {
+      fprintf(stderr,"%s: stk500v2_getsync(): timeout communicating with 
programmer\n",
+              progname);
+      return -1;
+    } else
+      goto retry;
+
+  // or any other error
+  } else {
+    if (tries > 33) {
+      fprintf(stderr,"%s: stk500v2_getsync(): error communicating with 
programmer: (%d)\n",
+              progname,status);
+    } else
+      goto retry;
+  }
+
+  return 0;
+}
+
+static int stk500v2_command(PROGRAMMER * pgm, char * buf, size_t len, size_t 
maxlen) {
+  int i;
+  int tries = 0;
+  int status;
+
+  DEBUG("STK500V2: stk500v2_command(");
+  for (i=0;i<len;i++) DEBUG("0x%02hhx ",buf[i]);
+  DEBUG(", %d)\n",len);
+
+retry:
+  tries++;
+
+  // send the command to the programmer
+  stk500v2_send(pgm,buf,len);
+
+  // attempt to read the status back
+  status = stk500v2_recv(pgm,buf,maxlen);
+
+  // if we got a successful readback, return
+  if (status > 0) {
+    DEBUG(" = %d\n",status);
+    return status;
+  }
+
+  // otherwise try to sync up again
+  status = stk500v2_getsync(pgm);
+  if (status != 0) {
+    if (tries > 33) {
+      fprintf(stderr,"%s: stk500v2_command(): failed miserably to execute 
command 0x%02x\n",
+              progname,buf[0]);
+      return -1;
+    } else
+      goto retry;
+  }
+
+  DEBUG(" = 0\n");
+  return 0;
+}
+
+static int stk500v2_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
+                        unsigned char res[4])
+{
+  unsigned char buf[8];
+  int result;
+
+  DEBUG("STK500V2: 
stk500v2_cmd(%02x,%02x,%02x,%02x)\n",cmd[0],cmd[1],cmd[2],cmd[3]);
+
+  buf[0] = CMD_SPI_MULTI;
+  buf[1] = 4;
+  buf[2] = 4;
+  buf[3] = 0;
+  buf[4] = cmd[0];
+  buf[5] = cmd[1];
+  buf[6] = cmd[2];
+  buf[7] = cmd[3];
+
+  result = stk500v2_command(pgm, buf, 8, sizeof(buf));
+  if (buf[1] != STATUS_CMD_OK) {
+    fprintf(stderr, "%s: stk500v2_cmd(): failed to send command\n",
+            progname);
+    return -1;
+  }
+
+  res[0] = buf[2];
+  res[1] = buf[3];
+  res[2] = buf[4];
+  res[3] = buf[5];
+
+  return 0;
+}
+
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+  int result;
+  unsigned char buf[16];
+
+  if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+    fprintf(stderr, "%s: stk500v2_chip_erase: chip erase instruction not 
defined for part \"%s\"\n",
+            progname, p->desc);
+    return -1;
+  }
+
+  pgm->pgm_led(pgm, ON);
+
+  buf[0] = CMD_CHIP_ERASE_ISP;
+  buf[1] = p->chip_erase_delay / 1000;
+  buf[2] = 0;  // use delay (?)
+  avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf+3);
+  result = stk500v2_command(pgm, buf, 7, sizeof(buf));
+  usleep(p->chip_erase_delay);
+  pgm->initialize(pgm, p);
+
+  pgm->pgm_led(pgm, OFF);
+
+  return result;
+}
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+  unsigned char buf[16];
+
+  if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+    fprintf(stderr, "%s: stk500v2_program_enable(): program enable instruction 
not defined for part \"%s\"\n",
+            progname, p->desc);
+    return -1;
+  }
+
+  buf[0] = CMD_ENTER_PROGMODE_ISP;
+  buf[1] = p->timeout;
+  buf[2] = p->stabdelay;
+  buf[3] = p->cmdexedelay;
+  buf[4] = p->synchloops;
+  buf[5] = p->bytedelay;
+  buf[6] = p->pollvalue;
+  buf[7] = p->pollindex;
+  avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf+8);
+
+  return stk500v2_command(pgm, buf, 12, sizeof(buf));
+}
+
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+  return pgm->program_enable(pgm, p);
+}
+
+
+static void stk500v2_disable(PROGRAMMER * pgm)
+{
+  unsigned char buf[16];
+  int result;
+
+  buf[0] = CMD_LEAVE_PROGMODE_ISP;
+  buf[1] = 1; // preDelay;
+  buf[2] = 1; // postDelay;
+
+  result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+
+  if (buf[1] != STATUS_CMD_OK) {
+    fprintf(stderr, "%s: stk500v2_disable(): failed to leave programming mode, 
got 0x%02x\n",
+            progname,buf[1]);
+    exit(1);
+  }
+
+  return;
+}
+
+static void stk500v2_enable(PROGRAMMER * pgm)
+{
+  return;
+}
+
+
+static int stk500v2_open(PROGRAMMER * pgm, char * port)
+{
+  DEBUG("STK500V2: stk500v2_open()\n");
+
+  strcpy(pgm->port, port);
+  if (pgm->baudrate)
+    pgm->fd = serial_open(port, pgm->baudrate);
+  else
+    pgm->fd = serial_open(port, 115200);
+
+  /*
+   * drain any extraneous input
+   */
+  stk500v2_drain(pgm, 0);
+
+  stk500v2_getsync(pgm);
+
+  stk500v2_drain(pgm, 0);
+
+  return 0;
+}
+
+
+static void stk500v2_close(PROGRAMMER * pgm)
+{
+  DEBUG("STK500V2: stk500v2_close()\n");
+
+  serial_close(pgm->fd);
+  pgm->fd = -1;
+}
+
+
+static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
+{
+  unsigned char buf[16];
+  int result;
+
+  DEBUG("STK500V2: stk500v2_loadaddr\n");
+
+  buf[0] = CMD_LOAD_ADDRESS;
+  buf[1] = (addr >> 24) & 0xff;
+  buf[2] = (addr >> 16) & 0xff;
+  buf[3] = (addr >> 8) & 0xff;
+  buf[4] = addr & 0xff;
+
+  result = stk500v2_command(pgm, buf, 5, sizeof(buf));
+
+  if (buf[1] != STATUS_CMD_OK) {
+    fprintf(stderr, "%s: stk500v2_loadaddr(): failed to set load address, got 
0x%02x\n",
+            progname,buf[1]);
+    return -1;
+  }
+
+  return 0;
+}
+
+
+static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
+                              int page_size, int n_bytes)
+{
+  int addr, block_size;
+  unsigned char buf[266];
+  unsigned char cmds[4];
+  int result;
+
+  DEBUG("STK500V2: 
stk500v2_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+
+  if (page_size == 0) page_size = 256;
+
+  // determine which command is to be used
+  if (strcmp(m->desc, "flash") == 0) {
+    buf[0] = CMD_PROGRAM_FLASH_ISP;
+  } else if (strcmp(m->desc, "eeprom") == 0) {
+    buf[0] = CMD_PROGRAM_EEPROM_ISP;
+  }
+  buf[4] = m->delay;
+
+  // if the memory is paged, load the appropriate commands into the buffer
+  if (m->mode & 0x01) {
+    buf[3] = m->mode & 0x80;           // yes, write the stupid page to flash
+
+    if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
+      fprintf(stderr, "%s: stk500v2_paged_write: loadpage instruction not 
defined for part \"%s\"\n",
+              progname, p->desc);
+      return -1;
+    }
+    avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], cmds);
+    buf[5] = cmds[0];
+
+    if (m->op[AVR_OP_WRITEPAGE] == NULL) {
+      fprintf(stderr, "%s: stk500v2_paged_write: write page instruction not 
defined for part \"%s\"\n",
+              progname, p->desc);
+      return -1;
+    }
+    avr_set_bits(m->op[AVR_OP_WRITEPAGE], cmds);
+    buf[6] = cmds[0];
+
+  // otherwise, we need to load different commands in
+  } else {
+    buf[3] = m->mode & 0x80;           // yes, write the stupid words to flash
+
+    if (m->op[AVR_OP_WRITE_LO] == NULL) {
+      fprintf(stderr, "%s: stk500v2_paged_write: write instruction not defined 
for part \"%s\"\n",
+              progname, p->desc);
+      return -1;
+    }
+    avr_set_bits(m->op[AVR_OP_WRITE_LO], cmds);
+    buf[6] = cmds[0];
+
+  }
+
+  // the read command is common to both methods
+  if (m->op[AVR_OP_READ_LO] == NULL) {
+    fprintf(stderr, "%s: stk500v2_paged_write: read instruction not defined 
for part \"%s\"\n",
+            progname, p->desc);
+    return -1;
+  }
+  avr_set_bits(m->op[AVR_OP_READ_LO], cmds);
+  buf[7] = cmds[0];
+
+
+  buf[8] = m->readback[0];
+  buf[9] = m->readback[1];
+
+  stk500v2_loadaddr(pgm, 0);
+
+  for (addr=0; addr < n_bytes; addr += page_size) {
+    report_progress(addr,n_bytes,NULL);
+
+    if ((n_bytes-addr) < page_size)
+      block_size = n_bytes - addr;
+    else
+      block_size = page_size;
+    DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+    buf[1] = block_size >> 8;
+    buf[2] = block_size & 0xff;
+
+    memcpy(buf+10,m->buf+addr, block_size);
+
+    result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));
+    if (buf[1] != STATUS_CMD_OK) {
+      fprintf(stderr,"%s: stk500v2_paged_write: write command failed with 
%d\n",
+              progname,buf[1]);
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+static int stk500v2_is_page_empty(unsigned int address, int page_size, 
+                                const unsigned char *buf)
+{
+    int i;
+    for(i = 0; i < page_size; i++) {
+        if(buf[address + i] != 0xFF) {
+            /* Page is not empty. */
+            return(0);
+        }
+    }
+    
+    /* Page is empty. */
+    return(1);
+}
+
+static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
+                             int page_size, int n_bytes)
+{
+  int addr, block_size;
+  unsigned char buf[275];      // max buffer size for stk500v2 at this point
+  unsigned char cmds[4];
+  int result, i;
+
+  DEBUG("STK500V2: 
stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+
+  if (page_size == 0) page_size = 256;
+
+  // determine which command is to be used
+  if (strcmp(m->desc, "flash") == 0) {
+    buf[0] = CMD_READ_FLASH_ISP;
+  } else if (strcmp(m->desc, "eeprom") == 0) {
+    buf[0] = CMD_READ_EEPROM_ISP;
+  }
+
+  // the read command is common to both methods
+  if (m->op[AVR_OP_READ_LO] == NULL) {
+    fprintf(stderr, "%s: stk500v2_paged_write: read instruction not defined 
for part \"%s\"\n",
+            progname, p->desc);
+    return -1;
+  }
+  avr_set_bits(m->op[AVR_OP_READ_LO], cmds);
+  buf[3] = cmds[0];
+
+  for (addr=0; addr < n_bytes; addr += page_size) {
+    report_progress(addr, n_bytes,NULL);
+
+    if ((n_bytes-addr) < page_size)
+      block_size = n_bytes - addr;
+    else
+      block_size = page_size;
+    DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+    buf[1] = block_size >> 8;
+    buf[2] = block_size & 0xff;
+
+    stk500v2_loadaddr(pgm, addr);
+
+    result = stk500v2_command(pgm,buf,4,sizeof(buf));
+    if (buf[1] != STATUS_CMD_OK) {
+      fprintf(stderr,"%s: stk500v2_paged_write: read command failed with %d\n",
+              progname,buf[1]);
+      return -1;
+    }
+#if 0
+    for (i=0;i<page_size;i++) {
+      fprintf(stderr,"%02X",buf[2+i]);
+      if (i%16 == 15) fprintf(stderr,"\n");
+    }
+#endif
+
+    memcpy(&m->buf[addr], &buf[2], block_size);
+  }
+
+  return 0;
+}
+
+
+static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
+{
+  unsigned char uaref, utarg;
+
+  utarg = (unsigned)((v + 0.049) * 10);
+
+  if (stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) {
+    fprintf(stderr,
+           "%s: stk500v2_set_vtarget(): cannot obtain V[aref]\n",
+           progname);
+    return -1;
+  }
+
+  if (uaref > utarg) {
+    fprintf(stderr,
+           "%s: stk500v2_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
+           progname, uaref / 10.0, v);
+    if (stk500v2_setparm(pgm, PARAM_VADJUST, utarg)
+       != 0)
+      return -1;
+  }
+  return stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
+}
+
+
+static int stk500v2_set_varef(PROGRAMMER * pgm, double v)
+{
+  unsigned char uaref, utarg;
+
+  uaref = (unsigned)((v + 0.049) * 10);
+
+  if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {
+    fprintf(stderr,
+           "%s: stk500v2_set_varef(): cannot obtain V[target]\n",
+           progname);
+    return -1;
+  }
+
+  if (uaref > utarg) {
+    fprintf(stderr,
+           "%s: stk500v2_set_varef(): V[aref] must not be greater than "
+           "V[target] = %.1f\n",
+           progname, utarg / 10.0);
+    return -1;
+  }
+  return stk500v2_setparm(pgm, PARAM_VADJUST, uaref);
+}
+
+
+static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
+{
+  int fosc;
+  unsigned char prescale, cmatch;
+  static unsigned ps[] = {
+    1, 8, 32, 64, 128, 256, 1024
+  };
+  int idx, rc;
+
+  prescale = cmatch = 0;
+  if (v > 0.0) {
+    if (v > STK500V2_XTAL / 2) {
+      const char *unit;
+      if (v > 1e6) {
+        v /= 1e6;
+        unit = "MHz";
+      } else if (v > 1e3) {
+        v /= 1e3;
+        unit = "kHz";
+      } else
+        unit = "Hz";
+      fprintf(stderr,
+          "%s: stk500v2_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
+          progname, v, unit, STK500V2_XTAL / 2e6);
+      fosc = STK500V2_XTAL / 2;
+    } else
+      fosc = (unsigned)v;
+    
+    for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
+      if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {
+        /* this prescaler value can handle our frequency */
+        prescale = idx + 1;
+        cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;
+        break;
+      }
+    }
+    if (idx == sizeof(ps) / sizeof(ps[0])) {
+      fprintf(stderr, "%s: stk500v2_set_fosc(): f = %u Hz too low, %u Hz 
min\n",
+          progname, fosc, STK500V2_XTAL / (256 * 1024 * 2));
+      return -1;
+    }
+  }
+  
+  if ((rc = stk500v2_setparm(pgm, PARAM_OSC_PSCALE, prescale)) != 0
+      || (rc = stk500v2_setparm(pgm, PARAM_OSC_CMATCH, cmatch)) != 0)
+    return rc;
+  
+  return 0;
+}
+
+
+/* This code assumes that each count of the SCK duration parameter
+   represents 8/f, where f is the clock frequency of the STK500V2 master
+   processors (not the target).  This number comes from Atmel
+   application note AVR061.  It appears that the STK500V2 bit bangs SCK.
+   For small duration values, the actual SCK width is larger than
+   expected.  As the duration value increases, the SCK width error
+   diminishes. */
+static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
+{
+  unsigned char dur;
+  double min, max;
+
+  min = 8.0 / STK500V2_XTAL;
+  max = 255 * min;
+  dur = v / min + 0.5;
+  
+  if (v < min) {
+      dur = 1;
+      fprintf(stderr,
+             "%s: stk500v2_set_sck_period(): p = %.1f us too small, using %.1f 
us\n",
+             progname, v / 1e-6, dur * min / 1e-6);
+  } else if (v > max) {
+      dur = 255;
+      fprintf(stderr,
+             "%s: stk500v2_set_sck_period(): p = %.1f us too large, using %.1f 
us\n",
+             progname, v / 1e-6, dur * min / 1e-6);
+  }
+  
+  return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);
+}
+
+
+static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned 
char * value)
+{
+  unsigned char buf[32];
+
+  buf[0] = CMD_GET_PARAMETER;
+  buf[1] = parm;
+
+  if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
+    fprintf(stderr,"%s: stk500v2_getparm(): failed to get parameter 0x%02x\n",
+            progname, parm);
+    return -1;
+  }
+
+  *value = buf[2];
+
+  return 0;
+}
+
+  
+static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned 
char value)
+{
+  unsigned char buf[32];
+
+  buf[0] = CMD_SET_PARAMETER;
+  buf[1] = parm;
+  buf[2] = value;
+
+  if (stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) {
+    fprintf(stderr, "\n%s: stk500v2_setparm(): failed to set parameter 
0x%02x\n",
+            progname, parm);
+    return -1;
+  }
+
+  return 0;
+}
+
+
+static void stk500v2_display(PROGRAMMER * pgm, char * p)
+{
+  unsigned char maj, min, hdw, topcard;
+  const char *topcard_name;
+
+  stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
+  stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
+  stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
+  stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard);
+
+  fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
+  fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
+
+  if (1) {                     // should check to see if it's a stk500 first
+    switch (topcard) {
+      case 0xAA: topcard_name = "STK501"; break;
+      case 0x55: topcard_name = "STK502"; break;
+      case 0xFA: topcard_name = "STK503"; break;
+      case 0xEE: topcard_name = "STK504"; break;
+      case 0xE4: topcard_name = "STK505"; break;
+      case 0xDD: topcard_name = "STK520"; break;
+      default: topcard_name = "Unknown"; break;
+    }
+    fprintf(stderr, "%sTopcard         : %s\n", p, topcard_name);
+  }
+  stk500v2_print_parms1(pgm, p);
+
+  return;
+}
+
+
+static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p)
+{
+  unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
+
+  stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
+  stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
+  stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
+  stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
+  stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
+
+  fprintf(stderr, "%sVtarget         : %.1f V\n", p, vtarget / 10.0);
+  fprintf(stderr, "%sVaref           : %.1f V\n", p, vadjust / 10.0);
+  fprintf(stderr, "%sOscillator      : ", p);
+  if (osc_pscale == 0)
+    fprintf(stderr, "Off\n");
+  else {
+    int prescale = 1;
+    double f = STK500V2_XTAL / 2;
+    const char *unit;
+
+    switch (osc_pscale) {
+      case 2: prescale = 8; break;
+      case 3: prescale = 32; break;
+      case 4: prescale = 64; break;
+      case 5: prescale = 128; break;
+      case 6: prescale = 256; break;
+      case 7: prescale = 1024; break;
+    }
+    f /= prescale;
+    f /= (osc_cmatch + 1);
+    if (f > 1e6) {
+      f /= 1e6;
+      unit = "MHz";
+    } else if (f > 1e3) {
+      f /= 1000;
+      unit = "kHz";
+    } else
+      unit = "Hz";
+    fprintf(stderr, "%.3f %s\n", f, unit);
+  }
+  fprintf(stderr, "%sSCK period      : %.1f us\n", p, 
+         sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
+
+  return;
+}
+
+
+static void stk500v2_print_parms(PROGRAMMER * pgm)
+{
+  stk500v2_print_parms1(pgm, "");
+}
+
+
+void stk500v2_initpgm(PROGRAMMER * pgm)
+{
+  strcpy(pgm->type, "STK500V2");
+
+  /*
+   * mandatory functions
+   */
+  pgm->initialize     = stk500v2_initialize;
+  pgm->display        = stk500v2_display;
+  pgm->enable         = stk500v2_enable;
+  pgm->disable        = stk500v2_disable;
+  pgm->program_enable = stk500v2_program_enable;
+  pgm->chip_erase     = stk500v2_chip_erase;
+  pgm->cmd            = stk500v2_cmd;
+  pgm->open           = stk500v2_open;
+  pgm->close          = stk500v2_close;
+
+  /*
+   * optional functions
+   */
+  pgm->paged_write    = stk500v2_paged_write;
+  pgm->paged_load     = stk500v2_paged_load;
+  pgm->print_parms    = stk500v2_print_parms;
+  pgm->set_vtarget    = stk500v2_set_vtarget;
+  pgm->set_varef      = stk500v2_set_varef;
+  pgm->set_fosc       = stk500v2_set_fosc;
+  pgm->set_sck_period = stk500v2_set_sck_period;
+  pgm->page_size      = 256;
+}
--- stk500v2.h  1969-12-31 16:00:00.000000000 -0800
+++ stk500v2.h  2005-01-30 16:16:49.000000000 -0800
@@ -0,0 +1,29 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004  Brian S. Dean <address@hidden>
+ *
+ * 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: stk500.h,v 1.9 2004/12/22 01:52:45 bdean Exp $ */
+
+#ifndef __stk500v2_h__
+#define __stk500v2_h__
+
+void stk500v2_initpgm (PROGRAMMER * pgm);
+
+#endif
+
+
--- stk500v2_private.h  1969-12-31 16:00:00.000000000 -0800
+++ stk500v2_private.h  2005-01-30 17:14:25.000000000 -0800
@@ -0,0 +1,134 @@
+//**** ATMEL AVR - A P P L I C A T I O N   N O T E  ************************
+//*
+//* Title:             AVR068 - STK500 Communication Protocol
+//* Filename:          command.h
+//* Version:           1.0
+//* Last updated:      10.01.2005
+//*
+//* Support E-mail:    address@hidden
+//*
+//**************************************************************************
+
+// *****************[ STK message constants ]***************************
+
+#define MESSAGE_START                       0x1B        //= ESC = 27 decimal
+#define TOKEN                               0x0E
+
+// *****************[ STK general command constants ]**************************
+
+#define CMD_SIGN_ON                         0x01
+#define CMD_SET_PARAMETER                   0x02
+#define CMD_GET_PARAMETER                   0x03
+#define CMD_SET_DEVICE_PARAMETERS           0x04
+#define CMD_OSCCAL                          0x05
+#define CMD_LOAD_ADDRESS                    0x06
+#define CMD_FIRMWARE_UPGRADE                0x07
+
+
+// *****************[ STK ISP command constants ]******************************
+
+#define CMD_ENTER_PROGMODE_ISP              0x10
+#define CMD_LEAVE_PROGMODE_ISP              0x11
+#define CMD_CHIP_ERASE_ISP                  0x12
+#define CMD_PROGRAM_FLASH_ISP               0x13
+#define CMD_READ_FLASH_ISP                  0x14
+#define CMD_PROGRAM_EEPROM_ISP              0x15
+#define CMD_READ_EEPROM_ISP                 0x16
+#define CMD_PROGRAM_FUSE_ISP                0x17
+#define CMD_READ_FUSE_ISP                   0x18
+#define CMD_PROGRAM_LOCK_ISP                0x19
+#define CMD_READ_LOCK_ISP                   0x1A
+#define CMD_READ_SIGNATURE_ISP              0x1B
+#define CMD_READ_OSCCAL_ISP                 0x1C
+#define CMD_SPI_MULTI                       0x1D
+
+// *****************[ STK PP command constants ]*******************************
+
+#define CMD_ENTER_PROGMODE_PP               0x20
+#define CMD_LEAVE_PROGMODE_PP               0x21
+#define CMD_CHIP_ERASE_PP                   0x22
+#define CMD_PROGRAM_FLASH_PP                0x23
+#define CMD_READ_FLASH_PP                   0x24
+#define CMD_PROGRAM_EEPROM_PP               0x25
+#define CMD_READ_EEPROM_PP                  0x26
+#define CMD_PROGRAM_FUSE_PP                 0x27
+#define CMD_READ_FUSE_PP                    0x28
+#define CMD_PROGRAM_LOCK_PP                 0x29
+#define CMD_READ_LOCK_PP                    0x2A
+#define CMD_READ_SIGNATURE_PP               0x2B
+#define CMD_READ_OSCCAL_PP                  0x2C    
+
+#define CMD_SET_CONTROL_STACK               0x2D
+
+// *****************[ STK HVSP command constants ]*****************************
+
+#define CMD_ENTER_PROGMODE_HVSP             0x30
+#define CMD_LEAVE_PROGMODE_HVSP             0x31
+#define CMD_CHIP_ERASE_HVSP                 0x32
+#define CMD_PROGRAM_FLASH_HVSP              0x33
+#define CMD_READ_FLASH_HVSP                 0x34
+#define CMD_PROGRAM_EEPROM_HVSP             0x35
+#define CMD_READ_EEPROM_HVSP                0x36
+#define CMD_PROGRAM_FUSE_HVSP               0x37
+#define CMD_READ_FUSE_HVSP                  0x38
+#define CMD_PROGRAM_LOCK_HVSP               0x39
+#define CMD_READ_LOCK_HVSP                  0x3A
+#define CMD_READ_SIGNATURE_HVSP             0x3B
+#define CMD_READ_OSCCAL_HVSP                0x3C
+
+// *****************[ STK test command constants ]***************************
+
+#define CMD_ENTER_TESTMODE                  0x60
+#define CMD_LEAVE_TESTMODE                  0x61
+#define CMD_CHIP_WRITE                      0x62
+#define CMD_PROGRAM_FLASH_PARTIAL           0x63
+#define CMD_PROGRAM_EEPROM_PARTIAL          0x64
+#define CMD_PROGRAM_SIGNATURE_ROW           0x65
+#define CMD_READ_FLASH_MARGIN               0x66
+#define CMD_READ_EEPROM_MARGIN              0x67
+#define CMD_READ_SIGNATURE_ROW_MARGIN       0x68
+#define CMD_PROGRAM_TEST_FUSE               0x69
+#define CMD_READ_TEST_FUSE                  0x6A
+#define CMD_PROGRAM_HIDDEN_FUSE_LOW         0x6B
+#define CMD_READ_HIDDEN_FUSE_LOW            0x6C
+#define CMD_PROGRAM_HIDDEN_FUSE_HIGH        0x6D
+#define CMD_READ_HIDDEN_FUSE_HIGH           0x6E
+#define CMD_PROGRAM_HIDDEN_FUSE_EXT         0x6F
+#define CMD_READ_HIDDEN_FUSE_EXT            0x70
+
+// *****************[ STK status constants ]***************************
+
+// Success
+#define STATUS_CMD_OK                       0x00
+
+// Warnings
+#define STATUS_CMD_TOUT                     0x80
+#define STATUS_RDY_BSY_TOUT                 0x81
+#define STATUS_SET_PARAM_MISSING            0x82
+
+// Errors
+#define STATUS_CMD_FAILED                   0xC0
+#define STATUS_CKSUM_ERROR                  0xC1
+#define STATUS_CMD_UNKNOWN                  0xC9
+
+// *****************[ STK parameter constants ]***************************
+#define PARAM_BUILD_NUMBER_LOW              0x80
+#define PARAM_BUILD_NUMBER_HIGH             0x81
+#define PARAM_HW_VER                        0x90
+#define PARAM_SW_MAJOR                      0x91
+#define PARAM_SW_MINOR                      0x92
+#define PARAM_VTARGET                       0x94
+#define PARAM_VADJUST                       0x95
+#define PARAM_OSC_PSCALE                    0x96
+#define PARAM_OSC_CMATCH                    0x97
+#define PARAM_SCK_DURATION                  0x98
+#define PARAM_TOPCARD_DETECT                0x9A
+#define PARAM_STATUS                        0x9C
+#define PARAM_DATA                          0x9D
+#define PARAM_RESET_POLARITY                0x9E
+#define PARAM_CONTROLLER_INIT               0x9F
+
+// *****************[ STK answer constants ]***************************
+
+#define ANSWER_CKSUM_ERROR                  0xB0
+

reply via email to

[Prev in Thread] Current Thread [Next in Thread]