9d79354bd08e697c7834af3a67bc3c2511031637
2 USBasp - USB in-circuit programmer for Atmel AVR controllers
4 Thomas Fischl <tfischl@gmx.de>
7 The project is built with AVR USB driver by Objective Development, which is
8 published under an own licence based on the GNU General Public License (GPL).
9 USBasp is also distributed under this enhanced licence. See Documentation.
11 Target.........: ATMega8 at 12 MHz
12 Creation Date..: 2005-02-20
13 Last change....: 2005-04-20
15 PC2 SCK speed option. GND -> slow (8khz SCK),
16 open -> fast (375kHz SCK)
20 #include <avr/signal.h>
21 #include <avr/interrupt.h>
22 #include <avr/pgmspace.h>
29 #define USBASP_FUNC_CONNECT 1
30 #define USBASP_FUNC_DISCONNECT 2
31 #define USBASP_FUNC_TRANSMIT 3
32 #define USBASP_FUNC_READFLASH 4
33 #define USBASP_FUNC_ENABLEPROG 5
34 #define USBASP_FUNC_WRITEFLASH 6
35 #define USBASP_FUNC_READEEPROM 7
36 #define USBASP_FUNC_WRITEEEPROM 8
38 #define PROG_STATE_IDLE 0
39 #define PROG_STATE_WRITEFLASH 1
40 #define PROG_STATE_READFLASH 2
41 #define PROG_STATE_READEEPROM 3
42 #define PROG_STATE_WRITEEEPROM 4
44 #define PROG_BLOCKFLAG_FIRST 1
45 #define PROG_BLOCKFLAG_LAST 2
47 #define ledRedOn() PORTC &= ~(1 << PC1)
48 #define ledRedOff() PORTC |= (1 << PC1)
49 #define ledGreenOn() PORTC &= ~(1 << PC0)
50 #define ledGreenOff() PORTC |= (1 << PC0)
52 static uchar replyBuffer
[8];
54 static uchar prog_state
= PROG_STATE_IDLE
;
56 static unsigned int prog_address
;
57 static unsigned int prog_nbytes
= 0;
58 static uchar prog_pagesize
;
59 static uchar prog_blockflags
;
60 static uchar prog_pagecounter
;
63 uchar
usbFunctionSetup(uchar data
[8]) {
67 if(data
[1] == USBASP_FUNC_CONNECT
){
70 if ((PINC
& (1 << PC2
)) == 0) {
71 ispSetSCKOption(ISP_SCK_SLOW
);
73 ispSetSCKOption(ISP_SCK_FAST
);
79 } else if (data
[1] == USBASP_FUNC_DISCONNECT
) {
83 } else if (data
[1] == USBASP_FUNC_TRANSMIT
) {
84 replyBuffer
[0] = ispTransmit(data
[2]);
85 replyBuffer
[1] = ispTransmit(data
[3]);
86 replyBuffer
[2] = ispTransmit(data
[4]);
87 replyBuffer
[3] = ispTransmit(data
[5]);
90 } else if (data
[1] == USBASP_FUNC_READFLASH
) {
91 prog_address
= (data
[3] << 8) | data
[2];
92 prog_nbytes
= (data
[7] << 8) | data
[6];
93 prog_state
= PROG_STATE_READFLASH
;
94 len
= 0xff; /* multiple in */
96 } else if (data
[1] == USBASP_FUNC_READEEPROM
) {
97 prog_address
= (data
[3] << 8) | data
[2];
98 prog_nbytes
= (data
[7] << 8) | data
[6];
99 prog_state
= PROG_STATE_READEEPROM
;
100 len
= 0xff; /* multiple in */
102 } else if (data
[1] == USBASP_FUNC_ENABLEPROG
) {
103 replyBuffer
[0] = ispEnterProgrammingMode();;
106 } else if (data
[1] == USBASP_FUNC_WRITEFLASH
) {
107 prog_address
= (data
[3] << 8) | data
[2];
108 prog_pagesize
= data
[4];
109 prog_blockflags
= data
[5];
110 if (prog_blockflags
& PROG_BLOCKFLAG_FIRST
) {
111 prog_pagecounter
= prog_pagesize
;
113 prog_nbytes
= (data
[7] << 8) | data
[6];
114 prog_state
= PROG_STATE_WRITEFLASH
;
115 len
= 0xff; /* multiple out */
117 } else if (data
[1] == USBASP_FUNC_WRITEEEPROM
) {
118 prog_address
= (data
[3] << 8) | data
[2];
121 prog_nbytes
= (data
[7] << 8) | data
[6];
122 prog_state
= PROG_STATE_WRITEEEPROM
;
123 len
= 0xff; /* multiple out */
126 usbMsgPtr
= replyBuffer
;
132 uchar
usbFunctionRead(uchar
*data
, uchar len
) {
136 /* check if programmer is in correct read state */
137 if ((prog_state
!= PROG_STATE_READFLASH
) &&
138 (prog_state
!= PROG_STATE_READEEPROM
)) {
143 for (i
= 0; i
< len
; i
++) {
144 if (prog_state
== PROG_STATE_READFLASH
) {
145 data
[i
] = ispReadFlash(prog_address
);
147 data
[i
] = ispReadEEPROM(prog_address
);
154 prog_state
= PROG_STATE_IDLE
;
161 uchar
usbFunctionWrite(uchar
*data
, uchar len
) {
165 /* check if programmer is in correct write state */
166 if ((prog_state
!= PROG_STATE_WRITEFLASH
) &&
167 (prog_state
!= PROG_STATE_WRITEEEPROM
)) {
172 for (i
= 0; i
< len
; i
++) {
174 if (prog_state
== PROG_STATE_WRITEFLASH
) {
177 if (prog_pagesize
== 0) {
179 ispWriteFlash(prog_address
, data
[i
], 1);
182 ispWriteFlash(prog_address
, data
[i
], 0);
184 if (prog_pagecounter
== 0) {
185 ispFlushPage(prog_address
, data
[i
]);
186 prog_pagecounter
= prog_pagesize
;
192 ispWriteEEPROM(prog_address
, data
[i
]);
197 if (prog_nbytes
== 0) {
198 prog_state
= PROG_STATE_IDLE
;
199 if ((prog_blockflags
& PROG_BLOCKFLAG_LAST
) &&
200 (prog_pagecounter
!= prog_pagesize
)) {
202 /* last block and page flush pending, so flush it now */
203 ispFlushPage(prog_address
, data
[i
]);
217 PORTB
= 0; /* no pullups on USB and ISP pins */
218 DDRD
= ~(1 << 2); /* all outputs except PD2 = INT0 */
219 DDRB
= 0; /* all USB and ISP pins inputs */
221 DDRC
= 0x03; /* all inputs except PC0, PC1 */
224 clockInit(); /* init timer */
226 ispSetSCKOption(ISP_SCK_FAST
);
230 for(;;){ /* main event loop */