1 |
/* |
1 |
/* |
2 |
* USBasp - USB in-circuit programmer for Atmel AVR controllers |
2 |
* USBasp - USB in-circuit programmer for Atmel AVR controllers |
3 |
* |
3 |
* |
4 |
* Thomas Fischl <tfischl@gmx.de> |
4 |
* Thomas Fischl <tfischl@gmx.de> |
5 |
* |
5 |
* |
6 |
* License........: GNU GPL v2 (see Readme.txt) |
6 |
* License........: GNU GPL v2 (see Readme.txt) |
7 |
* Target.........: ATMega8 at 12 MHz |
7 |
* Target.........: ATMega8 at 12 MHz |
8 |
* Creation Date..: 2005-02-20 |
8 |
* Creation Date..: 2005-02-20 |
9 |
* Last change....: 2009-02-28 |
9 |
* Last change....: 2009-02-28 |
10 |
* |
10 |
* |
11 |
* PC2 SCK speed option. |
11 |
* PC2 SCK speed option. |
12 |
* GND -> slow (8khz SCK), |
12 |
* GND -> slow (8khz SCK), |
13 |
* open -> software set speed (default is 375kHz SCK) |
13 |
* open -> software set speed (default is 375kHz SCK) |
- |
|
14 |
* |
- |
|
15 |
* 2014_02_09 miho@mlab.cz - cleaned code and defined IO port better, automatic compile prodcess for more target CPUs |
- |
|
16 |
* |
14 |
*/ |
17 |
*/ |
15 |
|
18 |
|
16 |
#include <avr/io.h> |
19 |
#include <avr/io.h> |
17 |
#include <avr/interrupt.h> |
20 |
#include <avr/interrupt.h> |
18 |
#include <avr/pgmspace.h> |
21 |
#include <avr/pgmspace.h> |
19 |
#include <avr/wdt.h> |
22 |
#include <avr/wdt.h> |
20 |
|
23 |
|
21 |
#include "usbasp.h" |
24 |
#include "usbasp.h" |
22 |
#include "usbdrv.h" |
25 |
#include "usbdrv.h" |
23 |
#include "isp.h" |
26 |
#include "isp.h" |
24 |
#include "clock.h" |
27 |
#include "clock.h" |
25 |
#include "tpi.h" |
28 |
#include "tpi.h" |
26 |
#include "tpi_defs.h" |
29 |
#include "tpi_defs.h" |
27 |
|
30 |
|
28 |
static uchar replyBuffer[8]; |
31 |
static uchar replyBuffer[8]; |
29 |
|
32 |
|
30 |
static uchar prog_state = PROG_STATE_IDLE; |
33 |
static uchar prog_state = PROG_STATE_IDLE; |
31 |
static uchar prog_sck = USBASP_ISP_SCK_AUTO; |
34 |
static uchar prog_sck = USBASP_ISP_SCK_AUTO; |
32 |
|
35 |
|
33 |
static uchar prog_address_newmode = 0; |
36 |
static uchar prog_address_newmode = 0; |
34 |
static unsigned long prog_address; |
37 |
static unsigned long prog_address; |
35 |
static unsigned int prog_nbytes = 0; |
38 |
static unsigned int prog_nbytes = 0; |
36 |
static unsigned int prog_pagesize; |
39 |
static unsigned int prog_pagesize; |
37 |
static uchar prog_blockflags; |
40 |
static uchar prog_blockflags; |
38 |
static uchar prog_pagecounter; |
41 |
static uchar prog_pagecounter; |
39 |
|
42 |
|
40 |
uchar usbFunctionSetup(uchar data[8]) { |
43 |
uchar usbFunctionSetup(uchar data[8]) { |
41 |
|
44 |
|
42 |
uchar len = 0; |
45 |
uchar len = 0; |
43 |
|
46 |
|
44 |
if (data[1] == USBASP_FUNC_CONNECT) { |
47 |
if (data[1] == USBASP_FUNC_CONNECT) { |
45 |
|
48 |
|
46 |
/* set SCK speed */ |
49 |
/* set SCK speed */ |
47 |
if ((PINC & (1 << PC2)) == 0) { |
50 |
if ((PIN(CLKSW_PORT) & (1 << CLKSW_BIT)) == 0) { |
48 |
ispSetSCKOption(USBASP_ISP_SCK_8); |
51 |
ispSetSCKOption(USBASP_ISP_SCK_8); |
49 |
} else { |
52 |
} else { |
50 |
ispSetSCKOption(prog_sck); |
53 |
ispSetSCKOption(prog_sck); |
51 |
} |
54 |
} |
52 |
|
55 |
|
53 |
/* set compatibility mode of address delivering */ |
56 |
/* set compatibility mode of address delivering */ |
54 |
prog_address_newmode = 0; |
57 |
prog_address_newmode = 0; |
55 |
|
58 |
|
56 |
ledRedOn(); |
59 |
ledRedOn(); |
57 |
ispConnect(); |
60 |
ispConnect(); |
58 |
|
61 |
|
59 |
} else if (data[1] == USBASP_FUNC_DISCONNECT) { |
62 |
} else if (data[1] == USBASP_FUNC_DISCONNECT) { |
60 |
ispDisconnect(); |
63 |
ispDisconnect(); |
61 |
ledRedOff(); |
64 |
ledRedOff(); |
62 |
|
65 |
|
63 |
} else if (data[1] == USBASP_FUNC_TRANSMIT) { |
66 |
} else if (data[1] == USBASP_FUNC_TRANSMIT) { |
64 |
replyBuffer[0] = ispTransmit(data[2]); |
67 |
replyBuffer[0] = ispTransmit(data[2]); |
65 |
replyBuffer[1] = ispTransmit(data[3]); |
68 |
replyBuffer[1] = ispTransmit(data[3]); |
66 |
replyBuffer[2] = ispTransmit(data[4]); |
69 |
replyBuffer[2] = ispTransmit(data[4]); |
67 |
replyBuffer[3] = ispTransmit(data[5]); |
70 |
replyBuffer[3] = ispTransmit(data[5]); |
68 |
len = 4; |
71 |
len = 4; |
69 |
|
72 |
|
70 |
} else if (data[1] == USBASP_FUNC_READFLASH) { |
73 |
} else if (data[1] == USBASP_FUNC_READFLASH) { |
71 |
|
74 |
|
72 |
if (!prog_address_newmode) |
75 |
if (!prog_address_newmode) |
73 |
prog_address = (data[3] << 8) | data[2]; |
76 |
prog_address = (data[3] << 8) | data[2]; |
74 |
|
77 |
|
75 |
prog_nbytes = (data[7] << 8) | data[6]; |
78 |
prog_nbytes = (data[7] << 8) | data[6]; |
76 |
prog_state = PROG_STATE_READFLASH; |
79 |
prog_state = PROG_STATE_READFLASH; |
77 |
len = 0xff; /* multiple in */ |
80 |
len = 0xff; /* multiple in */ |
78 |
|
81 |
|
79 |
} else if (data[1] == USBASP_FUNC_READEEPROM) { |
82 |
} else if (data[1] == USBASP_FUNC_READEEPROM) { |
80 |
|
83 |
|
81 |
if (!prog_address_newmode) |
84 |
if (!prog_address_newmode) |
82 |
prog_address = (data[3] << 8) | data[2]; |
85 |
prog_address = (data[3] << 8) | data[2]; |
83 |
|
86 |
|
84 |
prog_nbytes = (data[7] << 8) | data[6]; |
87 |
prog_nbytes = (data[7] << 8) | data[6]; |
85 |
prog_state = PROG_STATE_READEEPROM; |
88 |
prog_state = PROG_STATE_READEEPROM; |
86 |
len = 0xff; /* multiple in */ |
89 |
len = 0xff; /* multiple in */ |
87 |
|
90 |
|
88 |
} else if (data[1] == USBASP_FUNC_ENABLEPROG) { |
91 |
} else if (data[1] == USBASP_FUNC_ENABLEPROG) { |
89 |
replyBuffer[0] = ispEnterProgrammingMode(); |
92 |
replyBuffer[0] = ispEnterProgrammingMode(); |
90 |
len = 1; |
93 |
len = 1; |
91 |
|
94 |
|
92 |
} else if (data[1] == USBASP_FUNC_WRITEFLASH) { |
95 |
} else if (data[1] == USBASP_FUNC_WRITEFLASH) { |
93 |
|
96 |
|
94 |
if (!prog_address_newmode) |
97 |
if (!prog_address_newmode) |
95 |
prog_address = (data[3] << 8) | data[2]; |
98 |
prog_address = (data[3] << 8) | data[2]; |
96 |
|
99 |
|
97 |
prog_pagesize = data[4]; |
100 |
prog_pagesize = data[4]; |
98 |
prog_blockflags = data[5] & 0x0F; |
101 |
prog_blockflags = data[5] & 0x0F; |
99 |
prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); |
102 |
prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); |
100 |
if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { |
103 |
if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { |
101 |
prog_pagecounter = prog_pagesize; |
104 |
prog_pagecounter = prog_pagesize; |
102 |
} |
105 |
} |
103 |
prog_nbytes = (data[7] << 8) | data[6]; |
106 |
prog_nbytes = (data[7] << 8) | data[6]; |
104 |
prog_state = PROG_STATE_WRITEFLASH; |
107 |
prog_state = PROG_STATE_WRITEFLASH; |
105 |
len = 0xff; /* multiple out */ |
108 |
len = 0xff; /* multiple out */ |
106 |
|
109 |
|
107 |
} else if (data[1] == USBASP_FUNC_WRITEEEPROM) { |
110 |
} else if (data[1] == USBASP_FUNC_WRITEEEPROM) { |
108 |
|
111 |
|
109 |
if (!prog_address_newmode) |
112 |
if (!prog_address_newmode) |
110 |
prog_address = (data[3] << 8) | data[2]; |
113 |
prog_address = (data[3] << 8) | data[2]; |
111 |
|
114 |
|
112 |
prog_pagesize = 0; |
115 |
prog_pagesize = 0; |
113 |
prog_blockflags = 0; |
116 |
prog_blockflags = 0; |
114 |
prog_nbytes = (data[7] << 8) | data[6]; |
117 |
prog_nbytes = (data[7] << 8) | data[6]; |
115 |
prog_state = PROG_STATE_WRITEEEPROM; |
118 |
prog_state = PROG_STATE_WRITEEEPROM; |
116 |
len = 0xff; /* multiple out */ |
119 |
len = 0xff; /* multiple out */ |
117 |
|
120 |
|
118 |
} else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { |
121 |
} else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { |
119 |
|
122 |
|
120 |
/* set new mode of address delivering (ignore address delivered in commands) */ |
123 |
/* set new mode of address delivering (ignore address delivered in commands) */ |
121 |
prog_address_newmode = 1; |
124 |
prog_address_newmode = 1; |
122 |
/* set new address */ |
125 |
/* set new address */ |
123 |
prog_address = *((unsigned long*) &data[2]); |
126 |
prog_address = *((unsigned long*) &data[2]); |
124 |
|
127 |
|
125 |
} else if (data[1] == USBASP_FUNC_SETISPSCK) { |
128 |
} else if (data[1] == USBASP_FUNC_SETISPSCK) { |
126 |
|
129 |
|
127 |
/* set sck option */ |
130 |
/* set sck option */ |
128 |
prog_sck = data[2]; |
131 |
prog_sck = data[2]; |
129 |
replyBuffer[0] = 0; |
132 |
replyBuffer[0] = 0; |
130 |
len = 1; |
133 |
len = 1; |
131 |
|
134 |
|
132 |
} else if (data[1] == USBASP_FUNC_TPI_CONNECT) { |
135 |
} else if (data[1] == USBASP_FUNC_TPI_CONNECT) { |
133 |
tpi_dly_cnt = data[2] | (data[3] << 8); |
136 |
tpi_dly_cnt = data[2] | (data[3] << 8); |
134 |
|
137 |
|
135 |
/* RST high */ |
138 |
/* RST high */ |
136 |
ISP_OUT |= (1 << ISP_RST); |
139 |
ISP_OUT |= (1 << ISP_RST); |
137 |
ISP_DDR |= (1 << ISP_RST); |
140 |
ISP_DDR |= (1 << ISP_RST); |
138 |
|
141 |
|
139 |
clockWait(3); |
142 |
clockWait(3); |
140 |
|
143 |
|
141 |
/* RST low */ |
144 |
/* RST low */ |
142 |
ISP_OUT &= ~(1 << ISP_RST); |
145 |
ISP_OUT &= ~(1 << ISP_RST); |
143 |
ledRedOn(); |
146 |
ledRedOn(); |
144 |
|
147 |
|
145 |
clockWait(16); |
148 |
clockWait(16); |
146 |
tpi_init(); |
149 |
tpi_init(); |
147 |
|
150 |
|
148 |
} else if (data[1] == USBASP_FUNC_TPI_DISCONNECT) { |
151 |
} else if (data[1] == USBASP_FUNC_TPI_DISCONNECT) { |
149 |
|
152 |
|
150 |
tpi_send_byte(TPI_OP_SSTCS(TPISR)); |
153 |
tpi_send_byte(TPI_OP_SSTCS(TPISR)); |
151 |
tpi_send_byte(0); |
154 |
tpi_send_byte(0); |
152 |
|
155 |
|
153 |
clockWait(10); |
156 |
clockWait(10); |
154 |
|
157 |
|
155 |
/* pulse RST */ |
158 |
/* pulse RST */ |
156 |
ISP_OUT |= (1 << ISP_RST); |
159 |
ISP_OUT |= (1 << ISP_RST); |
157 |
clockWait(5); |
160 |
clockWait(5); |
158 |
ISP_OUT &= ~(1 << ISP_RST); |
161 |
ISP_OUT &= ~(1 << ISP_RST); |
159 |
clockWait(5); |
162 |
clockWait(5); |
160 |
|
163 |
|
161 |
/* set all ISP pins inputs */ |
164 |
/* set all ISP pins inputs */ |
162 |
ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
165 |
ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
163 |
/* switch pullups off */ |
166 |
/* switch pullups off */ |
164 |
ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
167 |
ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
165 |
|
168 |
|
166 |
ledRedOff(); |
169 |
ledRedOff(); |
167 |
|
170 |
|
168 |
} else if (data[1] == USBASP_FUNC_TPI_RAWREAD) { |
171 |
} else if (data[1] == USBASP_FUNC_TPI_RAWREAD) { |
169 |
replyBuffer[0] = tpi_recv_byte(); |
172 |
replyBuffer[0] = tpi_recv_byte(); |
170 |
len = 1; |
173 |
len = 1; |
171 |
|
174 |
|
172 |
} else if (data[1] == USBASP_FUNC_TPI_RAWWRITE) { |
175 |
} else if (data[1] == USBASP_FUNC_TPI_RAWWRITE) { |
173 |
tpi_send_byte(data[2]); |
176 |
tpi_send_byte(data[2]); |
174 |
|
177 |
|
175 |
} else if (data[1] == USBASP_FUNC_TPI_READBLOCK) { |
178 |
} else if (data[1] == USBASP_FUNC_TPI_READBLOCK) { |
176 |
prog_address = (data[3] << 8) | data[2]; |
179 |
prog_address = (data[3] << 8) | data[2]; |
177 |
prog_nbytes = (data[7] << 8) | data[6]; |
180 |
prog_nbytes = (data[7] << 8) | data[6]; |
178 |
prog_state = PROG_STATE_TPI_READ; |
181 |
prog_state = PROG_STATE_TPI_READ; |
179 |
len = 0xff; /* multiple in */ |
182 |
len = 0xff; /* multiple in */ |
180 |
|
183 |
|
181 |
} else if (data[1] == USBASP_FUNC_TPI_WRITEBLOCK) { |
184 |
} else if (data[1] == USBASP_FUNC_TPI_WRITEBLOCK) { |
182 |
prog_address = (data[3] << 8) | data[2]; |
185 |
prog_address = (data[3] << 8) | data[2]; |
183 |
prog_nbytes = (data[7] << 8) | data[6]; |
186 |
prog_nbytes = (data[7] << 8) | data[6]; |
184 |
prog_state = PROG_STATE_TPI_WRITE; |
187 |
prog_state = PROG_STATE_TPI_WRITE; |
185 |
len = 0xff; /* multiple out */ |
188 |
len = 0xff; /* multiple out */ |
186 |
|
189 |
|
187 |
} else if (data[1] == USBASP_FUNC_GETCAPABILITIES) { |
190 |
} else if (data[1] == USBASP_FUNC_GETCAPABILITIES) { |
188 |
replyBuffer[0] = USBASP_CAP_0_TPI; |
191 |
replyBuffer[0] = USBASP_CAP_0_TPI; |
189 |
replyBuffer[1] = 0; |
192 |
replyBuffer[1] = 0; |
190 |
replyBuffer[2] = 0; |
193 |
replyBuffer[2] = 0; |
191 |
replyBuffer[3] = 0; |
194 |
replyBuffer[3] = 0; |
192 |
len = 4; |
195 |
len = 4; |
193 |
} |
196 |
} |
194 |
|
197 |
|
195 |
usbMsgPtr = replyBuffer; |
198 |
usbMsgPtr = replyBuffer; |
196 |
|
199 |
|
197 |
return len; |
200 |
return len; |
198 |
} |
201 |
} |
199 |
|
202 |
|
200 |
uchar usbFunctionRead(uchar *data, uchar len) { |
203 |
uchar usbFunctionRead(uchar *data, uchar len) { |
201 |
|
204 |
|
202 |
uchar i; |
205 |
uchar i; |
203 |
|
206 |
|
204 |
/* check if programmer is in correct read state */ |
207 |
/* check if programmer is in correct read state */ |
205 |
if ((prog_state != PROG_STATE_READFLASH) && (prog_state |
208 |
if ((prog_state != PROG_STATE_READFLASH) && (prog_state |
206 |
!= PROG_STATE_READEEPROM) && (prog_state != PROG_STATE_TPI_READ)) { |
209 |
!= PROG_STATE_READEEPROM) && (prog_state != PROG_STATE_TPI_READ)) { |
207 |
return 0xff; |
210 |
return 0xff; |
208 |
} |
211 |
} |
209 |
|
212 |
|
210 |
/* fill packet TPI mode */ |
213 |
/* fill packet TPI mode */ |
211 |
if(prog_state == PROG_STATE_TPI_READ) |
214 |
if(prog_state == PROG_STATE_TPI_READ) |
212 |
{ |
215 |
{ |
213 |
tpi_read_block(prog_address, data, len); |
216 |
tpi_read_block(prog_address, data, len); |
214 |
prog_address += len; |
217 |
prog_address += len; |
215 |
return len; |
218 |
return len; |
216 |
} |
219 |
} |
217 |
|
220 |
|
218 |
/* fill packet ISP mode */ |
221 |
/* fill packet ISP mode */ |
219 |
for (i = 0; i < len; i++) { |
222 |
for (i = 0; i < len; i++) { |
220 |
if (prog_state == PROG_STATE_READFLASH) { |
223 |
if (prog_state == PROG_STATE_READFLASH) { |
221 |
data[i] = ispReadFlash(prog_address); |
224 |
data[i] = ispReadFlash(prog_address); |
222 |
} else { |
225 |
} else { |
223 |
data[i] = ispReadEEPROM(prog_address); |
226 |
data[i] = ispReadEEPROM(prog_address); |
224 |
} |
227 |
} |
225 |
prog_address++; |
228 |
prog_address++; |
226 |
} |
229 |
} |
227 |
|
230 |
|
228 |
/* last packet? */ |
231 |
/* last packet? */ |
229 |
if (len < 8) { |
232 |
if (len < 8) { |
230 |
prog_state = PROG_STATE_IDLE; |
233 |
prog_state = PROG_STATE_IDLE; |
231 |
} |
234 |
} |
232 |
|
235 |
|
233 |
return len; |
236 |
return len; |
234 |
} |
237 |
} |
235 |
|
238 |
|
236 |
uchar usbFunctionWrite(uchar *data, uchar len) { |
239 |
uchar usbFunctionWrite(uchar *data, uchar len) { |
237 |
|
240 |
|
238 |
uchar retVal = 0; |
241 |
uchar retVal = 0; |
239 |
uchar i; |
242 |
uchar i; |
240 |
|
243 |
|
241 |
/* check if programmer is in correct write state */ |
244 |
/* check if programmer is in correct write state */ |
242 |
if ((prog_state != PROG_STATE_WRITEFLASH) && (prog_state |
245 |
if ((prog_state != PROG_STATE_WRITEFLASH) && (prog_state |
243 |
!= PROG_STATE_WRITEEEPROM) && (prog_state != PROG_STATE_TPI_WRITE)) { |
246 |
!= PROG_STATE_WRITEEEPROM) && (prog_state != PROG_STATE_TPI_WRITE)) { |
244 |
return 0xff; |
247 |
return 0xff; |
245 |
} |
248 |
} |
246 |
|
249 |
|
247 |
if (prog_state == PROG_STATE_TPI_WRITE) |
250 |
if (prog_state == PROG_STATE_TPI_WRITE) |
248 |
{ |
251 |
{ |
249 |
tpi_write_block(prog_address, data, len); |
252 |
tpi_write_block(prog_address, data, len); |
250 |
prog_address += len; |
253 |
prog_address += len; |
251 |
prog_nbytes -= len; |
254 |
prog_nbytes -= len; |
252 |
if(prog_nbytes <= 0) |
255 |
if(prog_nbytes <= 0) |
253 |
{ |
256 |
{ |
254 |
prog_state = PROG_STATE_IDLE; |
257 |
prog_state = PROG_STATE_IDLE; |
255 |
return 1; |
258 |
return 1; |
256 |
} |
259 |
} |
257 |
return 0; |
260 |
return 0; |
258 |
} |
261 |
} |
259 |
|
262 |
|
260 |
for (i = 0; i < len; i++) { |
263 |
for (i = 0; i < len; i++) { |
261 |
|
264 |
|
262 |
if (prog_state == PROG_STATE_WRITEFLASH) { |
265 |
if (prog_state == PROG_STATE_WRITEFLASH) { |
263 |
/* Flash */ |
266 |
/* Flash */ |
264 |
|
267 |
|
265 |
if (prog_pagesize == 0) { |
268 |
if (prog_pagesize == 0) { |
266 |
/* not paged */ |
269 |
/* not paged */ |
267 |
ispWriteFlash(prog_address, data[i], 1); |
270 |
ispWriteFlash(prog_address, data[i], 1); |
268 |
} else { |
271 |
} else { |
269 |
/* paged */ |
272 |
/* paged */ |
270 |
ispWriteFlash(prog_address, data[i], 0); |
273 |
ispWriteFlash(prog_address, data[i], 0); |
271 |
prog_pagecounter--; |
274 |
prog_pagecounter--; |
272 |
if (prog_pagecounter == 0) { |
275 |
if (prog_pagecounter == 0) { |
273 |
ispFlushPage(prog_address, data[i]); |
276 |
ispFlushPage(prog_address, data[i]); |
274 |
prog_pagecounter = prog_pagesize; |
277 |
prog_pagecounter = prog_pagesize; |
275 |
} |
278 |
} |
276 |
} |
279 |
} |
277 |
|
280 |
|
278 |
} else { |
281 |
} else { |
279 |
/* EEPROM */ |
282 |
/* EEPROM */ |
280 |
ispWriteEEPROM(prog_address, data[i]); |
283 |
ispWriteEEPROM(prog_address, data[i]); |
281 |
} |
284 |
} |
282 |
|
285 |
|
283 |
prog_nbytes--; |
286 |
prog_nbytes--; |
284 |
|
287 |
|
285 |
if (prog_nbytes == 0) { |
288 |
if (prog_nbytes == 0) { |
286 |
prog_state = PROG_STATE_IDLE; |
289 |
prog_state = PROG_STATE_IDLE; |
287 |
if ((prog_blockflags & PROG_BLOCKFLAG_LAST) && (prog_pagecounter |
290 |
if ((prog_blockflags & PROG_BLOCKFLAG_LAST) && (prog_pagecounter |
288 |
!= prog_pagesize)) { |
291 |
!= prog_pagesize)) { |
289 |
|
292 |
|
290 |
/* last block and page flush pending, so flush it now */ |
293 |
/* last block and page flush pending, so flush it now */ |
291 |
ispFlushPage(prog_address, data[i]); |
294 |
ispFlushPage(prog_address, data[i]); |
292 |
} |
295 |
} |
293 |
|
296 |
|
294 |
retVal = 1; // Need to return 1 when no more data is to be received |
297 |
retVal = 1; // Need to return 1 when no more data is to be received |
295 |
} |
298 |
} |
296 |
|
299 |
|
297 |
prog_address++; |
300 |
prog_address++; |
298 |
} |
301 |
} |
299 |
|
302 |
|
300 |
return retVal; |
303 |
return retVal; |
301 |
} |
304 |
} |
302 |
|
305 |
|
303 |
int main(void) { |
306 |
int main(void) { |
304 |
uchar i, j; |
307 |
uchar i, j; |
305 |
|
308 |
|
306 |
/* no pullups on USB and ISP pins */ |
309 |
/* unused pins with pullups */ |
- |
|
310 |
PORTB = PORTB_UNUSED_MASK; |
- |
|
311 |
PORTC = PORTC_UNUSED_MASK; |
307 |
PORTD = 0; |
312 |
PORTD = PORTD_UNUSED_MASK; |
- |
|
313 |
|
- |
|
314 |
/* LED ports as output */ |
308 |
PORTB = 0; |
315 |
ledInit(); |
- |
|
316 |
ledGreenOn(); |
- |
|
317 |
ledRedOff(); |
- |
|
318 |
|
309 |
/* all outputs except PD2 = INT0 */ |
319 |
/* CLKSW input with PullUp (external jumper to GND) */ |
310 |
DDRD = ~(1 << 2); |
320 |
clkswInit(); |
311 |
|
321 |
|
312 |
/* output SE0 for USB reset */ |
322 |
/* output SE0 for USB reset */ |
313 |
DDRB = ~0; |
323 |
DDR(USB_CFG_IOPORTNAME) |= (1 << USB_CFG_DPLUS_BIT | 1<<USB_CFG_DMINUS_BIT); |
314 |
j = 0; |
324 |
|
315 |
/* USB Reset by device only required on Watchdog Reset */ |
325 |
/* USB Reset by device only required on Watchdog Reset */ |
- |
|
326 |
j = 0; |
316 |
while (--j) { |
327 |
while (--j) { |
317 |
i = 0; |
328 |
i = 0; |
318 |
/* delay >10ms for USB reset */ |
329 |
/* delay >10ms for USB reset */ |
319 |
while (--i) |
330 |
while (--i) |
320 |
; |
331 |
; |
321 |
} |
332 |
} |
322 |
/* all USB and ISP pins inputs */ |
- |
|
323 |
DDRB = 0; |
- |
|
324 |
|
333 |
|
325 |
/* all inputs except PC0, PC1 */ |
334 |
/* all USB and ISP pins inputs */ |
326 |
DDRC = 0x03; |
- |
|
327 |
PORTC = 0xfe; |
335 |
DDR(USB_CFG_IOPORTNAME) &= ~(1 << USB_CFG_DPLUS_BIT | 1<<USB_CFG_DMINUS_BIT); |
328 |
|
336 |
|
329 |
/* init timer */ |
337 |
/* init timer */ |
330 |
clockInit(); |
338 |
clockInit(); |
331 |
|
339 |
|
332 |
/* main event loop */ |
340 |
/* main event loop */ |
333 |
usbInit(); |
341 |
usbInit(); |
334 |
sei(); |
342 |
sei(); |
335 |
for (;;) { |
343 |
for (;;) { |
336 |
usbPoll(); |
344 |
usbPoll(); |
337 |
} |
345 |
} |
338 |
return 0; |
346 |
return 0; |
339 |
} |
347 |
} |
340 |
|
- |
|