From 8ba95cd0c33fbd999953397ee4a62c46662e5f1e Mon Sep 17 00:00:00 2001
From: "Brian S. Dean" <bsd@bsdhome.com>
Date: Fri, 21 Feb 2003 17:24:47 +0000
Subject: [PATCH] Add the ability to specify which pin to pulse when retrying
 entry into programming mode.  Use 'retry_pulse' in the per-part specification
 that can currently take values of 'reset' or 'sck', the default being 'sck'
 which preserves the previous behaviour.  Some newer parts indicate that
 /RESET should be pulsed, while older parts say to pulse SCK.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@212 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avr.c         | 15 +++++++++++++++
 avrpart.h     |  2 ++
 config_gram.y | 28 +++++++++++++++++++++++++---
 lexer.l       | 17 ++++++++++-------
 par.c         |  2 +-
 stk500.c      |  2 +-
 6 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/avr.c b/avr.c
index 5d322cff..4ef15439 100644
--- a/avr.c
+++ b/avr.c
@@ -58,6 +58,7 @@ AVRPART * avr_new_part(void)
   p->id[0]   = 0;
   p->desc[0] = 0;
   p->reset_disposition = RESET_DEDICATED;
+  p->retry_pulse = PIN_AVR_SCK;
   p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;
 
   p->mem = lcreat(NULL, 0);
@@ -1065,6 +1066,18 @@ char * reset_disp_str(int r)
 }
 
 
+char * pin_name(int pinno)
+{
+  switch (pinno) {
+    case PIN_AVR_RESET : return "RESET";
+    case PIN_AVR_MISO  : return "MISO";
+    case PIN_AVR_MOSI  : return "MOSI";
+    case PIN_AVR_SCK   : return "SCK";
+    default : return "<unknown>";
+  }
+}
+
+
 void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
 {
   int i;
@@ -1079,6 +1092,7 @@ void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
           "%sPAGEL                 : P%02X\n"
           "%sBS2                   : P%02X\n"
           "%sRESET disposition     : %s\n"
+          "%sRETRY pulse           : %s\n"
           "%sserial program mode   : %s\n"
           "%sparallel program mode : %s\n"
           "%sMemory Detail         :\n\n",
@@ -1087,6 +1101,7 @@ void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
           prefix, p->pagel,
           prefix, p->bs2,
           prefix, reset_disp_str(p->reset_disposition),
+          prefix, pin_name(p->retry_pulse),
           prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
           prefix, (p->flags & AVRPART_PARALLELOK) ? 
             ((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
diff --git a/avrpart.h b/avrpart.h
index c788af66..3bc452e8 100644
--- a/avrpart.h
+++ b/avrpart.h
@@ -84,6 +84,8 @@ typedef struct avrpart {
   unsigned char pagel;              /* for parallel programming */
   unsigned char bs2;                /* for parallel programming */
   int           reset_disposition;  /* see RESET_ enums */
+  int           retry_pulse;        /* retry program enable by pulsing
+                                       this pin (PIN_AVR_*) */
   unsigned      flags;              /* see AVRPART_ masks */
 
   OPCODE      * op[AVR_OP_MAX];     /* opcodes */
diff --git a/config_gram.y b/config_gram.y
index 1685a5e3..4ed73bd2 100644
--- a/config_gram.y
+++ b/config_gram.y
@@ -93,6 +93,7 @@ static int parse_cmdbits(OPCODE * op);
 %token K_READBACK_P2
 %token K_READMEM
 %token K_RESET
+%token K_RETRY_PULSE
 %token K_SERIAL
 %token K_SCK
 %token K_SIZE
@@ -307,8 +308,10 @@ prog_parm :
     }
   } |
 
-  K_RESET  TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_RESET, $3); } |
-  K_SCK    TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_SCK, $3); } |
+  K_RESET  TKN_EQUAL TKN_NUMBER { free_token($1); 
+                                  assign_pin(PIN_AVR_RESET, $3); } |
+  K_SCK    TKN_EQUAL TKN_NUMBER { free_token($1); 
+                                  assign_pin(PIN_AVR_SCK, $3); } |
   K_MOSI   TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3); } |
   K_MISO   TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MISO, $3); } |
   K_ERRLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_ERR, $3); } |
@@ -347,6 +350,10 @@ parallel_modes :
   yesno | K_PSEUDO
 ;
 
+retry_lines :
+  K_RESET | K_SCK
+;
+
 part_parm :
   K_ID TKN_EQUAL TKN_STRING 
     {
@@ -394,7 +401,7 @@ part_parm :
       else if ($3->primary == K_IO)
         current_part->reset_disposition = RESET_IO;
 
-      free_token($3);
+      free_tokens(2, $1, $3);
     } |
 
   K_SERIAL TKN_EQUAL yesno
@@ -426,6 +433,21 @@ part_parm :
       free_token($3);
     } |
 
+  K_RETRY_PULSE TKN_EQUAL retry_lines
+    {
+      switch ($3->primary) {
+        case K_RESET :
+          current_part->retry_pulse = PIN_AVR_RESET;
+          break;
+        case K_SCK :
+          current_part->retry_pulse = PIN_AVR_SCK;
+          break;
+      }
+
+      free_token($1);
+    } |
+
+
 /*
   K_EEPROM { current_mem = AVR_M_EEPROM; }
     mem_specs |
diff --git a/lexer.l b/lexer.l
index a093b9aa..c9f2d91d 100644
--- a/lexer.l
+++ b/lexer.l
@@ -120,15 +120,14 @@ banked           { yylval=NULL; return K_PAGED; }
 bs2              { yylval=NULL; return K_BS2; }
 buff             { yylval=NULL; return K_BUFF; }
 chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
-dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
 desc             { yylval=NULL; return K_DESC; }
 devicecode       { yylval=NULL; return K_DEVICECODE; }
 eeprom           { yylval=NULL; return K_EEPROM; }
 errled           { yylval=NULL; return K_ERRLED; }
 flash            { yylval=NULL; return K_FLASH; }
 id               { yylval=NULL; return K_ID; }
-io               { yylval=new_token(K_IO); return K_IO; }
 max_write_delay  { yylval=NULL; return K_MAX_WRITE_DELAY; }
+memory           { yylval=NULL; return K_MEMORY; }
 min_write_delay  { yylval=NULL; return K_MIN_WRITE_DELAY; }
 miso             { yylval=NULL; return K_MISO; }
 mosi             { yylval=NULL; return K_MOSI; }
@@ -142,13 +141,11 @@ parallel         { yylval=NULL; return K_PARALLEL; }
 part             { yylval=NULL; return K_PART; }
 pgmled           { yylval=NULL; return K_PGMLED; }
 programmer       { yylval=NULL; return K_PROGRAMMER; }
-pseudo           { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
 pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
 rdyled           { yylval=NULL; return K_RDYLED; }
 readback_p1      { yylval=NULL; return K_READBACK_P1; }
 readback_p2      { yylval=NULL; return K_READBACK_P2; }
-reset            { yylval=NULL; return K_RESET; }
-sck              { yylval=NULL; return K_SCK; }
+retry_pulse      { yylval=NULL; return K_RETRY_PULSE; }
 serial           { yylval=NULL; return K_SERIAL; }
 size             { yylval=NULL; return K_SIZE; }
 stk500           { yylval=NULL; return K_STK500; }
@@ -156,6 +153,14 @@ type             { yylval=NULL; return K_TYPE; }
 vcc              { yylval=NULL; return K_VCC; }
 vfyled           { yylval=NULL; return K_VFYLED; }
 
+
+dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
+io               { yylval=new_token(K_IO); return K_IO; }
+pseudo           { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
+
+reset            { yylval=new_token(K_RESET); return K_RESET; }
+sck              { yylval=new_token(K_SCK); return K_SCK; }
+
 read             { yylval=new_token(K_READ); return K_READ; }
 write            { yylval=new_token(K_WRITE); return K_WRITE; }
 read_lo          { yylval=new_token(K_READ_LO); return K_READ_LO; }
@@ -168,8 +173,6 @@ writepage        { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
 chip_erase       { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
 pgm_enable       { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
 
-memory           { yylval=NULL; return K_MEMORY; }
-
 no               { yylval=new_token(K_NO); return K_NO; }
 yes              { yylval=new_token(K_YES); return K_YES; }
 
diff --git a/par.c b/par.c
index d02d80b2..f28fbb27 100644
--- a/par.c
+++ b/par.c
@@ -445,7 +445,7 @@ static int par_initialize(PROGRAMMER * pgm, AVRPART * p)
       rc = pgm->program_enable(pgm, p);
       if ((rc == 0)||(rc == -1))
         break;
-      par_pulsepin(pgm->fd, pgm->pinno[PIN_AVR_SCK]);
+      par_pulsepin(pgm->fd, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
       tries++;
     } while (tries < 65);
 
diff --git a/stk500.c b/stk500.c
index 7673b1aa..c6af5a84 100644
--- a/stk500.c
+++ b/stk500.c
@@ -637,7 +637,7 @@ static int stk500_setattr(int fd)
 
   termios.c_iflag = 0;
   termios.c_oflag = 0;
-  termios.c_cflag &= ~ (PARENB | CSIZE | CSTOPB);
+  termios.c_cflag = 0;
   termios.c_cflag |=   (CS8 | CREAD | CLOCAL);
   termios.c_lflag = 0;
   termios.c_cc[VMIN]  = 1;