X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/6ffa080eb257892c7cad9f80f8bfef99b4896082..39f1c0c136520a3f4746ad6381d1242979125ff3:/firmware/main.c?ds=inline diff --git a/firmware/main.c b/firmware/main.c index af740fcc3..ca65df24f 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -1,53 +1,32 @@ /* - USBasp - USB in-circuit programmer for Atmel AVR controllers - - Thomas Fischl - - License........: GNU GPL v2 (see Readme.txt) - Target.........: ATMega8 at 12 MHz - Creation Date..: 2005-02-20 - Last change....: 2007-07-23 - - PC2 SCK speed option. GND -> slow (8khz SCK), - open -> fast (375kHz SCK) -*/ + * USBasp - USB in-circuit programmer for Atmel AVR controllers + * + * Thomas Fischl + * + * License........: GNU GPL v2 (see Readme.txt) + * Target.........: ATMega8 at 12 MHz + * Creation Date..: 2005-02-20 + * Last change....: 2009-02-28 + * + * PC2 SCK speed option. + * GND -> slow (8khz SCK), + * open -> software set speed (default is 375kHz SCK) + */ #include #include #include #include +#include "usbasp.h" #include "usbdrv.h" #include "isp.h" #include "clock.h" -#define USBASP_FUNC_CONNECT 1 -#define USBASP_FUNC_DISCONNECT 2 -#define USBASP_FUNC_TRANSMIT 3 -#define USBASP_FUNC_READFLASH 4 -#define USBASP_FUNC_ENABLEPROG 5 -#define USBASP_FUNC_WRITEFLASH 6 -#define USBASP_FUNC_READEEPROM 7 -#define USBASP_FUNC_WRITEEEPROM 8 -#define USBASP_FUNC_SETLONGADDRESS 9 - -#define PROG_STATE_IDLE 0 -#define PROG_STATE_WRITEFLASH 1 -#define PROG_STATE_READFLASH 2 -#define PROG_STATE_READEEPROM 3 -#define PROG_STATE_WRITEEEPROM 4 - -#define PROG_BLOCKFLAG_FIRST 1 -#define PROG_BLOCKFLAG_LAST 2 - -#define ledRedOn() PORTC &= ~(1 << PC1) -#define ledRedOff() PORTC |= (1 << PC1) -#define ledGreenOn() PORTC &= ~(1 << PC0) -#define ledGreenOff() PORTC |= (1 << PC0) - static uchar replyBuffer[8]; static uchar prog_state = PROG_STATE_IDLE; +static uchar prog_sck = USBASP_ISP_SCK_AUTO; static uchar prog_address_newmode = 0; static unsigned long prog_address; @@ -56,211 +35,220 @@ static unsigned int prog_pagesize; static uchar prog_blockflags; static uchar prog_pagecounter; - uchar usbFunctionSetup(uchar data[8]) { - uchar len = 0; - - if(data[1] == USBASP_FUNC_CONNECT){ + uchar len = 0; - /* set SCK speed */ - if ((PINC & (1 << PC2)) == 0) { - ispSetSCKOption(ISP_SCK_SLOW); - } else { - ispSetSCKOption(ISP_SCK_FAST); - } + if (data[1] == USBASP_FUNC_CONNECT) { - /* set compatibility mode of address delivering */ - prog_address_newmode = 0; + /* set SCK speed */ + if ((PINC & (1 << PC2)) == 0) { + ispSetSCKOption(USBASP_ISP_SCK_8); + } else { + ispSetSCKOption(prog_sck); + } - ledRedOn(); - ispConnect(); + /* set compatibility mode of address delivering */ + prog_address_newmode = 0; - } else if (data[1] == USBASP_FUNC_DISCONNECT) { - ispDisconnect(); - ledRedOff(); + ledRedOn(); + ispConnect(); - } else if (data[1] == USBASP_FUNC_TRANSMIT) { - replyBuffer[0] = ispTransmit(data[2]); - replyBuffer[1] = ispTransmit(data[3]); - replyBuffer[2] = ispTransmit(data[4]); - replyBuffer[3] = ispTransmit(data[5]); - len = 4; + } else if (data[1] == USBASP_FUNC_DISCONNECT) { + ispDisconnect(); + ledRedOff(); - } else if (data[1] == USBASP_FUNC_READFLASH) { + } else if (data[1] == USBASP_FUNC_TRANSMIT) { + replyBuffer[0] = ispTransmit(data[2]); + replyBuffer[1] = ispTransmit(data[3]); + replyBuffer[2] = ispTransmit(data[4]); + replyBuffer[3] = ispTransmit(data[5]); + len = 4; - if (!prog_address_newmode) - prog_address = (data[3] << 8) | data[2]; + } else if (data[1] == USBASP_FUNC_READFLASH) { - prog_nbytes = (data[7] << 8) | data[6]; - prog_state = PROG_STATE_READFLASH; - len = 0xff; /* multiple in */ + if (!prog_address_newmode) + prog_address = (data[3] << 8) | data[2]; - } else if (data[1] == USBASP_FUNC_READEEPROM) { + prog_nbytes = (data[7] << 8) | data[6]; + prog_state = PROG_STATE_READFLASH; + len = 0xff; /* multiple in */ - if (!prog_address_newmode) - prog_address = (data[3] << 8) | data[2]; + } else if (data[1] == USBASP_FUNC_READEEPROM) { - prog_nbytes = (data[7] << 8) | data[6]; - prog_state = PROG_STATE_READEEPROM; - len = 0xff; /* multiple in */ + if (!prog_address_newmode) + prog_address = (data[3] << 8) | data[2]; - } else if (data[1] == USBASP_FUNC_ENABLEPROG) { - replyBuffer[0] = ispEnterProgrammingMode();; - len = 1; + prog_nbytes = (data[7] << 8) | data[6]; + prog_state = PROG_STATE_READEEPROM; + len = 0xff; /* multiple in */ - } else if (data[1] == USBASP_FUNC_WRITEFLASH) { + } else if (data[1] == USBASP_FUNC_ENABLEPROG) { + replyBuffer[0] = ispEnterProgrammingMode(); + len = 1; - if (!prog_address_newmode) - prog_address = (data[3] << 8) | data[2]; + } else if (data[1] == USBASP_FUNC_WRITEFLASH) { - prog_pagesize = data[4]; - prog_blockflags = data[5] & 0x0F; - prog_pagesize += (((unsigned int)data[5] & 0xF0)<<4); - if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { - prog_pagecounter = prog_pagesize; - } - prog_nbytes = (data[7] << 8) | data[6]; - prog_state = PROG_STATE_WRITEFLASH; - len = 0xff; /* multiple out */ + if (!prog_address_newmode) + prog_address = (data[3] << 8) | data[2]; - } else if (data[1] == USBASP_FUNC_WRITEEEPROM) { + prog_pagesize = data[4]; + prog_blockflags = data[5] & 0x0F; + prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); + if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { + prog_pagecounter = prog_pagesize; + } + prog_nbytes = (data[7] << 8) | data[6]; + prog_state = PROG_STATE_WRITEFLASH; + len = 0xff; /* multiple out */ - if (!prog_address_newmode) - prog_address = (data[3] << 8) | data[2]; + } else if (data[1] == USBASP_FUNC_WRITEEEPROM) { - prog_pagesize = 0; - prog_blockflags = 0; - prog_nbytes = (data[7] << 8) | data[6]; - prog_state = PROG_STATE_WRITEEEPROM; - len = 0xff; /* multiple out */ + if (!prog_address_newmode) + prog_address = (data[3] << 8) | data[2]; - } else if(data[1] == USBASP_FUNC_SETLONGADDRESS) { + prog_pagesize = 0; + prog_blockflags = 0; + prog_nbytes = (data[7] << 8) | data[6]; + prog_state = PROG_STATE_WRITEEEPROM; + len = 0xff; /* multiple out */ - /* set new mode of address delivering (ignore address delivered in commands) */ - prog_address_newmode = 1; - /* set new address */ - prog_address = *((unsigned long*)&data[2]); - } + } else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { - usbMsgPtr = replyBuffer; + /* set new mode of address delivering (ignore address delivered in commands) */ + prog_address_newmode = 1; + /* set new address */ + prog_address = *((unsigned long*) &data[2]); - return len; -} + } else if (data[1] == USBASP_FUNC_SETISPSCK) { + /* set sck option */ + prog_sck = data[2]; + replyBuffer[0] = 0; + len = 1; + } -uchar usbFunctionRead(uchar *data, uchar len) { + usbMsgPtr = replyBuffer; - uchar i; - - /* check if programmer is in correct read state */ - if ((prog_state != PROG_STATE_READFLASH) && - (prog_state != PROG_STATE_READEEPROM)) { - return 0xff; - } - - /* fill packet */ - for (i = 0; i < len; i++) { - if (prog_state == PROG_STATE_READFLASH) { - data[i] = ispReadFlash(prog_address); - } else { - data[i] = ispReadEEPROM(prog_address); - } - prog_address++; - } - - /* last packet? */ - if (len < 8) { - prog_state = PROG_STATE_IDLE; - } - - return len; + return len; } +uchar usbFunctionRead(uchar *data, uchar len) { -uchar usbFunctionWrite(uchar *data, uchar len) { + uchar i; - uchar retVal = 0; - uchar i; + /* check if programmer is in correct read state */ + if ((prog_state != PROG_STATE_READFLASH) && (prog_state + != PROG_STATE_READEEPROM)) { + return 0xff; + } - /* check if programmer is in correct write state */ - if ((prog_state != PROG_STATE_WRITEFLASH) && - (prog_state != PROG_STATE_WRITEEEPROM)) { - return 0xff; - } + /* fill packet */ + for (i = 0; i < len; i++) { + if (prog_state == PROG_STATE_READFLASH) { + data[i] = ispReadFlash(prog_address); + } else { + data[i] = ispReadEEPROM(prog_address); + } + prog_address++; + } + + /* last packet? */ + if (len < 8) { + prog_state = PROG_STATE_IDLE; + } + return len; +} - for (i = 0; i < len; i++) { +uchar usbFunctionWrite(uchar *data, uchar len) { - if (prog_state == PROG_STATE_WRITEFLASH) { - /* Flash */ + uchar retVal = 0; + uchar i; - if (prog_pagesize == 0) { - /* not paged */ - ispWriteFlash(prog_address, data[i], 1); - } else { - /* paged */ - ispWriteFlash(prog_address, data[i], 0); - prog_pagecounter --; - if (prog_pagecounter == 0) { - ispFlushPage(prog_address, data[i]); - prog_pagecounter = prog_pagesize; + /* check if programmer is in correct write state */ + if ((prog_state != PROG_STATE_WRITEFLASH) && (prog_state + != PROG_STATE_WRITEEEPROM)) { + return 0xff; } - } - } else { - /* EEPROM */ - ispWriteEEPROM(prog_address, data[i]); - } + for (i = 0; i < len; i++) { - prog_nbytes --; + if (prog_state == PROG_STATE_WRITEFLASH) { + /* Flash */ - if (prog_nbytes == 0) { - prog_state = PROG_STATE_IDLE; - if ((prog_blockflags & PROG_BLOCKFLAG_LAST) && - (prog_pagecounter != prog_pagesize)) { + if (prog_pagesize == 0) { + /* not paged */ + ispWriteFlash(prog_address, data[i], 1); + } else { + /* paged */ + ispWriteFlash(prog_address, data[i], 0); + prog_pagecounter--; + if (prog_pagecounter == 0) { + ispFlushPage(prog_address, data[i]); + prog_pagecounter = prog_pagesize; + } + } - /* last block and page flush pending, so flush it now */ - ispFlushPage(prog_address, data[i]); - } + } else { + /* EEPROM */ + ispWriteEEPROM(prog_address, data[i]); + } - retVal = 1; // Need to return 1 when no more data is to be received - } + prog_nbytes--; - prog_address ++; - } + if (prog_nbytes == 0) { + prog_state = PROG_STATE_IDLE; + if ((prog_blockflags & PROG_BLOCKFLAG_LAST) && (prog_pagecounter + != prog_pagesize)) { - return retVal; -} + /* last block and page flush pending, so flush it now */ + ispFlushPage(prog_address, data[i]); + } + retVal = 1; // Need to return 1 when no more data is to be received + } -int main(void) -{ - uchar i, j; - - PORTD = 0; - PORTB = 0; /* no pullups on USB and ISP pins */ - DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */ + prog_address++; + } - DDRB = ~0; /* output SE0 for USB reset */ - j = 0; - while(--j){ /* USB Reset by device only required on Watchdog Reset */ - i = 0; - while(--i); /* delay >10ms for USB reset */ - } - DDRB = 0; /* all USB and ISP pins inputs */ + return retVal; +} - DDRC = 0x03; /* all inputs except PC0, PC1 */ - PORTC = 0xfe; +int main(void) { + uchar i, j; + + /* no pullups on USB and ISP pins */ + PORTD = 0; + PORTB = 0; + /* all outputs except PD2 = INT0 */ + DDRD = ~(1 << 2); + + /* output SE0 for USB reset */ + DDRB = ~0; + j = 0; + /* USB Reset by device only required on Watchdog Reset */ + while (--j) { + i = 0; + /* delay >10ms for USB reset */ + while (--i) + ; + } + /* all USB and ISP pins inputs */ + DDRB = 0; - clockInit(); /* init timer */ + /* all inputs except PC0, PC1 */ + DDRC = 0x03; + PORTC = 0xfe; - ispSetSCKOption(ISP_SCK_FAST); + /* init timer */ + clockInit(); - usbInit(); - sei(); - for(;;){ /* main event loop */ - usbPoll(); - } - return 0; + /* main event loop */ + usbInit(); + sei(); + for (;;) { + usbPoll(); + } + return 0; }