diff --git a/Makefile.am b/Makefile.am index b6fb05d5..8151ef69 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,6 +52,7 @@ avrdude_SOURCES = \ avr.h \ avr910.c \ avr910.h \ + avrpart.c \ avrpart.h \ butterfly.c \ butterfly.h \ diff --git a/avr.c b/avr.c index 066f4070..58e81c13 100644 --- a/avr.c +++ b/avr.c @@ -45,250 +45,6 @@ extern PROGRAMMER * pgm; extern int do_cycles; -AVRPART * avr_new_part(void) -{ - AVRPART * p; - - p = (AVRPART *)malloc(sizeof(AVRPART)); - if (p == NULL) { - fprintf(stderr, "new_part(): out of memory\n"); - exit(1); - } - - memset(p, 0, sizeof(*p)); - - p->id[0] = 0; - p->desc[0] = 0; - p->reset_disposition = RESET_DEDICATED; - p->retry_pulse = PIN_AVR_SCK; - p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK; - p->config_file[0] = 0; - p->lineno = 0; - - p->mem = lcreat(NULL, 0); - - return p; -} - - - -OPCODE * avr_new_opcode(void) -{ - OPCODE * m; - - m = (OPCODE *)malloc(sizeof(*m)); - if (m == NULL) { - fprintf(stderr, "avr_new_opcode(): out of memory\n"); - exit(1); - } - - memset(m, 0, sizeof(*m)); - - return m; -} - - - -AVRMEM * avr_new_memtype(void) -{ - AVRMEM * m; - - m = (AVRMEM *)malloc(sizeof(*m)); - if (m == NULL) { - fprintf(stderr, "avr_new_memtype(): out of memory\n"); - exit(1); - } - - memset(m, 0, sizeof(*m)); - - return m; -} - - -AVRMEM * avr_dup_mem(AVRMEM * m) -{ - AVRMEM * n; - - n = avr_new_memtype(); - - *n = *m; - - n->buf = (unsigned char *)malloc(n->size); - if (n->buf == NULL) { - fprintf(stderr, - "avr_dup_mem(): out of memory (memsize=%d)\n", - n->size); - exit(1); - } - memset(n->buf, 0, n->size); - - return n; -} - - -AVRPART * avr_dup_part(AVRPART * d) -{ - AVRPART * p; - LISTID save; - LNODEID ln; - - p = avr_new_part(); - save = p->mem; - - *p = *d; - - p->mem = save; - - for (ln=lfirst(d->mem); ln; ln=lnext(ln)) { - ladd(p->mem, avr_dup_mem(ldata(ln))); - } - - return p; -} - - - -AVRMEM * avr_locate_mem(AVRPART * p, char * desc) -{ - AVRMEM * m, * match; - LNODEID ln; - int matches; - int l; - - l = strlen(desc); - matches = 0; - match = NULL; - for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { - m = ldata(ln); - if (strncmp(desc, m->desc, l) == 0) { - match = m; - matches++; - } - } - - if (matches == 1) - return match; - - return NULL; -} - - - - -/* - * avr_set_bits() - * - * Set instruction bits in the specified command based on the opcode. - */ -int avr_set_bits(OPCODE * op, unsigned char * cmd) -{ - int i, j, bit; - unsigned char mask; - - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_VALUE) { - j = 3 - i / 8; - bit = i % 8; - mask = 1 << bit; - if (op->bit[i].value) - cmd[j] = cmd[j] | mask; - else - cmd[j] = cmd[j] & ~mask; - } - } - - return 0; -} - - -/* - * avr_set_addr() - * - * Set address bits in the specified command based on the opcode, and - * the address. - */ -int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr) -{ - int i, j, bit; - unsigned long value; - unsigned char mask; - - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_ADDRESS) { - j = 3 - i / 8; - bit = i % 8; - mask = 1 << bit; - value = addr >> op->bit[i].bitno & 0x01; - if (value) - cmd[j] = cmd[j] | mask; - else - cmd[j] = cmd[j] & ~mask; - } - } - - return 0; -} - - -/* - * avr_set_input() - * - * Set input data bits in the specified command based on the opcode, - * and the data byte. - */ -int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data) -{ - int i, j, bit; - unsigned char value; - unsigned char mask; - - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_INPUT) { - j = 3 - i / 8; - bit = i % 8; - mask = 1 << bit; - value = data >> op->bit[i].bitno & 0x01; - if (value) - cmd[j] = cmd[j] | mask; - else - cmd[j] = cmd[j] & ~mask; - } - } - - return 0; -} - - -/* - * avr_get_output() - * - * Retreive output data bits from the command results based on the - * opcode data. - */ -int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data) -{ - int i, j, bit; - unsigned char value; - unsigned char mask; - - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_OUTPUT) { - j = 3 - i / 8; - bit = i % 8; - mask = 1 << bit; - value = ((res[j] & mask) >> bit) & 0x01; - value = value << op->bit[i].bitno; - if (value) - *data = *data | value; - else - *data = *data & ~value; - } - } - - return 0; -} - - int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char * value) { @@ -506,7 +262,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, /* * since we don't know what voltage the target AVR is powered by, be - * conservative and delay the max amount the spec says to wait + * conservative and delay the max amount the spec says to wait */ usleep(mem->max_write_delay); @@ -832,7 +588,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, if (werror) { /* * make sure the error led stay on if there was a previous write - * error, otherwise it gets cleared in avr_write_byte() + * error, otherwise it gets cleared in avr_write_byte() */ pgm->err_led(pgm, ON); } @@ -852,7 +608,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p) report_progress (0,1,"Reading"); rc = avr_read(pgm, p, "signature", 0, 0); if (rc < 0) { - fprintf(stderr, + fprintf(stderr, "%s: error reading signature data for part \"%s\", rc=%d\n", progname, p->desc, rc); return -1; @@ -863,35 +619,12 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p) } -/* - * 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. + * Return the number of bytes verified, or -1 if they don't match. */ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size) { @@ -1045,174 +778,3 @@ int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles) 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 ""; 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 ""; 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; iop[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 ""; - } -} - - -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 ""; - } -} - - -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); -} - - diff --git a/avr.h b/avr.h index c93efe97..a197335d 100644 --- a/avr.h +++ b/avr.h @@ -33,29 +33,14 @@ extern struct avrpart parts[]; - -AVRPART * avr_find_part(char * p); - -AVRPART * avr_new_part(void); - -OPCODE * avr_new_opcode(void); - -AVRMEM * avr_new_memtype(void); - -AVRPART * avr_dup_part(AVRPART * d); - -AVRMEM * avr_locate_mem(AVRPART * p, char * desc); - int avr_txrx_bit(int fd, int bit); unsigned char avr_txrx(int fd, unsigned char byte); -int avr_set_bits(OPCODE * op, unsigned char * cmd); - -int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, +int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char * value); -int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, +int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, int verbose); int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, @@ -64,7 +49,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char data); -int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, +int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, int verbose); int avr_signature(PROGRAMMER * pgm, AVRPART * p); @@ -75,11 +60,9 @@ int avr_initmem(AVRPART * p); int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size); -void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type, +void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type, int verbose); -void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose); - int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles); int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);; diff --git a/avrpart.c b/avrpart.c new file mode 100644 index 00000000..eb6ec3d9 --- /dev/null +++ b/avrpart.c @@ -0,0 +1,473 @@ + +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id$ */ + +#include +#include + +#include "avrpart.h" +#include "pindefs.h" + +extern char * progname; + + +/*** + *** Elementary functions dealing with OPCODE structures + ***/ + +OPCODE * avr_new_opcode(void) +{ + OPCODE * m; + + m = (OPCODE *)malloc(sizeof(*m)); + if (m == NULL) { + fprintf(stderr, "avr_new_opcode(): out of memory\n"); + exit(1); + } + + memset(m, 0, sizeof(*m)); + + return m; +} + + +/* + * avr_set_bits() + * + * Set instruction bits in the specified command based on the opcode. + */ +int avr_set_bits(OPCODE * op, unsigned char * cmd) +{ + int i, j, bit; + unsigned char mask; + + for (i=0; i<32; i++) { + if (op->bit[i].type == AVR_CMDBIT_VALUE) { + j = 3 - i / 8; + bit = i % 8; + mask = 1 << bit; + if (op->bit[i].value) + cmd[j] = cmd[j] | mask; + else + cmd[j] = cmd[j] & ~mask; + } + } + + return 0; +} + + +/* + * avr_set_addr() + * + * Set address bits in the specified command based on the opcode, and + * the address. + */ +int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr) +{ + int i, j, bit; + unsigned long value; + unsigned char mask; + + for (i=0; i<32; i++) { + if (op->bit[i].type == AVR_CMDBIT_ADDRESS) { + j = 3 - i / 8; + bit = i % 8; + mask = 1 << bit; + value = addr >> op->bit[i].bitno & 0x01; + if (value) + cmd[j] = cmd[j] | mask; + else + cmd[j] = cmd[j] & ~mask; + } + } + + return 0; +} + + +/* + * avr_set_input() + * + * Set input data bits in the specified command based on the opcode, + * and the data byte. + */ +int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data) +{ + int i, j, bit; + unsigned char value; + unsigned char mask; + + for (i=0; i<32; i++) { + if (op->bit[i].type == AVR_CMDBIT_INPUT) { + j = 3 - i / 8; + bit = i % 8; + mask = 1 << bit; + value = data >> op->bit[i].bitno & 0x01; + if (value) + cmd[j] = cmd[j] | mask; + else + cmd[j] = cmd[j] & ~mask; + } + } + + return 0; +} + + +/* + * avr_get_output() + * + * Retreive output data bits from the command results based on the + * opcode data. + */ +int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data) +{ + int i, j, bit; + unsigned char value; + unsigned char mask; + + for (i=0; i<32; i++) { + if (op->bit[i].type == AVR_CMDBIT_OUTPUT) { + j = 3 - i / 8; + bit = i % 8; + mask = 1 << bit; + value = ((res[j] & mask) >> bit) & 0x01; + value = value << op->bit[i].bitno; + if (value) + *data = *data | value; + else + *data = *data & ~value; + } + } + + 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 ""; 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 ""; break; + } +} + + + +/*** + *** Elementary functions dealing with AVRMEM structures + ***/ + +AVRMEM * avr_new_memtype(void) +{ + AVRMEM * m; + + m = (AVRMEM *)malloc(sizeof(*m)); + if (m == NULL) { + fprintf(stderr, "avr_new_memtype(): out of memory\n"); + exit(1); + } + + memset(m, 0, sizeof(*m)); + + return m; +} + + +/* + * 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; +} + + +AVRMEM * avr_dup_mem(AVRMEM * m) +{ + AVRMEM * n; + + n = avr_new_memtype(); + + *n = *m; + + n->buf = (unsigned char *)malloc(n->size); + if (n->buf == NULL) { + fprintf(stderr, + "avr_dup_mem(): out of memory (memsize=%d)\n", + n->size); + exit(1); + } + memset(n->buf, 0, n->size); + + return n; +} + + +AVRMEM * avr_locate_mem(AVRPART * p, char * desc) +{ + AVRMEM * m, * match; + LNODEID ln; + int matches; + int l; + + l = strlen(desc); + matches = 0; + match = NULL; + for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { + m = ldata(ln); + if (strncmp(desc, m->desc, l) == 0) { + match = m; + matches++; + } + } + + if (matches == 1) + return match; + + return NULL; +} + + +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; iop[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); + } + } + } + } + } +} + + + +/* + * Elementary functions dealing with AVRPART structures + */ + + +AVRPART * avr_new_part(void) +{ + AVRPART * p; + + p = (AVRPART *)malloc(sizeof(AVRPART)); + if (p == NULL) { + fprintf(stderr, "new_part(): out of memory\n"); + exit(1); + } + + memset(p, 0, sizeof(*p)); + + p->id[0] = 0; + p->desc[0] = 0; + p->reset_disposition = RESET_DEDICATED; + p->retry_pulse = PIN_AVR_SCK; + p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK; + p->config_file[0] = 0; + p->lineno = 0; + + p->mem = lcreat(NULL, 0); + + return p; +} + + +AVRPART * avr_dup_part(AVRPART * d) +{ + AVRPART * p; + LISTID save; + LNODEID ln; + + p = avr_new_part(); + save = p->mem; + + *p = *d; + + p->mem = save; + + for (ln=lfirst(d->mem); ln; ln=lnext(ln)) { + ladd(p->mem, avr_dup_mem(ldata(ln))); + } + + return p; +} + + +char * reset_disp_str(int r) +{ + switch (r) { + case RESET_DEDICATED : return "dedicated"; + case RESET_IO : return "possible i/o"; + default : return ""; + } +} + + +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 ""; + } +} + + +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); +} diff --git a/avrpart.h b/avrpart.h index 11275978..ea501f80 100644 --- a/avrpart.h +++ b/avrpart.h @@ -116,4 +116,24 @@ typedef struct avrmem { OPCODE * op[AVR_OP_MAX]; /* opcodes */ } AVRMEM; +/* Functions for OPCODE structures */ +OPCODE * avr_new_opcode(void); +int avr_set_bits(OPCODE * op, unsigned char * cmd); +int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr); +int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data); +int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data); + +/* Functions for AVRMEM structures */ +AVRMEM * avr_new_memtype(void); +int avr_initmem(AVRPART * p); +AVRMEM * avr_dup_mem(AVRMEM * m); +AVRMEM * avr_locate_mem(AVRPART * p, char * desc); +void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type, + int verbose); + +/* Functions for AVRPART structures */ +AVRPART * avr_new_part(void); +AVRPART * avr_dup_part(AVRPART * d); +void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose); + #endif