Rev 3471 Rev 3472
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   -