/[uisp]/uisp/src/AvrAtmel.C
ViewVC logotype

Contents of /uisp/src/AvrAtmel.C

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show annotations) (download)
Mon Jun 24 13:10:43 2002 UTC (21 years, 10 months ago) by marekm
Branch: MAIN
CVS Tags: rel-20020626, rel-20020626-rc1
Changes since 1.5: +9 -2 lines
File MIME type: text/plain
	* configure.in (AM_INIT_AUTOMAKE): Update version.
	* pavr/pavr.c: Add ATmega323 support.

	* src/AvrAtmel.C (ChipErase): Wait up to 5 seconds for chip erase.
	* src/Serial.C (Tx, Rx): Use Info() instead of fprintf() to log
	sent and received characters (now enabled at run time with -v=4).
	(Send): Accept optional timeout argument, default is 1 second.
	* src/Serial.h (DEBUG_LOG_TX, DEBUG_LOG_RX): Remove.
	(Send): Update for optional timeout argument.
	Thanks to Bryce Denney <bryce@tlw.com> for suggestions.

1 /*
2 * $Id: AvrAtmel.C,v 1.5 2002/06/08 22:59:42 marekm Exp $
3 *
4 ****************************************************************************
5 *
6 * uisp - The Micro In-System Programmer for Atmel AVR microcontrollers.
7 * Copyright (C) 1999, 2000, 2001, 2002 Uros Platise
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 ****************************************************************************
24 */
25
26 /*
27 AvrAtmel.C
28
29 Device driver for the Serial Atmel Low Cost Programmer
30 Uros Platise (c) 1999
31 */
32
33 #include "config.h"
34
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include "AvrAtmel.h"
42
43 #define AUTO_SELECT 0
44
45 /* Low Cost Atmel Programmer AVR Codes
46 Valid for software version: SW_MAJOR=2 SW_MINOR=0
47
48 Code 0xff is reserved for invalid code. Update the
49 TAvrAtmel constructor if Atmel comes up with it.
50
51 The list is current as of AVRProg 1.37 (shipped with AVR Studio 3.54).
52 */
53 TAvrAtmel::SPrgPart TAvrAtmel::prg_part [] = {
54 {"S1200A", 0x10, "AT90S1200 rev. A", false}, /* old */
55 {"S1200B", 0x11, "AT90S1200 rev. B", false}, /* old */
56 {"S1200C", 0x12, "AT90S1200 rev. C", false}, /* old */
57 {"S1200", 0x13, "AT90S1200", false},
58 {"S2313", 0x20, "AT90S2313", false},
59 {"S4414", 0x28, "AT90S4414", false},
60 {"S4433", 0x30, "AT90S4433", false},
61 {"S2333", 0x34, "AT90S2333", false},
62 {"S8515", 0x38, "AT90S8515", false},
63 {"M8515", 0x3A, "ATmega8515", false},
64 {"M8515b", 0x3B, "ATmega8515 BOOT", false},
65 {"M103C", 0x40, "ATmega103 rev. C", false}, /* old */
66 {"M103", 0x41, "ATmega103", false},
67 {"M603", 0x42, "ATmega603", false},
68 {"M128", 0x43, "ATmega128", false},
69 {"M128b", 0x44, "ATmega128 BOOT", false},
70 {"S2323", 0x48, "AT90S2323", false},
71 {"S2343", 0x4C, "AT90S2343", false}, /* ATtiny22 too */
72 {"TN11", 0x50, "ATtiny11", false}, /* parallel */
73 {"TN10", 0x51, "ATtiny10", false}, /* parallel */
74 {"TN12", 0x55, "ATtiny12", false},
75 {"TN15", 0x56, "ATtiny15", false},
76 {"TN19", 0x58, "ATtiny19", false}, /* parallel */
77 {"TN28", 0x5C, "ATtiny28", false}, /* parallel */
78 {"TN26", 0x5E, "ATtiny26", false},
79 {"M161", 0x60, "ATmega161", false},
80 {"M161b", 0x61, "ATmega161 BOOT", false},
81 {"M163", 0x64, "ATmega163", false},
82 {"M83", 0x65, "ATmega83", false}, /* ATmega8535 ??? */
83 {"M163b", 0x66, "ATmega163 BOOT", false},
84 {"M83b", 0x67, "ATmega83 BOOT", false},
85 {"S8535", 0x68, "AT90S8535", false},
86 {"S4434", 0x6C, "AT90S4434", false},
87 {"C8534", 0x70, "AT90C8534", false}, /* parallel */
88 {"C8544", 0x71, "AT90C8544", false}, /* parallel ??? */
89 {"M32", 0x72, "ATmega32", false}, /* XXX no ATmega323 */
90 {"M32b", 0x73, "ATmega32 BOOT", false},
91 {"M16", 0x74, "ATmega16", false},
92 {"M16b", 0x75, "ATmega16 BOOT", false},
93 {"M8", 0x76, "ATmega8", false},
94 {"M8b", 0x77, "ATmega8 BOOT", false},
95 {"89C1051",0x80, "AT89C1051", false}, /* parallel */
96 {"89C2051",0x81, "AT89C2051", false}, /* parallel */
97 {"89C51", 0x82, "AT89C51", false}, /* parallel */
98 {"89LV51", 0x83, "AT89LV51", false}, /* parallel */
99 {"89C52", 0x84, "AT89C52", false}, /* parallel */
100 {"89LV52", 0x85, "AT89LV52", false}, /* parallel */
101 {"S8252", 0x86, "AT89S8252", false},
102 {"89S53", 0x87, "AT89S53", false},
103 /* 0x88..0xDF reserved for AT89,
104 0xE0..0xFF reserved */
105 {"auto", AUTO_SELECT, "Auto detect", false},
106 {"", 0x00, "", false}
107 };
108
109 /* Private Functions
110 */
111
112 void TAvrAtmel::EnterProgrammingMode(){
113 /* Select Device Type */
114 TByte set_device[2] = {'T', desired_avrcode};
115 Send(set_device, 2, 1);
116 CheckResponse(set_device[0]);
117
118 /* Enter Programming Mode */
119 TByte enter_prg[1] = {'P'};
120 Send(enter_prg, 1);
121 CheckResponse(enter_prg[0]);
122
123 /* Read Signature Bytes */
124 TByte sig_bytes[3] = {'s', 0, 0};
125 Send(sig_bytes, 1, 3);
126 part_number = sig_bytes[0];
127 part_family = sig_bytes[1];
128 vendor_code = sig_bytes[2];
129 }
130
131 void TAvrAtmel::LeaveProgrammingMode(){
132 TByte leave_prg [1] = { 'L' };
133 Send(leave_prg, 1);
134 }
135
136 void TAvrAtmel::CheckResponse(TByte x){
137 if (x!=13){throw Error_Device ("Device is not responding correctly.");}
138 }
139
140 void TAvrAtmel::EnableAvr(){
141 bool auto_select = desired_avrcode == AUTO_SELECT;
142
143 for (unsigned pidx=0; prg_part[pidx].code != AUTO_SELECT; pidx++){
144
145 if (!prg_part[pidx].supported && auto_select){continue;}
146 if (auto_select){
147 desired_avrcode = prg_part[pidx].code;
148 Info(2, "Trying with: %s\n", prg_part[pidx].description);
149 }
150 EnterProgrammingMode();
151 if (!auto_select ||
152 !(vendor_code==0 && part_family==1 && part_number==2)){
153 break;
154 }
155 LeaveProgrammingMode();
156 }
157
158 // OverridePart("atmega163"); // XXXXX local hack for broken signature bytes
159
160 Identify();
161
162 if (auto_select){
163 /* If avr was recongnized by the Identify(), try to find better match
164 in the support list.
165 */
166 unsigned better_pidx = 0;
167 TByte better_avrcode = desired_avrcode;
168
169 for (unsigned pidx=0; prg_part[pidx].code != AUTO_SELECT; pidx++){
170 if (!prg_part[pidx].supported){continue;}
171 if (strstr(prg_part[pidx].description, GetPartName())){
172 better_avrcode = prg_part[better_pidx = pidx].code;
173 }
174 }
175 if (better_avrcode != desired_avrcode){
176 Info(2, "Retrying with better match: %s\n",
177 prg_part[better_pidx].description);
178 desired_avrcode = better_avrcode;
179 LeaveProgrammingMode();
180 EnterProgrammingMode();
181 Identify();
182 }
183 }
184 }
185
186 void TAvrAtmel::SetAddress(TAddr addr){
187 apc_address = addr;
188 TByte setAddr [3] = { 'A', (addr>>8)&0xff, addr&0xff};
189 Send(setAddr, 3, 1);
190 CheckResponse(setAddr [0]);
191 }
192
193 void TAvrAtmel::WriteProgramMemoryPage(){
194 SetAddress(page_addr >> 1);
195 TByte prg_page [1] = { 'm' };
196 Send(prg_page, 1);
197 }
198
199 /* Device Interface Functions
200 */
201
202 TByte TAvrAtmel::ReadByte(TAddr addr){
203 CheckMemoryRange(addr);
204 if (segment==SEG_FLASH){
205 TAddr saddr = addr>>1;
206 TByte rdF [2] = { 'R', 0 };
207
208 if (buf_addr==addr && cache_lowbyte==true){return buf_lowbyte;}
209 if (apc_address!=saddr || apc_autoinc==false) SetAddress(saddr);
210 apc_address++;
211 Send(rdF, 1, 2);
212 /* cache low byte */
213 cache_lowbyte = true;
214 buf_addr = (saddr<<1) + 1;
215 buf_lowbyte = rdF[0];
216 return rdF [1 - (addr&1)];
217 }
218 else if (segment==SEG_EEPROM){
219 SetAddress(addr);
220 TByte readEE [1] = { 'd' };
221 Send(readEE, 1);
222 return readEE[0];
223 }
224 else if (segment==SEG_FUSE) {
225 TByte readback = 0xff;
226 switch (addr) {
227 case AVR_FUSE_LOW_ADDR:
228 if (TestFeatures(AVR_FUSE_RD))
229 readback = ReadFuseLowBits();
230 #if 0
231 /* TRoth/2002-06-03: This case is handled by ReadLockBits() so we don't
232 need it here. Can I delete it completely? */
233 else if (TestFeatures(AVR_LOCK_RD76))
234 readback = ReadLockFuseBits();
235 #endif
236 break;
237 case AVR_FUSE_HIGH_ADDR:
238 if (TestFeatures(AVR_FUSE_HIGH))
239 readback = ReadFuseHighBits();
240 else
241 Info (1, "Cannot read high fuse bits on this device. Returning 0xff\n");
242 break;
243 case AVR_CAL_ADDR:
244 if (TestFeatures(AVR_CAL_RD))
245 readback = ReadCalByte(0);
246 else
247 Info (1, "Cannot read calibration byte on this device. Returning 0xff\n");
248 break;
249 case AVR_LOCK_ADDR:
250 readback = ReadLockBits();
251 break;
252 case AVR_FUSE_EXT_ADDR:
253 if (TestFeatures(AVR_FUSE_EXT))
254 readback = ReadFuseExtBits();
255 else
256 Info (1, "Cannot read extended fuse bits on this device. Returning 0xff\n");
257 break;
258 }
259 Info(3, "Read fuse/cal/lock: byte %d = 0x%02X\n",
260 (int) addr, (int) readback);
261 return readback;
262 }
263 else return 0;
264 }
265
266 void TAvrAtmel::WriteByte(TAddr addr, TByte byte, bool flush_buffer){
267 CheckMemoryRange(addr);
268
269 /* do not check if byte is already written -- it spoils auto-increment
270 feature which reduces the speed for 50%!
271 */
272 if (segment==SEG_FLASH){
273
274 cache_lowbyte = false; /* clear read cache buffer */
275 if (!page_size && byte==0xff) return;
276
277 /* PAGE MODE PROGRAMMING:
278 If page mode is enabled cache page address.
279 When current address is out of the page address
280 flush page buffer and continue programming.
281 */
282 if (page_size){
283 Info(4, "Loading data to address: %d (page_addr_fetched=%s)\n",
284 addr, page_addr_fetched?"Yes":"No");
285
286 if (page_addr_fetched && page_addr != (addr & ~(page_size - 1))){
287 WriteProgramMemoryPage();
288 page_addr_fetched = false;
289 }
290 if (page_addr_fetched==false){
291 page_addr=addr & ~(page_size - 1);
292 page_addr_fetched=true;
293 }
294 if (flush_buffer){WriteProgramMemoryPage();}
295 }
296
297 TByte wrF [2] = { (addr&1)?'C':'c', byte };
298
299 if (apc_address!=(addr>>1) || apc_autoinc==false) SetAddress (addr>>1);
300 if (wrF[0]=='C') apc_address++;
301 Send(wrF, 2, 1);
302 CheckResponse(wrF[0]);
303 }
304 else if (segment==SEG_EEPROM){
305 SetAddress(addr);
306 TByte writeEE [2] = { 'D', byte };
307 Send(writeEE, 2, 1);
308 CheckResponse(writeEE[0]);
309 }
310 else if (segment==SEG_FUSE){
311 Info(3, "Write fuse/lock: byte %d = 0x%02X\n",
312 (int) addr, (int) byte);
313 switch (addr) {
314 case AVR_FUSE_LOW_ADDR:
315 if (TestFeatures(AVR_FUSE_NEWWR))
316 WriteFuseLowBits(byte);
317 else if (TestFeatures(AVR_FUSE_OLDWR))
318 WriteOldFuseBits(byte);
319 break;
320 case AVR_FUSE_HIGH_ADDR:
321 if (TestFeatures(AVR_FUSE_HIGH))
322 WriteFuseHighBits(byte);
323 else
324 Info (1, "Cannot write high fuse bits on this device");
325 break;
326 /* calibration byte (addr == 2) is read only */
327 case AVR_CAL_ADDR:
328 Info (1, "Cannot write calibration byte. It is read-only.\n");
329 break;
330 case AVR_LOCK_ADDR:
331 WriteLockBits(byte);
332 break;
333 case AVR_FUSE_EXT_ADDR:
334 if (TestFeatures(AVR_FUSE_EXT))
335 WriteFuseExtBits(byte);
336 }
337 }
338 }
339
340 /*
341 Write Fuse Bits (old): 7 6 5 4 3 2 1 0
342 2323,8535: x x x 1 1 1 1 FSTRT
343 2343: x x x 1 1 1 1 RCEN
344 2333,4433: x x x BODLV BODEN CKSL2 CKSL1 CKSL0
345 m103,m603: x x x 1 EESAV 1 SUT1 SUT0
346 */
347 void TAvrAtmel::WriteOldFuseBits (TByte val)
348 {
349 TByte buf[5] = {'.', 0xac, (val & 0x1f) | 0xa0, 0x00, 0xd2 };
350 Info (2, "Write fuse high bits: %02x\n", (int)val);
351 Send (buf, 5, 2);
352 CheckResponse (buf[1]);
353 }
354
355 /*
356 Write Fuse Bits (Low, new): 7 6 5 4 3 2 1 0
357 m161: 1 BTRST 1 BODLV BODEN CKSL2 CKSL1 CKSL0
358 m163,m323: BODLV BODEN 1 1 CKSL3 CKSL2 CKSL1 CKSL0
359 m8,m16,m64,m128: BODLV BODEN SUT1 SUT0 CKSL3 CKSL2 CKSL1 CKSL0
360 tn12: BODLV BODEN SPIEN RSTDI CKSL3 CKSL2 CKSL1 CKSL0
361 tn15: BODLV BODEN SPIEN RSTDI 1 1 CKSL1 CKSL0
362
363 WARNING (tn12,tn15): writing SPIEN=1 disables further low voltage programming!
364 */
365 void TAvrAtmel::WriteFuseLowBits (TByte val)
366 {
367 // use new universal command.
368 TByte buf[5] = {'.', 0xac, 0xa0, 0x00, val };
369 Info (2, "Write fuse high bits: %02x\n", (int)val);
370 Send (buf, 5, 2);
371 CheckResponse (buf[1]);
372 }
373
374 /*
375 Write Fuse Bits High: 7 6 5 4 3 2 1 0
376 m163: 1 1 1 1 1 BTSZ1 BTSZ0 BTRST
377 m323: OCDEN JTGEN 1 1 EESAV BTSZ1 BTSZ0 BTRST
378 m16,m64,m128: OCDEN JTGEN x CKOPT EESAV BTSZ1 BTSZ0 BTRST
379 m8: RSTDI WDTON x CKOPT EESAV BTSZ1 BTSZ0 BTRST
380 */
381 void TAvrAtmel::WriteFuseHighBits (TByte val)
382 {
383 // use new universal command.
384 TByte buf[5] = {'.', 0xac, 0xa8, 0x00, val };
385 Info (2, "Write fuse high bits: %02x\n", (int)val);
386 Send (buf, 5, 2);
387 CheckResponse (buf[1]);
388 }
389
390 /*
391 Write Extended Fuse Bits: 7 6 5 4 3 2 1 0
392 m64,m128: x x x x x x M103C WDTON
393 */
394 void TAvrAtmel::WriteFuseExtBits (TByte val)
395 {
396 // use new universal command.
397 TByte buf[5] = {'.', 0xac, 0xa4, 0x00, val };
398 Info (2, "Write fuse extended bits: %02x\n", (int)val);
399 Send (buf, 5, 2);
400 CheckResponse (buf[1]);
401 }
402
403
404 void TAvrAtmel::FlushWriteBuffer(){
405 if (page_addr_fetched){
406 WriteProgramMemoryPage();
407 }
408 }
409
410 /* Chip erase can take a few seconds when talking to a boot loader,
411 which does it one page at a time. */
412
413 #ifndef CHIP_ERASE_TIMEOUT
414 #define CHIP_ERASE_TIMEOUT 5
415 #endif
416
417 void TAvrAtmel::ChipErase(){
418 TByte eraseTarget [1] = { 'e' };
419 Send (eraseTarget, 1, -1, CHIP_ERASE_TIMEOUT);
420 CheckResponse(eraseTarget [0]);
421 Info(1, "Erasing device ...\nReinitializing device\n");
422 EnableAvr();
423 }
424
425 void TAvrAtmel::WriteLockBits(TByte bits){
426 TByte lockTarget [2] = { 'l', 0xF9 | ((bits << 1) & 0x06) };
427 Send (lockTarget, 2, 1);
428 CheckResponse(lockTarget [0]);
429 Info(1, "Writing lock bits ...\nReinitializing device\n");
430 EnableAvr();
431 }
432
433 TByte TAvrAtmel::ReadFuseLowBits ()
434 {
435 // use new universal command.
436 TByte buf[5] = {'.', 0x50, 0x00, 0x00, 0x00 };
437 Send (buf, 5, 2);
438 CheckResponse (buf[1]);
439 Info (2, "Read fuse low bits: %02x\n", (int)buf[0]);
440 return buf[0];
441 }
442
443 TByte TAvrAtmel::ReadFuseHighBits ()
444 {
445 // use new universal command.
446 TByte buf[5] = {'.', 0x58, 0x08, 0x00, 0x00 };
447 Send (buf, 5, 2);
448 CheckResponse (buf[1]);
449 Info (2, "Read fuse high bits: %02x\n", (int)buf[0]);
450 return buf[0];
451 }
452
453 TByte TAvrAtmel::ReadCalByte(TByte addr)
454 {
455 // use new universal command.
456 TByte buf[5] = {'.', 0x38, 0x00, addr, 0x00 };
457 Send (buf, 5, 2);
458 CheckResponse (buf[1]);
459 Info (2, "Read calibration byte: %02x\n", (int)buf[0]);
460 return buf[0];
461 }
462
463 TByte TAvrAtmel::ReadFuseExtBits ()
464 {
465 // use new universal command.
466 TByte buf[5] = {'.', 0x50, 0x08, 0x00, 0x00 };
467 Send (buf, 5, 2);
468 CheckResponse (buf[1]);
469 return buf[0];
470 Info (2, "Read extended fuse bits: %02x\n", (int)buf[0]);
471 return buf[0];
472 }
473
474 TByte TAvrAtmel::ReadLockFuseBits ()
475 {
476 // use new universal command.
477 TByte buf[5] = {'.', 0x58, 0x00, 0x00, 0x00 };
478 Send (buf, 5, 2);
479 CheckResponse (buf[1]);
480 Info (2, "Read lock bits: %02x\n", (int)buf[0]);
481 return buf[0];
482 }
483
484 // ReadLockBits tries to return the lock bits in a uniform order, despite
485 // the differences in different AVR versions. The goal is to get the lock
486 // bits into this order:
487 // x x BLB12 BLB11 BLB02 BLB01 LB2 LB1
488 // For devices that don't support a boot block, the BLB bits will be 1.
489 TByte
490 TAvrAtmel::ReadLockBits()
491 {
492 TByte rbits = 0xFF;
493 if (TestFeatures(AVR_LOCK_BOOT)) {
494 /* x x BLB12 BLB11 BLB02 BLB01 LB2 LB1 */
495 rbits = ReadLockFuseBits();
496 } else if (TestFeatures(AVR_LOCK_RD76)) {
497 rbits = ReadLockFuseBits();
498 /* LB1 LB2 x x x x x x -> 1 1 1 1 1 1 LB2 LB1 */
499 rbits = ((rbits >> 7) & 1) | ((rbits >> 5) & 1) | 0xFC;
500 } else if (TestFeatures(AVR_LOCK_RD12)) {
501 rbits = ReadLockFuseBits();
502 /* x x x x x LB2 LB1 x -> 1 1 1 1 1 1 LB2 LB1 */
503 rbits = ((rbits >> 1) & 3) | 0xFC;
504 } else {
505 // if its signature returns 0,1,2 then say it's locked.
506 /* Read Signature Bytes */
507 TByte sig_bytes[3] = {'s', 0, 0};
508 Send(sig_bytes, 1, 3);
509 if (sig_bytes[0]==0 && sig_bytes[1]==1 && sig_bytes[2]==2)
510 rbits = 0xFC;
511 else
512 throw Error_Device ("ReadLockBits failed: are you sure this device has lock bits?");
513 }
514 return rbits;
515 }
516
517
518 /* Constructor/Destructor
519 */
520
521 TAvrAtmel::TAvrAtmel():
522 cache_lowbyte(false), apc_address(0x10000), apc_autoinc(false)
523 {
524
525 /* Select Part by Number or Name */
526 desired_avrcode=0xff;
527 const char* desired_partname = GetCmdParam("-dpart");
528 bool got_device=false;
529
530 if (desired_partname!=NULL) {
531 if (desired_partname[0] >= '0' && desired_partname[0] <= '9'){
532 desired_avrcode = strtol(&desired_partname[0],(char**)NULL,16);
533 } else{
534 int j;
535 for (j=0; prg_part[j].name[0] != 0; j++){
536 if (strcasecmp (desired_partname, prg_part[j].name)==0){
537 desired_avrcode = prg_part[j].code;
538 break;
539 }
540 }
541 if (prg_part[j].name[0]==0){throw Error_Device("-dpart: Invalid name.");}
542 }
543 }
544
545 /* check: software version and supported part codes */
546 TByte sw_version [2] = {'V', 0};
547 TByte hw_version [2] = {'v', 0};
548 Send(sw_version, 1, 2);
549 Send(hw_version, 1, 2);
550 Info(1, "Programmer Information:\n"
551 " Software Version: %c.%c, Hardware Version: %c.%c\n",
552 sw_version [0], sw_version [1],
553 hw_version [0], hw_version [1]);
554
555 /* Detect Auto-Increment */
556 if (sw_version[0]>='2'){
557 apc_autoinc=true;
558 Info(2, "Address Auto Increment Optimization Enabled\n");
559 }
560
561 /* Retrieve supported codes */
562 TByte sup_codes[1] = {'t'};
563 TByte sup_prg_code[32];
564 Tx(sup_codes, 1);
565 TByte buf_code;
566 timeval timeout = {1, 0};
567 int i=0;
568 if (desired_partname==NULL){
569 Info(1, " Supported Parts:\n\tNo\tAbbreviation\tDescription\n");
570 }
571 do{
572 Rx(&buf_code, 1, &timeout);
573 sup_prg_code[i++] = buf_code;
574 if (buf_code==0){break;}
575 if (desired_partname!=NULL){
576 if (buf_code==desired_avrcode){got_device=true;}
577 if (desired_avrcode!=AUTO_SELECT) continue;
578 }
579 int j;
580 for (j=0; prg_part[j].name[0] != 0; j++){
581 if (prg_part[j].code == buf_code){
582 prg_part[j].supported = true;
583 if (desired_avrcode!=AUTO_SELECT){
584 Info(1, "\t%.2x\t%s\t\t%s\n",
585 buf_code, prg_part[j].name, prg_part[j].description);
586 }
587 break;
588 }
589 }
590 if (prg_part[j].code == 0) {
591 Info(1, " - %.2xh (not on the uisp's list yet)\n", buf_code);
592 }
593 } while (1);
594 Info(1, "\n");
595
596 if (got_device==false) {
597 if (desired_partname==NULL){
598 throw Error_Device("Select a part from the list with the: -dpart\n"
599 "or use the -dpart=auto option for auto-select.\n");
600 }
601 else if (desired_avrcode!=AUTO_SELECT){
602 throw Error_Device("Programmer does not supported chosen device.");
603 }
604 }
605
606 EnableAvr();
607 }
608
609 TAvrAtmel::~TAvrAtmel(){
610 /* leave programming mode! Due to this
611 procedure, enableAvr had to be taken out
612 of TAtmelAvr::TAtmelAvr func. */
613 LeaveProgrammingMode();
614 }

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26