📄 avr.c
字号:
usleep(mem->min_write_delay); rc = avr_read_byte(pgm, p, mem, addr, &r); if (rc != 0) { pgm->pgm_led(pgm, OFF); pgm->err_led(pgm, ON); return -4; } if ((data == mem->readback[0]) || (data == mem->readback[1])) { /* * use an extra long delay when we happen to be writing values * used for polled data read-back. In this case, polling * doesn't work, and we need to delay the worst case write time * specified for the chip. */ usleep(mem->max_write_delay); rc = avr_read_byte(pgm, p, mem, addr, &r); if (rc != 0) { pgm->pgm_led(pgm, OFF); pgm->err_led(pgm, OFF); return -5; } } 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. */ usleep(mem->max_write_delay); /* maximum write delay */ 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 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; int printed; 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); printed = 0; 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); } } for (i=0; i<wsize; i++) { data = m->buf[i]; if (verbose) { if ((i % 16 == 0)||(i == (wsize-1))) { fprintf(stderr, "\r \r%6lu", i); printed = 1; } } 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); } } if (printed) fprintf(stderr, "\n"); return i;}/* * read the AVR device's signature bytes */int avr_signature(PROGRAMMER * pgm, AVRPART * p){ int rc; 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; } return 0;}/* * Allocate and initialize memory buffers for each of the device's * defined memory regions. */int avr_initmem(AVRPART * p){ LNODEID ln; AVRMEM * m; for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { m = ldata(ln); m->buf = (unsigned char *) malloc(m->size); if (m->buf == NULL) { fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n", progname, m->desc, m->size); return -1; } } 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; int cycle_count; unsigned char v1, v2, v3, v4; int rc; a = avr_locate_mem(p, "eeprom"); if (a == NULL) { return -1; } rc = avr_read_byte(pgm, p, a, a->size-4, &v1); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_read_byte(pgm, p, a, a->size-3, &v2); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_read_byte(pgm, p, a, a->size-2, &v3); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_read_byte(pgm, p, a, a->size-1, &v4); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n", progname, rc); return -1; } if ((v1 == 0xff) && (v2 == 0xff) && (v3 != 0xff) && (v4 != 0xff)) { v1 = 0; v2 = 0; } cycle_count = (((unsigned int)v1) << 24) | (((unsigned int)v2) << 16) | (((unsigned int)v3) << 8) | v4; *cycles = cycle_count; return 0;}int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles){ AVRMEM * a; unsigned char v1, v2, v3, v4; int rc; a = avr_locate_mem(p, "eeprom"); if (a == NULL) { return -1; } v4 = cycles & 0x0ff; v3 = (cycles & 0x0ff00) >> 8; v2 = (cycles & 0x0ff0000) >> 16; v1 = (cycles & 0x0ff000000) >> 24; rc = avr_write_byte(pgm, p, a, a->size-4, v1); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_write_byte(pgm, p, a, a->size-3, v2); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_write_byte(pgm, p, a, a->size-2, v3); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n", progname, rc); return -1; } rc = avr_write_byte(pgm, p, a, a->size-1, v4); if (rc < 0) { fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n", progname, rc); return -1; } return 0;}char * avr_op_str(int op){ switch (op) { case AVR_OP_READ : return "READ"; break; case AVR_OP_WRITE : return "WRITE"; break; case AVR_OP_READ_LO : return "READ_LO"; break; case AVR_OP_READ_HI : return "READ_HI"; break; case AVR_OP_WRITE_LO : return "WRITE_LO"; break; case AVR_OP_WRITE_HI : return "WRITE_HI"; break; case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break; case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break; case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break; case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break; case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break; default : return "<unknown opcode>"; break; }}char * bittype(int type){ switch (type) { case AVR_CMDBIT_IGNORE : return "IGNORE"; break; case AVR_CMDBIT_VALUE : return "VALUE"; break; case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break; case AVR_CMDBIT_INPUT : return "INPUT"; break; case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break; default : return "<unknown bit type>"; break; }}void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type, int verbose){ int i, j; char * optr; if (m == NULL) { fprintf(f, "%s Page Polled\n" "%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n" "%s----------- ------ ------ ---- ------ ----- ----- ---------\n", prefix, prefix, prefix); } else { if (verbose > 2) { fprintf(f, "%s Page Polled\n" "%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n" "%s----------- ------ ------ ---- ------ ----- ----- ---------\n", prefix, prefix, prefix); } fprintf(f, "%s%-11s %-6s %6d %4d %5d %5d %5d 0x%02x 0x%02x\n", prefix, m->desc, m->paged ? "yes" : "no", m->size, m->page_size, m->num_pages, m->min_write_delay, m->max_write_delay, m->readback[0], m->readback[1]); if (verbose > 2) { fprintf(stderr, "%s Memory Ops:\n" "%s Oeration Inst Bit Bit Type Bitno Value\n" "%s ----------- -------- -------- ----- -----\n", prefix, prefix, prefix); for (i=0; i<AVR_OP_MAX; i++) { if (m->op[i]) { for (j=31; j>=0; j--) { if (j==31) optr = avr_op_str(i); else optr = " "; fprintf(f, "%s %-11s %8d %8s %5d %5d\n", prefix, optr, j, bittype(m->op[i]->bit[j].type), m->op[i]->bit[j].bitno, m->op[i]->bit[j].value); } } } } }}char * reset_disp_str(int r){ switch (r) { case RESET_DEDICATED : return "dedicated"; case RESET_IO : return "possible i/o"; default : return "<invalid>"; }}char * pin_name(int pinno){ switch (pinno) { case PIN_AVR_RESET : return "RESET"; case PIN_AVR_MISO : return "MISO"; case PIN_AVR_MOSI : return "MOSI"; case PIN_AVR_SCK : return "SCK"; default : return "<unknown>"; }}void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose){ int i; char * buf; char * px; LNODEID ln; AVRMEM * m; fprintf(f, "%sAVR Part : %s\n" "%sChip Erase delay : %d us\n" "%sPAGEL : P%02X\n" "%sBS2 : P%02X\n" "%sRESET disposition : %s\n" "%sRETRY pulse : %s\n" "%sserial program mode : %s\n" "%sparallel program mode : %s\n" "%sMemory Detail :\n\n", prefix, p->desc, prefix, p->chip_erase_delay, prefix, p->pagel, prefix, p->bs2, prefix, reset_disp_str(p->reset_disposition), prefix, pin_name(p->retry_pulse), prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no", prefix, (p->flags & AVRPART_PARALLELOK) ? ((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no", prefix); px = prefix; i = strlen(prefix) + 5; buf = (char *)malloc(i); if (buf == NULL) { /* ugh, this is not important enough to bail, just ignore it */ } else { strcpy(buf, prefix); strcat(buf, " "); px = buf; } if (verbose <= 2) { avr_mem_display(px, f, NULL, 0, verbose); } for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { m = ldata(ln); avr_mem_display(px, f, m, i, verbose); } if (buf) free(buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -