Sorry for long delay. Here are patches.

Patches are against latest released USBasp firmware version
(2007-10-23) and Avrdude's CVS version (as of 29.03.2008).

Software control over SCK frequency from 1.5 MHz down to 500 Hz.

Bitclock period, specified using -B switch, is rounded to closest
available frequency:
less than 0.5 or none - default speed (jumper setting)
0.5 - 1.0 -> 1.5 MHz
1.0 - 2.0 -> 750 kHz
2.0 - 4.0 -> 375 kHz
4.0 - 8.0 -> 187.5 kHz
8.0 - 20.96 -> 93.75 kHz
20.96 - 46.88 -> 32 kHz
46.88 - 93.75 -> 16 kHz
93.75 - 187.5 -> 8 kHz
187.5 - 375.0 -> 4 kHz
375.0 - 750.0 -> 2 kHz
750.0 - 1500.0 -> 1 Khz
more than 1500.0 -> 500 Hz

Doesn't break forward/backward avrdude/usbasp compability (at least I
hope so ;)) - firmware just falls back to jumper setting.

Hope this will be useful

Jurgis


On Wed, Jan 9, 2008 at 6:56 PM, Thomas Fischl <[EMAIL PROTECTED]> wrote:
>
> Joerg Wunsch wrote:
>
> > You can never get too slow. :-) You could have a device being clocked
> > from a 32 kHz crystal oscillator, and with a CKDIV8 fuse programmed,
> > so the resulting CPU clock frequency were 4096 Hz.  In that case, the
> > ISP clock must be below 1024 Hz... (and be it only in order to
> > unprogram the mistakenly programmed CKDIV8 fuse again :).
>
> Okay. Then we should leave the software SPI function in the USBasp
> firmware and make the clock delays in it variable. This function can be
> used for frequencies lower than 187.5kHz and the hardware SPI for faster
> clocking.
>
> Thomas
diff -ur avrdude.cvs/usbasp.c avrdude.new/usbasp.c
--- avrdude.cvs/usbasp.c	2007-11-07 22:36:12.000000000 +0200
+++ avrdude.new/usbasp.c	2008-03-29 22:32:26.000000000 +0200
@@ -227,7 +227,51 @@
 {
 
   unsigned char temp[4];
+  double clock = pgm->bitclock*1e+6;
+  double freq = 0; 
   memset(temp, 0, sizeof(temp));
+  
+  /* set ISP SCK speed index */
+  if (clock > 1500.0) { 
+    temp[0] = ISP_SCK_0_5;
+    freq = 0.5;
+  } else if (clock > 750.0) {
+    temp[0] = ISP_SCK_1;
+    freq = 1;  
+  } else if (clock > 375.0) {
+    temp[0] = ISP_SCK_2;
+    freq = 2;
+  } else if (clock > 187.5) { 
+    temp[0] = ISP_SCK_4;
+    freq = 4;
+  } else if (clock > 93.75) {
+    temp[0] = ISP_SCK_8;
+    freq = 8;
+  } else if (clock > 46.88) {
+    temp[0] = ISP_SCK_16;
+    freq = 16;
+  } else if (clock > 20.96) {
+    temp[0] = ISP_SCK_32;
+    freq = 32;
+  } else if (clock > 8.0) {
+    temp[0] = ISP_SCK_93_75;
+    freq = 93.75;
+  } else if (clock > 4.0) {
+    temp[0] = ISP_SCK_187_5;
+    freq = 187.5;
+  } else if (clock > 2.0) {
+    temp[0] = ISP_SCK_375;
+    freq = 375;
+  } else if (clock > 1.0) {
+    temp[0] = ISP_SCK_750;
+    freq = 750;
+  } else if (clock > 0.5) {
+    temp[0] = ISP_SCK_1500;
+    freq = 1500;
+  }
+  if (freq > 0) 
+    fprintf(stderr, "%s: USBasp: using %g kHz SCK\n", progname, freq);
+    
   usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
 
   usleep(100000);
diff -ur avrdude.cvs/usbasp.h avrdude.new/usbasp.h
--- avrdude.cvs/usbasp.h	2007-07-24 19:43:25.000000000 +0300
+++ avrdude.new/usbasp.h	2008-03-29 22:24:34.000000000 +0200
@@ -51,6 +51,23 @@
 #define USB_ERROR_ACCESS    2
 #define USB_ERROR_IO        3
 
+/* ISP SCK speed indexes */
+/* software ISP modes */
+#define ISP_SCK_0_5    23  /*   500 Hz */
+#define ISP_SCK_1      24  /*   1 kHz */
+#define ISP_SCK_2      25  /*   2 kHz */
+#define ISP_SCK_4      26  /*   4 kHz */
+#define ISP_SCK_8      27  /*   8 kHz */
+#define ISP_SCK_16     28  /*  16 kHz */
+#define ISP_SCK_32     29  /*  32 kHz */
+/* hardware ISP modes */		       
+#define ISP_SCK_93_75  30  /*  93.75 kHz */
+#define ISP_SCK_187_5  31  /* 187.5  kHz */
+#define ISP_SCK_375    32  /* 375 kHz   */
+#define ISP_SCK_750    33  /* 750 kHz   */
+#define ISP_SCK_1500   34  /* 1.5 MHz   */
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff -ur usbasp.2007-10-23/firmware/isp.c usbasp.2007-10-23-new/firmware/isp.c
--- usbasp.2007-10-23/firmware/isp.c	2007-07-23 19:31:26.000000000 +0300
+++ usbasp.2007-10-23-new/firmware/isp.c	2008-03-29 21:08:47.000000000 +0200
@@ -15,33 +15,82 @@
 
 #define spiHWdisable() SPCR = 0
 
-void spiHWenable() {
+uchar clock_div; /* hardware divider index */
+uchar sw_delay=12;
 
-  /* enable SPI, master, 375kHz SCK */
-  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1);
-  SPSR = (1 << SPI2X);
+void spiHWenable() {
+  switch (clock_div) {
+  case ISP_SCK_1500:
+    /* enable SPI, master, 1.5MHz, XTAL/8 */
+    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
+    SPSR = (1 << SPI2X);      
+  case ISP_SCK_750:
+    /* enable SPI, master, 750kHz, XTAL/16 */
+    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
+    SPSR = 0;
+    break;
+  case ISP_SCK_375:
+  default:
+    /* enable SPI, master, 375kHz, XTAL/32 (default) */
+    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1);
+    SPSR = (1 << SPI2X);
+    break;
+  case ISP_SCK_187_5:
+    /* enable SPI, master, 187.5kHz XTAL/64 */
+    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1);
+    SPSR = 0;
+    break;
+  case ISP_SCK_93_75:
+    /* enable SPI, master, 93.75kHz XTAL/128 */
+    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1)| (1 << SPR0);
+    SPSR = 0;
+    break;
+  }
 }
 
 void ispSetSCKOption(uchar option) {
 
-  if (option == 0) {
-
-    /* use software spi */
-    ispTransmit = ispTransmit_sw;
-    //    spiHWdisable();
-
-  } else {
+  if (option >= ISP_SCK_93_75) {
 
     /* use hardware spi */
     ispTransmit = ispTransmit_hw;
+    clock_div = option;
+
+  } else {
+    /* use software spi */
+    ispTransmit = ispTransmit_sw;
 
+    switch (option) {
+    case ISP_SCK_32:
+      sw_delay = 3;
+      break;
+    case ISP_SCK_16:
+      sw_delay = 6;
+      break;
+    case ISP_SCK_8:
+    default:
+      sw_delay = 12;
+      break;
+    case ISP_SCK_4:
+      sw_delay = 24;
+      break;
+    case ISP_SCK_2:
+      sw_delay = 48;
+      break;	
+    case ISP_SCK_1:
+      sw_delay = 96;
+      break;	
+    case ISP_SCK_0_5:
+      sw_delay = 192;
+      break;	
+    }
   }
 }
   
 void ispDelay() {
 
   uint8_t starttime = TIMERVALUE;
-  while ((uint8_t) (TIMERVALUE - starttime) < 12) { }
+  while ((uint8_t) (TIMERVALUE - starttime) < sw_delay) { }
 }
 
 void ispConnect() {
diff -ur usbasp.2007-10-23/firmware/isp.h usbasp.2007-10-23-new/firmware/isp.h
--- usbasp.2007-10-23/firmware/isp.h	2007-07-23 19:31:20.000000000 +0300
+++ usbasp.2007-10-23-new/firmware/isp.h	2008-03-29 21:09:19.000000000 +0200
@@ -24,9 +24,32 @@
 #define ISP_MISO  PB4
 #define ISP_SCK   PB5
 
+/* ISP SCK speed indexes */
+/* software ISP modes */
+#define ISP_SCK_0_5    23  /*   500 Hz */
+#define ISP_SCK_1      24  /*   1 kHz */
+#define ISP_SCK_2      25  /*   2 kHz */
+#define ISP_SCK_4      26  /*   4 kHz */
+#define ISP_SCK_8      27  /*   8 kHz */
+#define ISP_SCK_16     28  /*  16 kHz */
+#define ISP_SCK_32     29  /*  32 kHz */
+/* hardware ISP modes */		       
+#define ISP_SCK_93_75  30  /*  93.75 kHz */
+#define ISP_SCK_187_5  31  /* 187.5  kHz */
+#define ISP_SCK_375    32  /* 375 kHz   */
+#define ISP_SCK_750    33  /* 750 kHz   */
+#define ISP_SCK_1500   34  /* 1.5 MHz   */
+
+
+/* last speed mode index */
+#define ISP_SCK_FIRST  ISP_SCK_0_5
+#define ISP_SCK_LAST   ISP_SCK_1500 
+
 #define ISP_DELAY 1
-#define ISP_SCK_SLOW 0
-#define ISP_SCK_FAST 1
+#define ISP_SCK_SLOW ISP_SCK_8 
+#define ISP_SCK_FAST ISP_SCK_375
+
+
 
 /* Prepare connection to target device */
 void ispConnect();
diff -ur usbasp.2007-10-23/firmware/main.c usbasp.2007-10-23-new/firmware/main.c
--- usbasp.2007-10-23/firmware/main.c	2007-10-23 13:14:02.000000000 +0300
+++ usbasp.2007-10-23-new/firmware/main.c	2008-03-29 21:08:47.000000000 +0200
@@ -63,11 +63,16 @@
 
   if(data[1] == USBASP_FUNC_CONNECT){
 
-    /* set SCK speed */
-    if ((PINC & (1 << PC2)) == 0) {
-      ispSetSCKOption(ISP_SCK_SLOW);
+    if (data[2] && data[2] >= ISP_SCK_FIRST && data[2] <= ISP_SCK_LAST) {
+      /* use speed index if there's valid one */
+      ispSetSCKOption(data[2]);
     } else {
-      ispSetSCKOption(ISP_SCK_FAST);
+      /* set SCK speed based on jumper */
+      if ((PINC & (1 << PC2)) == 0) {
+	ispSetSCKOption(ISP_SCK_SLOW);
+      } else {
+	ispSetSCKOption(ISP_SCK_FAST);
+      }
     }
 
     /* set compatibility mode of address delivering */
_______________________________________________
avrdude-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avrdude-dev

Reply via email to