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 */