2003-03-23 Theodore A. Roth * avr.c (avr_write): Add call to pgm->write_setup() before the write loop. * avr910.c: Change all show_func_info() calls to no_show_func_info(). Add read/write to/from flash/eeprom memory functionality. * pgm.c: Initialize pgm->write_setup. * pgm.h: Add write_setup field to PROGRAMMER structure. * ser_posix.c: Remove unneeded cast in verbosity code. Index: avr.c =================================================================== RCS file: /cvsroot/avrdude/avrdude/avr.c,v retrieving revision 1.54 diff -u -r1.54 avr.c --- avr.c 23 Mar 2003 23:22:50 -0000 1.54 +++ avr.c 24 Mar 2003 06:55:32 -0000 @@ -733,6 +733,10 @@ } } + if (pgm->write_setup) { + pgm->write_setup(pgm, p, m); + } + for (i=0; ibuf[i]; if (verbose) { Index: avr910.c =================================================================== RCS file: /cvsroot/avrdude/avrdude/avr910.c,v retrieving revision 1.3 diff -u -r1.3 avr910.c --- avr910.c 17 Mar 2003 06:20:01 -0000 1.3 +++ avr910.c 24 Mar 2003 06:55:33 -0000 @@ -67,7 +67,7 @@ static int avr910_drain(PROGRAMMER * pgm, int display) { - show_func_info(); + no_show_func_info(); return serial_drain(pgm->fd, display); } @@ -139,14 +139,29 @@ return 0; } + +static void avr910_enter_prog_mode(PROGRAMMER * pgm) +{ + avr910_send(pgm, "P", 1); + avr910_vfy_cmd_sent(pgm, "enter prog mode"); +} + + +static void avr910_leave_prog_mode(PROGRAMMER * pgm) +{ + avr910_send(pgm, "L", 1); + avr910_vfy_cmd_sent(pgm, "leave prog mode"); +} + + /* * issue the 'program enable' command to the AVR device */ static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p) { - show_func_info(); + no_show_func_info(); - return -1; + return 0; } @@ -176,20 +191,6 @@ } -static void avr910_enter_prog_mode(PROGRAMMER * pgm) -{ - avr910_send(pgm, "P", 1); - avr910_vfy_cmd_sent(pgm, "enter prog mode"); -} - - -static void avr910_leave_prog_mode(PROGRAMMER * pgm) -{ - avr910_send(pgm, "L", 1); - avr910_vfy_cmd_sent(pgm, "leave prog mode"); -} - - /* * initialize the AVR device and prepare it to accept commands */ @@ -203,7 +204,7 @@ unsigned char c; int dev_supported = 0; - show_func_info(); + no_show_func_info(); /* Get the programmer identifier. Programmer returns exactly 7 chars _without_ the null.*/ @@ -316,7 +317,7 @@ { int i; - show_func_info(); + no_show_func_info(); for (i=0; i<4; i++) { fprintf(stderr, "cmd[%d] = 0x%02x\n", i, cmd[i]); @@ -352,11 +353,137 @@ static void avr910_display(PROGRAMMER * pgm, char * p) { - show_func_info(); + no_show_func_info(); return; } + +static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr) +{ + unsigned char cmd[3]; + + cmd[0] = 'A'; + cmd[1] = (addr >> 8) & 0xff; + cmd[2] = addr & 0xff; + + avr910_send(pgm, cmd, sizeof(cmd)); + avr910_vfy_cmd_sent(pgm, "set addr"); +} + + +/* + * For some reason, if we don't do this when writing to flash, the first byte + * of flash is not programmed. I susect that the board got out of sync after + * the erase and sending another command gets us back in sync. -TRoth + */ +static void avr910_write_setup(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) +{ + if (strcmp(m->desc, "flash") == 0) { + avr910_send(pgm, "y", 1); + avr910_vfy_cmd_sent(pgm, "clear LED"); + } +} + + +static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned long addr, unsigned char value) +{ + unsigned char cmd[2]; + + no_show_func_info(); + + if (strcmp(m->desc, "flash") == 0) { + if (addr & 0x01) { + cmd[0] = 'C'; /* Write Program Mem high byte */ + } + else { + cmd[0] = 'c'; + } + + addr >>= 1; + } + else if (strcmp(m->desc, "eeprom") == 0) { + cmd[0] = 'D'; + } + else { + return -1; + } + + cmd[1] = value; + + avr910_set_addr(pgm, addr); + + avr910_send(pgm, cmd, sizeof(cmd)); + avr910_vfy_cmd_sent(pgm, "write byte"); + + return 0; +} + + +static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned long addr, unsigned char * value) +{ + static int cached = 0; + static unsigned char cvalue; + static unsigned long caddr; + + if (cached && ((caddr + 1) == addr)) { + *value = cvalue; + cached = 0; + } + else { + unsigned char buf[2]; + + avr910_set_addr(pgm, addr >> 1); + + avr910_send(pgm, "R", 1); + + /* Read back the program mem word (MSB first) */ + avr910_recv(pgm, buf, sizeof(buf)); + + if ((addr & 0x01) == 0) { + *value = buf[1]; + cached = 1; + cvalue = buf[0]; + caddr = addr; + } + else { + *value = buf[0]; + } + } + + return 0; +} + + +static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned long addr, unsigned char * value) +{ + avr910_set_addr(pgm, addr); + avr910_send(pgm, "d", 1); + avr910_recv(pgm, value, 1); + + return 0; +} + + +static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned long addr, unsigned char * value) +{ + no_show_func_info(); + + if (strcmp(m->desc, "flash") == 0) { + return avr910_read_byte_flash(pgm, p, m, addr, value); + } + + if (strcmp(m->desc, "eeprom") == 0) { + return avr910_read_byte_eeprom(pgm, p, m, addr, value); + } + + return -1; +} + /* Signature byte reads are always 3 bytes. */ static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) @@ -406,5 +533,8 @@ * optional functions */ + pgm->write_setup = avr910_write_setup; + pgm->write_byte = avr910_write_byte; + pgm->read_byte = avr910_read_byte; pgm->read_sig_bytes = avr910_read_sig_bytes; } Index: pgm.c =================================================================== RCS file: /cvsroot/avrdude/avrdude/pgm.c,v retrieving revision 1.12 diff -u -r1.12 pgm.c --- pgm.c 23 Mar 2003 23:22:50 -0000 1.12 +++ pgm.c 24 Mar 2003 06:55:33 -0000 @@ -89,6 +89,7 @@ */ pgm->paged_write = NULL; pgm->paged_load = NULL; + pgm->write_setup = NULL; pgm->write_byte = NULL; pgm->read_byte = NULL; pgm->read_sig_bytes = NULL; Index: pgm.h =================================================================== RCS file: /cvsroot/avrdude/avrdude/pgm.h,v retrieving revision 1.12 diff -u -r1.12 pgm.h --- pgm.h 23 Mar 2003 23:22:50 -0000 1.12 +++ pgm.h 24 Mar 2003 06:55:33 -0000 @@ -66,6 +66,7 @@ int page_size, int n_bytes); int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes); + void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m); int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char value); int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, Index: ser_posix.c =================================================================== RCS file: /cvsroot/avrdude/avrdude/ser_posix.c,v retrieving revision 1.5 diff -u -r1.5 ser_posix.c --- ser_posix.c 24 Mar 2003 02:37:33 -0000 1.5 +++ ser_posix.c 24 Mar 2003 06:55:33 -0000 @@ -168,14 +168,14 @@ fprintf(stderr, "%s: Send: ", progname); while (buflen) { - char c = *buf; + unsigned char c = *buf; if (isprint(c)) { fprintf(stderr, "%c ", c); } else { fprintf(stderr, ". "); } - fprintf(stderr, "[%02x] ", ((unsigned int)c) & 0xff); + fprintf(stderr, "[%02x] ", c); buf++; buflen--; @@ -277,14 +277,14 @@ fprintf(stderr, "%s: Recv: ", progname); while (len) { - char c = *p; + unsigned char c = *p; if (isprint(c)) { fprintf(stderr, "%c ", c); } else { fprintf(stderr, ". "); } - fprintf(stderr, "[%02x] ", ((unsigned int)c &0xff)); + fprintf(stderr, "[%02x] ", c); p++; len--;