X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/00bb9c112fa6dfa84d3571659527c13af7170279..7e397056b12b16fbb9a65f37a2e1aa75174c9fe8:/firmware/isp.c?ds=inline diff --git a/firmware/isp.c b/firmware/isp.c index 50e6a26a1..fa6c7bef6 100644 --- a/firmware/isp.c +++ b/firmware/isp.c @@ -17,6 +17,7 @@ #define spiHWdisable() SPCR = 0 uchar sck_sw_delay; +uchar sck_sw_delay_loops; uchar sck_spcr; uchar sck_spsr; uchar isp_hiaddr; @@ -31,67 +32,102 @@ void ispSetSCKOption(uchar option) { if (option == USBASP_ISP_SCK_AUTO) option = USBASP_ISP_SCK_375; - if (option >= USBASP_ISP_SCK_93_75) { + if (((F_CPU <= 12000000) && (option >= USBASP_ISP_SCK_93_75)) + || ((F_CPU > 12000000) && (option >= USBASP_ISP_SCK_187_5))) { ispTransmit = ispTransmit_hw; sck_spsr = 0; sck_sw_delay = 1; /* force RST#/SCK pulse for 320us */ + sck_sw_delay_loops = 1; switch (option) { case USBASP_ISP_SCK_1500: - /* enable SPI, master, 1.5MHz, XTAL/8 */ - sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); - sck_spsr = (1 << SPI2X); +# if (F_CPU <= 12000000) + /* enable SPI, master, 1.5MHz, XTAL/8 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); + sck_spsr = (1 << SPI2X); +# else + /* enable SPI, master, ~1.1MHz, XTAL/16 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); +# endif + break; case USBASP_ISP_SCK_750: - /* enable SPI, master, 750kHz, XTAL/16 */ - sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); +# if (F_CPU <= 12000000) + /* enable SPI, master, 750kHz, XTAL/16 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); +# else + /* enable SPI, master, ~531kHz, XTAL/32 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); + sck_spsr = (1 << SPI2X); +# endif break; case USBASP_ISP_SCK_375: default: - /* enable SPI, master, 375kHz, XTAL/32 (default) */ - sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); - sck_spsr = (1 << SPI2X); +# if (F_CPU <= 12000000) + /* enable SPI, master, 375kHz, XTAL/32 (default) */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); + sck_spsr = (1 << SPI2X); +# else + /* enable SPI, master, ~265.6kHz XTAL/64 (default) */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); +# endif break; case USBASP_ISP_SCK_187_5: - /* enable SPI, master, 187.5kHz XTAL/64 */ - sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); - break; - case USBASP_ISP_SCK_93_75: - /* enable SPI, master, 93.75kHz XTAL/128 */ - sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); +# if (F_CPU <= 12000000) + /* enable SPI, master, 187.5kHz XTAL/64 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); +# else + /* enable SPI, master, ~132.81kHz XTAL/128 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); +# endif break; +# if (F_CPU <= 12000000) + case USBASP_ISP_SCK_93_75: + /* enable SPI, master, 93.75kHz XTAL/128 */ + sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); + break; +# endif } } else { ispTransmit = ispTransmit_sw; + sck_sw_delay_loops = 1; + switch (option) { +# if (F_CPU > 12000000) + case USBASP_ISP_SCK_93_75: + sck_sw_delay = 2; + + break; +# endif case USBASP_ISP_SCK_32: - sck_sw_delay = 3; + sck_sw_delay = ((3 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_16: - sck_sw_delay = 6; + sck_sw_delay = ((6 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_8: - sck_sw_delay = 12; + sck_sw_delay = ((12 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_4: - sck_sw_delay = 24; + sck_sw_delay = ((24 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_2: - sck_sw_delay = 48; + sck_sw_delay = ((48 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_1: - sck_sw_delay = 96; + sck_sw_delay = ((96 * (F_CPU/1000000L) + 11) / 12); break; case USBASP_ISP_SCK_0_5: - sck_sw_delay = 192; + sck_sw_delay = ((96 * (F_CPU/1000000L) + 11) / 12); + sck_sw_delay_loops = 2; break; } @@ -101,7 +137,11 @@ void ispSetSCKOption(uchar option) { void ispDelay() { uint8_t starttime = TIMERVALUE; - while ((uint8_t) (TIMERVALUE - starttime) < sck_sw_delay) { + uint8_t loops = sck_sw_delay_loops; + + while (loops--) { + while ((uint8_t) (TIMERVALUE - starttime) < sck_sw_delay) { + } } }