📄 avr.c
字号:
*/ rc = avr_read_byte(pgm, p, mem, addr, &r); if (rc != 0) { pgm->pgm_led(pgm, OFF); pgm->err_led(pgm, ON); return -4; } gettimeofday (&tv, NULL); prog_time = (tv.tv_sec * 1000000) + tv.tv_usec; } while ((r != data) && ((prog_time-start_time) < mem->max_write_delay)); } /* * At this point we either have a valid readback or the * max_write_delay is expired. */ if (r == data) { ready = 1; } else if (mem->pwroff_after_write) { /* * The device has been flagged as power-off after write to this * memory type. The reason we don't just blindly follow the * flag is that the power-off advice may only apply to some * memory bits but not all. We only actually power-off the * device if the data read back does not match what we wrote. */ pgm->pgm_led(pgm, OFF); fprintf(stderr, "%s: this device must be powered off and back on to continue\n", progname); if (pgm->pinno[PPI_AVR_VCC]) { fprintf(stderr, "%s: attempting to do this now ...\n", progname); pgm->powerdown(pgm); usleep(250000); rc = pgm->initialize(pgm, p); if (rc < 0) { fprintf(stderr, "%s: initialization failed, rc=%d\n", progname, rc); fprintf(stderr, "%s: can't re-initialize device after programming the " "%s bits\n", progname, mem->desc); fprintf(stderr, "%s: you must manually power-down the device and restart\n" "%s: %s to continue.\n", progname, progname, progname); return -3; } fprintf(stderr, "%s: device was successfully re-initialized\n", progname); return 0; } } tries++; if (!ready && tries > 5) { /* * we wrote the data, but after waiting for what should have * been plenty of time, the memory cell still doesn't match what * we wrote. Indicate a write error. */ pgm->pgm_led(pgm, OFF); pgm->err_led(pgm, ON); return -6; } } pgm->pgm_led(pgm, OFF); return 0;}/* * write a byte of data at the specified address */int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char data){ unsigned char safemode_lfuse; unsigned char safemode_hfuse; unsigned char safemode_efuse; unsigned char safemode_fuse; int rc; /* If we write the fuses, then we need to tell safemode that they *should* change */ safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse); if (strcmp(mem->desc, "fuse")==0) { safemode_fuse = data; } if (strcmp(mem->desc, "lfuse")==0) { safemode_lfuse = data; } if (strcmp(mem->desc, "hfuse")==0) { safemode_hfuse = data; } if (strcmp(mem->desc, "efuse")==0) { safemode_efuse = data; } safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse); if (pgm->write_byte) { rc = pgm->write_byte(pgm, p, mem, addr, data); if (rc == 0) { return rc; } /* write_byte() method failed, try again with default. */ } return avr_write_byte_default(pgm, p, mem, addr, data);}/* * Write the whole memory region of the specified memory from the * corresponding buffer of the avrpart pointed to by 'p'. Write up to * 'size' bytes from the buffer. Data is only written if the new data * value is different from the existing data value. Data beyond * 'size' bytes is not affected. * * Return the number of bytes written, or -1 if an error occurs. */int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, int verbose){ int rc; int wsize; unsigned long i; unsigned char data; int werror; AVRMEM * m; m = avr_locate_mem(p, memtype); if (m == NULL) { fprintf(stderr, "No \"%s\" memory for part %s\n", memtype, p->desc); return -1; } pgm->err_led(pgm, OFF); werror = 0; wsize = m->size; if (size < wsize) { wsize = size; } else if (size > wsize) { fprintf(stderr, "%s: WARNING: %d bytes requested, but memory region is only %d" "bytes\n" "%sOnly %d bytes will actually be written\n", progname, size, wsize, progbuf, wsize); } if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) { if (pgm->paged_write != NULL) { /* * the programmer supports a paged mode write, perhaps more * efficiently than we can read it directly, so use its routine * instead */ return pgm->paged_write(pgm, p, m, m->page_size, size); } } if (pgm->write_setup) { pgm->write_setup(pgm, p, m); } for (i=0; i<wsize; i++) { data = m->buf[i]; report_progress(i, wsize, NULL); rc = avr_write_byte(pgm, p, m, i, data); if (rc) { fprintf(stderr, " ***failed; "); fprintf(stderr, "\n"); pgm->err_led(pgm, ON); werror = 1; } if (m->paged) { /* * check to see if it is time to flush the page with a page * write */ if (((i % m->page_size) == m->page_size-1) || (i == wsize-1)) { rc = avr_write_page(pgm, p, m, i); if (rc) { fprintf(stderr, " *** page %ld (addresses 0x%04lx - 0x%04lx) failed " "to write\n", i % m->page_size, i - m->page_size + 1, i); fprintf(stderr, "\n"); pgm->err_led(pgm, ON); werror = 1; } } } if (werror) { /* * make sure the error led stay on if there was a previous write * error, otherwise it gets cleared in avr_write_byte() */ pgm->err_led(pgm, ON); } } return i;}/* * read the AVR device's signature bytes */int avr_signature(PROGRAMMER * pgm, AVRPART * p){ int rc; report_progress (0,1,"Reading"); rc = avr_read(pgm, p, "signature", 0, 0); if (rc < 0) { fprintf(stderr, "%s: error reading signature data for part \"%s\", rc=%d\n", progname, p->desc, rc); return -1; } report_progress (1,1,NULL); return 0;}/* * Verify the memory buffer of p with that of v. The byte range of v, * may be a subset of p. The byte range of p should cover the whole * chip's memory size. * * Return the number of bytes verified, or -1 if they don't match. */int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size){ int i; unsigned char * buf1, * buf2; int vsize; AVRMEM * a, * b; a = avr_locate_mem(p, memtype); if (a == NULL) { fprintf(stderr, "avr_verify(): memory type \"%s\" not defined for part %s\n", memtype, p->desc); return -1; } b = avr_locate_mem(v, memtype); if (b == NULL) { fprintf(stderr, "avr_verify(): memory type \"%s\" not defined for part %s\n", memtype, v->desc); return -1; } buf1 = a->buf; buf2 = b->buf; vsize = a->size; if (vsize < size) { fprintf(stderr, "%s: WARNING: requested verification for %d bytes\n" "%s%s memory region only contains %d bytes\n" "%sOnly %d bytes will be verified.\n", progname, size, progbuf, memtype, vsize, progbuf, vsize); size = vsize; } for (i=0; i<size; i++) { if (buf1[i] != buf2[i]) { fprintf(stderr, "%s: verification error, first mismatch at byte 0x%04x\n" "%s0x%02x != 0x%02x\n", progname, i, progbuf, buf1[i], buf2[i]); return -1; } } return size;}int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles){ AVRMEM * a; unsigned int cycle_count = 0; unsigned char v1; int rc; int i; a = avr_locate_mem(p, "eeprom"); if (a == NULL) { return -1; } for (i=4; i>0; i--) { rc = avr_read_byte(pgm, p, a, a->size-i, &v1); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n", progname, rc); return -1; } cycle_count = (cycle_count << 8) | v1; } /* * If the EEPROM is erased, the cycle count reads 0xffffffff. * In this case we return a cycle_count of zero. * So, the calling function don't have to care about whether or not * the cycle count was initialized. */ if (cycle_count == 0xffffffff) { cycle_count = 0; } *cycles = (int) cycle_count; return 0;}int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles){ AVRMEM * a; unsigned char v1; int rc; int i; a = avr_locate_mem(p, "eeprom"); if (a == NULL) { return -1; } for (i=1; i<=4; i++) { v1 = cycles & 0xff; cycles = cycles >> 8; rc = avr_write_byte(pgm, p, a, a->size-i, v1); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n", progname, rc); return -1; } } return 0; }int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p){ int cycles; int rc; if (do_cycles) { rc = avr_get_cycle_count(pgm, p, &cycles); /* * Don't update the cycle counter, if read failed */ if(rc != 0) { do_cycles = 0; } } rc = pgm->chip_erase(pgm, p); /* * Don't update the cycle counter, if erase failed */ if (do_cycles && (rc == 0)) { cycles++; fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n", progname, cycles); avr_put_cycle_count(pgm, p, cycles); } return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -