📄 main.c
字号:
/*
USBasp - USB in-circuit programmer for Atmel AVR controllers
Thomas Fischl <tfischl@gmx.de>
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)
*/
/*idn修改
Target.........: ATtiny26 at 16 MHz
Last change....: 2008-02-03
PA2 SCK speed option. open -> FAST 250kHz SCK 好象并不正确4M时钟都通信失败。
GND -> SLOW 966Hz SCK 可能也不正确,不过至少1M时钟正常,
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.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() PORTA &= ~(1 << PA1)
#define ledRedOff() PORTA |= (1 << PA1)
#define ledGreenOn() PORTA &= ~(1 << PA0)
#define ledGreenOff() PORTA |= (1 << PA0)
static uchar replyBuffer[8];
register uchar prog_state asm("r13");
register uchar prog_address_newmode asm("r12");
register unsigned long prog_address asm("r8");
register unsigned int prog_nbytes asm("r6");
register unsigned int prog_pagesize asm("r4");
register uchar prog_blockflags asm("r3");
register uchar prog_pagecounter asm("r2");
uchar usbFunctionSetup(uchar data[8]) {
uchar len = 0;
uchar tmpprog_state;
if(data[1] == USBASP_FUNC_CONNECT){
/* set SCK speed */
/* set compatibility mode of address delivering */
prog_address_newmode = 0;
ledRedOn();
ispConnect();
} else if (data[1] == USBASP_FUNC_DISCONNECT) {
ispDisconnect();
ledRedOff();
} else if (data[1] == USBASP_FUNC_TRANSMIT) {
*(unsigned long *)replyBuffer=ispTransmit32(*(unsigned long *)&data[2]);
len = 4;
} else if (data[1] == USBASP_FUNC_READFLASH) {
tmpprog_state = PROG_STATE_READFLASH;
goto multiple_out;
} else if (data[1] == USBASP_FUNC_ENABLEPROG) {
replyBuffer[0] = ispEnterProgrammingMode();;
len = 1;
} else if (data[1] == USBASP_FUNC_WRITEFLASH) {
//prog_pagesize = *(unsigned int*)&data[4];
// prog_pagesize += (((unsigned int)data[5] & 0xF0)<<4);
prog_blockflags = data[5] & 0x0F;
uchar tmp=data[5] & 0xF0;
asm volatile("ldd %A0, Z+4 \n\t"
"mov %B0, %1 \n\t"
"swap %B0 \n\t"
:"=r"(prog_pagesize):"r"(tmp),"0"(prog_pagesize));
if (prog_blockflags & PROG_BLOCKFLAG_FIRST) {
prog_pagecounter = prog_pagesize;
}
tmpprog_state = PROG_STATE_WRITEFLASH;
goto multiple_out;
} else if (data[1] == USBASP_FUNC_READEEPROM) {
tmpprog_state = PROG_STATE_READEEPROM;
goto multiple_out;
} else if (data[1] == USBASP_FUNC_WRITEEEPROM) {
prog_pagesize = 0;
prog_blockflags = 0;
tmpprog_state = PROG_STATE_WRITEEEPROM;
multiple_out:
prog_state=tmpprog_state;
if (!prog_address_newmode){
// prog_address = *((unsigned int*)&data[2]);
asm volatile("ldd %A0, Z+2 \n\t"
"ldd %B0, Z+3 \n\t"
"clr %C0 \n\t"
"clr %D0 \n\t"
:"=r"(prog_address):);
}
prog_nbytes = *((unsigned int*)&data[6]);
len = 0xff; /* multiple out */
} else if(data[1] == USBASP_FUNC_SETLONGADDRESS) {
/* set new mode of address delivering (ignore address delivered in commands) */
prog_address_newmode = 1;
/* set new address */
prog_address = *((unsigned long*)&data[2]);
}
usbMsgPtr = replyBuffer;
return len;
}
uchar usbFunctionRead(uchar *data, uchar len) {
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++) {
uchar rval;
if (prog_state == PROG_STATE_READFLASH) {
rval = (uchar)ispReadFlash();
} else {
rval = (uchar)ispReadEEPROM();
}
*data++ =rval;
inc_prog_address();//prog_address++;
}
/* last packet? */
if (len < 8) {
prog_state = PROG_STATE_IDLE;
}
return len;
}
uchar usbFunctionWrite(uchar *data, uchar len) {
uchar retVal = 0;
uchar i;
/* check if programmer is in correct write state */
if ((prog_state != PROG_STATE_WRITEFLASH) &&
(prog_state != PROG_STATE_WRITEEEPROM)) {
return 0xff;
}
uchar *data_i;
data_i=data;
for (i = 0; i < len; i++) {
if (prog_state == PROG_STATE_WRITEFLASH) {
/* Flash */
ispWriteFlash( *data_i);
} else {
/* EEPROM */
ispWriteEEPROM(*data_i);
}
prog_nbytes --;
if (prog_nbytes == 0) {
prog_state = PROG_STATE_IDLE;
if ((prog_blockflags & PROG_BLOCKFLAG_LAST) &&
(prog_pagecounter != prog_pagesize)) {
/* last block and page flush pending, so flush it now */
ispFlushPage();
}
retVal = 1; // Need to return 1 when no more data is to be received
}
data_i++;
inc_prog_address();//prog_address ++;
}
return retVal;
}
int main(void)
{
prog_state = PROG_STATE_IDLE;
// prog_address_newmode = 0;
// prog_nbytes = 0;
PORTA = (1<<selectFAST)|(1<<PA1);/*ledRedOff() ledGreenOn() selectFAST pullup */
DDRA = 0x03; /* all inputs except PA0, PA1 */
clockInit(); /* init timer */
usbInit();
sei();
for(;;){ /* main event loop */
usbPoll();
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -