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