Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 861 lines (738 sloc) 21.028 kb
fc828ae piece of shit.
mellis authored
1 /*
2 * avrdude - A Downloader/Uploader for AVR device programmers
3 * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /* $Id: avr.c,v 1.74 2007/05/16 20:15:13 joerg_wunsch Exp $ */
21
22 #include "ac_cfg.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/time.h>
29 #include <time.h>
30
31 #include "avrdude.h"
32
33 #include "avr.h"
34 #include "lists.h"
35 #include "pindefs.h"
36 #include "ppi.h"
37 #include "safemode.h"
38 #include "update.h"
39
40 FP_UpdateProgress update_progress;
41
42 #define DEBUG 0
43
44 int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
45 unsigned long addr, unsigned char * value)
46 {
47 unsigned char cmd[4];
48 unsigned char res[4];
49 unsigned char data;
50 OPCODE * readop, * lext;
51
52 if (pgm->cmd == NULL) {
53 fprintf(stderr,
54 "%s: Error: %s programmer uses avr_read_byte_default() but does not\n"
55 "provide a cmd() method.\n",
56 progname, pgm->type);
57 return -1;
58 }
59
60 pgm->pgm_led(pgm, ON);
61 pgm->err_led(pgm, OFF);
62
63 /*
64 * figure out what opcode to use
65 */
66 if (mem->op[AVR_OP_READ_LO]) {
67 if (addr & 0x00000001)
68 readop = mem->op[AVR_OP_READ_HI];
69 else
70 readop = mem->op[AVR_OP_READ_LO];
71 addr = addr / 2;
72 }
73 else {
74 readop = mem->op[AVR_OP_READ];
75 }
76
77 if (readop == NULL) {
78 #if DEBUG
79 fprintf(stderr,
80 "avr_read_byte(): operation not supported on memory type \"%s\"\n",
81 p->desc);
82 #endif
83 return -1;
84 }
85
86 /*
87 * If this device has a "load extended address" command, issue it.
88 */
89 lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
90 if (lext != NULL) {
91 memset(cmd, 0, sizeof(cmd));
92
93 avr_set_bits(lext, cmd);
94 avr_set_addr(lext, cmd, addr);
95 pgm->cmd(pgm, cmd, res);
96 }
97
98 memset(cmd, 0, sizeof(cmd));
99
100 avr_set_bits(readop, cmd);
101 avr_set_addr(readop, cmd, addr);
102 pgm->cmd(pgm, cmd, res);
103 data = 0;
104 avr_get_output(readop, res, &data);
105
106 pgm->pgm_led(pgm, OFF);
107
108 *value = data;
109
110 return 0;
111 }
112
113
114 /*
115 * Return the number of "interesting" bytes in a memory buffer,
116 * "interesting" being defined as up to the last non-0xff data
117 * value. This is useful for determining where to stop when dealing
118 * with "flash" memory, since writing 0xff to flash is typically a
119 * no-op. Always return an even number since flash is word addressed.
120 */
121 int avr_mem_hiaddr(AVRMEM * mem)
122 {
123 int i, n;
124
125 /* return the highest non-0xff address regardless of how much
126 memory was read */
127 for (i=mem->size-1; i>0; i--) {
128 if (mem->buf[i] != 0xff) {
129 n = i+1;
130 if (n & 0x01)
131 return n+1;
132 else
133 return n;
134 }
135 }
136
137 return 0;
138 }
139
140
141 /*
142 * Read the entirety of the specified memory type into the
143 * corresponding buffer of the avrpart pointed to by 'p'. If size =
144 * 0, read the entire contents, otherwise, read 'size' bytes.
145 *
146 * Return the number of bytes read, or < 0 if an error occurs.
147 */
148 int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
149 int verbose)
150 {
151 unsigned char rbyte;
152 unsigned long i;
153 unsigned char * buf;
154 AVRMEM * mem;
155 int rc;
156
157 mem = avr_locate_mem(p, memtype);
158 if (mem == NULL) {
159 fprintf(stderr, "No \"%s\" memory for part %s\n",
160 memtype, p->desc);
161 return -1;
162 }
163
164 buf = mem->buf;
165 if (size == 0) {
166 size = mem->size;
167 }
168
169 /*
170 * start with all 0xff
171 */
172 memset(buf, 0xff, size);
173
174 if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
175 if (pgm->paged_load != NULL && mem->page_size != 0) {
176 /*
177 * the programmer supports a paged mode read, perhaps more
178 * efficiently than we can read it directly, so use its routine
179 * instead
180 */
181 rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
182 if (rc >= 0) {
183 if (strcasecmp(mem->desc, "flash") == 0)
184 return avr_mem_hiaddr(mem);
185 else
186 return rc;
187 }
188 }
189 }
190
191 if (strcmp(mem->desc, "signature") == 0) {
192 if (pgm->read_sig_bytes) {
193 return pgm->read_sig_bytes(pgm, p, mem);
194 }
195 }
196
197 for (i=0; i<size; i++) {
198 rc = pgm->read_byte(pgm, p, mem, i, &rbyte);
199 if (rc != 0) {
200 fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
201 if (rc == -1)
202 fprintf(stderr,
203 " read operation not supported for memory \"%s\"\n",
204 memtype);
205 return -2;
206 }
207 buf[i] = rbyte;
208 report_progress(i, size, NULL);
209 }
210
211 if (strcasecmp(mem->desc, "flash") == 0)
212 return avr_mem_hiaddr(mem);
213 else
214 return i;
215 }
216
217
218 /*
219 * write a page data at the specified address
220 */
221 int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
222 unsigned long addr)
223 {
224 unsigned char cmd[4];
225 unsigned char res[4];
226 OPCODE * wp, * lext;
227
228 if (pgm->cmd == NULL) {
229 fprintf(stderr,
230 "%s: Error: %s programmer uses avr_write_page() but does not\n"
231 "provide a cmd() method.\n",
232 progname, pgm->type);
233 return -1;
234 }
235
236 wp = mem->op[AVR_OP_WRITEPAGE];
237 if (wp == NULL) {
238 fprintf(stderr,
239 "avr_write_page(): memory \"%s\" not configured for page writes\n",
240 mem->desc);
241 return -1;
242 }
243
244 /*
245 * if this memory is word-addressable, adjust the address
246 * accordingly
247 */
248 if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO]))
249 addr = addr / 2;
250
251 pgm->pgm_led(pgm, ON);
252 pgm->err_led(pgm, OFF);
253
254 /*
255 * If this device has a "load extended address" command, issue it.
256 */
257 lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
258 if (lext != NULL) {
259 memset(cmd, 0, sizeof(cmd));
260
261 avr_set_bits(lext, cmd);
262 avr_set_addr(lext, cmd, addr);
263 pgm->cmd(pgm, cmd, res);
264 }
265
266 memset(cmd, 0, sizeof(cmd));
267
268 avr_set_bits(wp, cmd);
269 avr_set_addr(wp, cmd, addr);
270 pgm->cmd(pgm, cmd, res);
271
272 /*
273 * since we don't know what voltage the target AVR is powered by, be
274 * conservative and delay the max amount the spec says to wait
275 */
276 usleep(mem->max_write_delay);
277
278 pgm->pgm_led(pgm, OFF);
279 return 0;
280 }
281
282
283 int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
284 unsigned long addr, unsigned char data)
285 {
286 unsigned char cmd[4];
287 unsigned char res[4];
288 unsigned char r;
289 int ready;
290 int tries;
291 unsigned long start_time;
292 unsigned long prog_time;
293 unsigned char b;
294 unsigned short caddr;
295 OPCODE * writeop;
296 int rc;
297 int readok=0;
298 struct timeval tv;
299
300 if (pgm->cmd == NULL) {
301 fprintf(stderr,
302 "%s: Error: %s programmer uses avr_write_byte_default() but does not\n"
303 "provide a cmd() method.\n",
304 progname, pgm->type);
305 return -1;
306 }
307
308 if (!mem->paged) {
309 /*
310 * check to see if the write is necessary by reading the existing
311 * value and only write if we are changing the value; we can't
312 * use this optimization for paged addressing.
313 */
314 rc = pgm->read_byte(pgm, p, mem, addr, &b);
315 if (rc != 0) {
316 if (rc != -1) {
317 return -2;
318 }
319 /*
320 * the read operation is not support on this memory type
321 */
322 }
323 else {
324 readok = 1;
325 if (b == data) {
326 return 0;
327 }
328 }
329 }
330
331 /*
332 * determine which memory opcode to use
333 */
334 if (mem->op[AVR_OP_WRITE_LO]) {
335 if (addr & 0x01)
336 writeop = mem->op[AVR_OP_WRITE_HI];
337 else
338 writeop = mem->op[AVR_OP_WRITE_LO];
339 caddr = addr / 2;
340 }
341 else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
342 if (addr & 0x01)
343 writeop = mem->op[AVR_OP_LOADPAGE_HI];
344 else
345 writeop = mem->op[AVR_OP_LOADPAGE_LO];
346 caddr = addr / 2;
347 }
348 else {
349 writeop = mem->op[AVR_OP_WRITE];
350 caddr = addr;
351 }
352
353 if (writeop == NULL) {
354 #if DEBUG
355 fprintf(stderr,
356 "avr_write_byte(): write not supported for memory type \"%s\"\n",
357 mem->desc);
358 #endif
359 return -1;
360 }
361
362
363 pgm->pgm_led(pgm, ON);
364 pgm->err_led(pgm, OFF);
365
366 memset(cmd, 0, sizeof(cmd));
367
368 avr_set_bits(writeop, cmd);
369 avr_set_addr(writeop, cmd, caddr);
370 avr_set_input(writeop, cmd, data);
371 pgm->cmd(pgm, cmd, res);
372
373 if (mem->paged) {
374 /*
375 * in paged addressing, single bytes to be written to the memory
376 * page complete immediately, we only need to delay when we commit
377 * the whole page via the avr_write_page() routine.
378 */
379 pgm->pgm_led(pgm, OFF);
380 return 0;
381 }
382
383 if (readok == 0) {
384 /*
385 * read operation not supported for this memory type, just wait
386 * the max programming time and then return
387 */
388 usleep(mem->max_write_delay); /* maximum write delay */
389 pgm->pgm_led(pgm, OFF);
390 return 0;
391 }
392
393 tries = 0;
394 ready = 0;
395 while (!ready) {
396
397 if ((data == mem->readback[0]) ||
398 (data == mem->readback[1])) {
399 /*
400 * use an extra long delay when we happen to be writing values
401 * used for polled data read-back. In this case, polling
402 * doesn't work, and we need to delay the worst case write time
403 * specified for the chip.
404 */
405 usleep(mem->max_write_delay);
406 rc = pgm->read_byte(pgm, p, mem, addr, &r);
407 if (rc != 0) {
408 pgm->pgm_led(pgm, OFF);
409 pgm->err_led(pgm, OFF);
410 return -5;
411 }
412 }
413 else {
414 gettimeofday (&tv, NULL);
415 start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
416 do {
417 /*
418 * Do polling, but timeout after max_write_delay.
419 */
420 rc = pgm->read_byte(pgm, p, mem, addr, &r);
421 if (rc != 0) {
422 pgm->pgm_led(pgm, OFF);
423 pgm->err_led(pgm, ON);
424 return -4;
425 }
426 gettimeofday (&tv, NULL);
427 prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
428 } while ((r != data) &&
429 ((prog_time-start_time) < mem->max_write_delay));
430 }
431
432 /*
433 * At this point we either have a valid readback or the
434 * max_write_delay is expired.
435 */
436
437 if (r == data) {
438 ready = 1;
439 }
440 else if (mem->pwroff_after_write) {
441 /*
442 * The device has been flagged as power-off after write to this
443 * memory type. The reason we don't just blindly follow the
444 * flag is that the power-off advice may only apply to some
445 * memory bits but not all. We only actually power-off the
446 * device if the data read back does not match what we wrote.
447 */
448 pgm->pgm_led(pgm, OFF);
449 fprintf(stderr,
450 "%s: this device must be powered off and back on to continue\n",
451 progname);
452 if (pgm->pinno[PPI_AVR_VCC]) {
453 fprintf(stderr, "%s: attempting to do this now ...\n", progname);
454 pgm->powerdown(pgm);
455 usleep(250000);
456 rc = pgm->initialize(pgm, p);
457 if (rc < 0) {
458 fprintf(stderr, "%s: initialization failed, rc=%d\n", progname, rc);
459 fprintf(stderr,
460 "%s: can't re-initialize device after programming the "
461 "%s bits\n", progname, mem->desc);
462 fprintf(stderr,
463 "%s: you must manually power-down the device and restart\n"
464 "%s: %s to continue.\n",
465 progname, progname, progname);
466 return -3;
467 }
468
469 fprintf(stderr, "%s: device was successfully re-initialized\n",
470 progname);
471 return 0;
472 }
473 }
474
475 tries++;
476 if (!ready && tries > 5) {
477 /*
478 * we wrote the data, but after waiting for what should have
479 * been plenty of time, the memory cell still doesn't match what
480 * we wrote. Indicate a write error.
481 */
482 pgm->pgm_led(pgm, OFF);
483 pgm->err_led(pgm, ON);
484
485 return -6;
486 }
487 }
488
489 pgm->pgm_led(pgm, OFF);
490 return 0;
491 }
492
493
494 /*
495 * write a byte of data at the specified address
496 */
497 int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
498 unsigned long addr, unsigned char data)
499 {
500
501 unsigned char safemode_lfuse;
502 unsigned char safemode_hfuse;
503 unsigned char safemode_efuse;
504 unsigned char safemode_fuse;
505
506 /* If we write the fuses, then we need to tell safemode that they *should* change */
507 safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
508
509 if (strcmp(mem->desc, "fuse")==0) {
510 safemode_fuse = data;
511 }
512 if (strcmp(mem->desc, "lfuse")==0) {
513 safemode_lfuse = data;
514 }
515 if (strcmp(mem->desc, "hfuse")==0) {
516 safemode_hfuse = data;
517 }
518 if (strcmp(mem->desc, "efuse")==0) {
519 safemode_efuse = data;
520 }
521
522 safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
523
524 return pgm->write_byte(pgm, p, mem, addr, data);
525 }
526
527
528 /*
529 * Write the whole memory region of the specified memory from the
530 * corresponding buffer of the avrpart pointed to by 'p'. Write up to
531 * 'size' bytes from the buffer. Data is only written if the new data
532 * value is different from the existing data value. Data beyond
533 * 'size' bytes is not affected.
534 *
535 * Return the number of bytes written, or -1 if an error occurs.
536 */
537 int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
538 int verbose)
539 {
540 int rc;
541 int wsize;
542 unsigned long i;
543 unsigned char data;
544 int werror;
545 AVRMEM * m;
546
547 m = avr_locate_mem(p, memtype);
548 if (m == NULL) {
549 fprintf(stderr, "No \"%s\" memory for part %s\n",
550 memtype, p->desc);
551 return -1;
552 }
553
554 pgm->err_led(pgm, OFF);
555
556 werror = 0;
557
558 wsize = m->size;
559 if (size < wsize) {
560 wsize = size;
561 }
562 else if (size > wsize) {
563 fprintf(stderr,
564 "%s: WARNING: %d bytes requested, but memory region is only %d"
565 "bytes\n"
566 "%sOnly %d bytes will actually be written\n",
567 progname, size, wsize,
568 progbuf, wsize);
569 }
570
571 if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
572 if (pgm->paged_write != NULL && m->page_size != 0) {
573 /*
574 * the programmer supports a paged mode write, perhaps more
575 * efficiently than we can read it directly, so use its routine
576 * instead
577 */
578 if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0)
579 return i;
580 }
581 }
582
583 if (pgm->write_setup) {
584 pgm->write_setup(pgm, p, m);
585 }
586
587 for (i=0; i<wsize; i++) {
588 data = m->buf[i];
589 report_progress(i, wsize, NULL);
590
591 rc = avr_write_byte(pgm, p, m, i, data);
592 if (rc) {
593 fprintf(stderr, " ***failed; ");
594 fprintf(stderr, "\n");
595 pgm->err_led(pgm, ON);
596 werror = 1;
597 }
598
599 if (m->paged) {
600 /*
601 * check to see if it is time to flush the page with a page
602 * write
603 */
604 if (((i % m->page_size) == m->page_size-1) ||
605 (i == wsize-1)) {
606 rc = avr_write_page(pgm, p, m, i);
607 if (rc) {
608 fprintf(stderr,
609 " *** page %ld (addresses 0x%04lx - 0x%04lx) failed "
610 "to write\n",
611 i % m->page_size,
612 i - m->page_size + 1, i);
613 fprintf(stderr, "\n");
614 pgm->err_led(pgm, ON);
615 werror = 1;
616 }
617 }
618 }
619
620 if (werror) {
621 /*
622 * make sure the error led stay on if there was a previous write
623 * error, otherwise it gets cleared in avr_write_byte()
624 */
625 pgm->err_led(pgm, ON);
626 }
627 }
628
629 return i;
630 }
631
632
633
634 /*
635 * read the AVR device's signature bytes
636 */
637 int avr_signature(PROGRAMMER * pgm, AVRPART * p)
638 {
639 int rc;
640
641 report_progress (0,1,"Reading");
642 rc = avr_read(pgm, p, "signature", 0, 0);
643 if (rc < 0) {
644 fprintf(stderr,
645 "%s: error reading signature data for part \"%s\", rc=%d\n",
646 progname, p->desc, rc);
647 return -1;
648 }
649 report_progress (1,1,NULL);
650
651 return 0;
652 }
653
654
655 /*
656 * Verify the memory buffer of p with that of v. The byte range of v,
657 * may be a subset of p. The byte range of p should cover the whole
658 * chip's memory size.
659 *
660 * Return the number of bytes verified, or -1 if they don't match.
661 */
662 int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
663 {
664 int i;
665 unsigned char * buf1, * buf2;
666 int vsize;
667 AVRMEM * a, * b;
668
669 a = avr_locate_mem(p, memtype);
670 if (a == NULL) {
671 fprintf(stderr,
672 "avr_verify(): memory type \"%s\" not defined for part %s\n",
673 memtype, p->desc);
674 return -1;
675 }
676
677 b = avr_locate_mem(v, memtype);
678 if (b == NULL) {
679 fprintf(stderr,
680 "avr_verify(): memory type \"%s\" not defined for part %s\n",
681 memtype, v->desc);
682 return -1;
683 }
684
685 buf1 = a->buf;
686 buf2 = b->buf;
687 vsize = a->size;
688
689 if (vsize < size) {
690 fprintf(stderr,
691 "%s: WARNING: requested verification for %d bytes\n"
692 "%s%s memory region only contains %d bytes\n"
693 "%sOnly %d bytes will be verified.\n",
694 progname, size,
695 progbuf, memtype, vsize,
696 progbuf, vsize);
697 size = vsize;
698 }
699
700 for (i=0; i<size; i++) {
701 if (buf1[i] != buf2[i]) {
702 fprintf(stderr,
703 "%s: verification error, first mismatch at byte 0x%04x\n"
704 "%s0x%02x != 0x%02x\n",
705 progname, i,
706 progbuf, buf1[i], buf2[i]);
707 return -1;
708 }
709 }
710
711 return size;
712 }
713
714
715 int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
716 {
717 AVRMEM * a;
718 unsigned int cycle_count = 0;
719 unsigned char v1;
720 int rc;
721 int i;
722
723 a = avr_locate_mem(p, "eeprom");
724 if (a == NULL) {
725 return -1;
726 }
727
728 for (i=4; i>0; i--) {
729 rc = pgm->read_byte(pgm, p, a, a->size-i, &v1);
730 if (rc < 0) {
731 fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
732 progname, rc);
733 return -1;
734 }
735 cycle_count = (cycle_count << 8) | v1;
736 }
737
738 /*
739 * If the EEPROM is erased, the cycle count reads 0xffffffff.
740 * In this case we return a cycle_count of zero.
741 * So, the calling function don't have to care about whether or not
742 * the cycle count was initialized.
743 */
744 if (cycle_count == 0xffffffff) {
745 cycle_count = 0;
746 }
747
748 *cycles = (int) cycle_count;
749
750 return 0;
751 }
752
753
754 int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
755 {
756 AVRMEM * a;
757 unsigned char v1;
758 int rc;
759 int i;
760
761 a = avr_locate_mem(p, "eeprom");
762 if (a == NULL) {
763 return -1;
764 }
765
766 for (i=1; i<=4; i++) {
767 v1 = cycles & 0xff;
768 cycles = cycles >> 8;
769
770 rc = avr_write_byte(pgm, p, a, a->size-i, v1);
771 if (rc < 0) {
772 fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
773 progname, rc);
774 return -1;
775 }
776 }
777
778 return 0;
779 }
780
781 int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
782 {
783 int cycles;
784 int rc;
785
786 if (do_cycles) {
787 rc = avr_get_cycle_count(pgm, p, &cycles);
788 /*
789 * Don't update the cycle counter, if read failed
790 */
791 if(rc != 0) {
792 do_cycles = 0;
793 }
794 }
795
796 rc = pgm->chip_erase(pgm, p);
797
798 /*
799 * Don't update the cycle counter, if erase failed
800 */
801 if (do_cycles && (rc == 0)) {
802 cycles++;
803 fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
804 progname, cycles);
805 avr_put_cycle_count(pgm, p, cycles);
806 }
807
808 return rc;
809 }
810
811 /*
812 * Report the progress of a read or write operation from/to the
813 * device.
814 *
815 * The first call of report_progress() should look like this (for a write op):
816 *
817 * report_progress (0, 1, "Writing");
818 *
819 * Then hdr should be passed NULL on subsequent calls while the
820 * operation is progressing. Once the operation is complete, a final
821 * call should be made as such to ensure proper termination of the
822 * progress report:
823 *
824 * report_progress (1, 1, NULL);
825 *
826 * It would be nice if we could reduce the usage to one and only one
827 * call for each of start, during and end cases. As things stand now,
828 * that is not possible and makes maintenance a bit more work.
829 */
830 void report_progress (int completed, int total, char *hdr)
831 {
832 static int last = 0;
833 static double start_time;
834 int percent = (completed * 100) / total;
835 struct timeval tv;
836 double t;
837
838 if (update_progress == NULL)
839 return;
840
841 gettimeofday(&tv, NULL);
842 t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
843
844 if (hdr) {
845 last = 0;
846 start_time = t;
847 update_progress (percent, t - start_time, hdr);
848 }
849
850 if (percent > 100)
851 percent = 100;
852
853 if (percent > last) {
854 last = percent;
855 update_progress (percent, t - start_time, hdr);
856 }
857
858 if (percent == 100)
859 last = 0; /* Get ready for next time. */
860 }
Something went wrong with that request. Please try again.