diff --git a/isp_down.c b/isp_down.c index 7795401..08be7fa 100644 --- a/isp_down.c +++ b/isp_down.c @@ -1,439 +1,552 @@ +#include +#include +#include +#include #include #include -#include -#include -#define BAUDRATE B115200 +#define DEVICE "/dev/usb/tts/0" +#define BAUDRATE B38400 +#define TIMEOUT 1000 struct chip_ { - char shortname[8]; - char longname[16]; - char signatur[3]; - int flash_size; - int eeprom_size; + char shortname[8]; + char longname[16]; + char signature[3]; + char devicecode; + int flash_size; + int eeprom_size; }; typedef struct chip_ CHIP; CHIP chips[] = { - { "1200", "AT90S1200", { 0x00, 0x90, 0x1E }, 0x200, 0x40 }, - { "2313", "AT90S2313", { 0x01, 0x91, 0x1E }, 0x400, 0x80 }, - { "8515", "AT90S8515", { 0x01, 0x93, 0x1E }, 0x1000, 0x200 }, - { "\0", "\0", {0, 0, 0}, 0, 0 } + { "1200", "AT90S1200", { 0x00, 0x90, 0x1E }, 0x13, 0x200, 0x40 }, + { "2313", "AT90S2313", { 0x01, 0x91, 0x1E }, 0x12, 0x400, 0x80 }, // unknown devicecode! + { "8515", "AT90S8515", { 0x01, 0x93, 0x1E }, 0x38, 0x1000, 0x200 }, + { "m103", "ATMega103", { 0x00, 0x00, 0x00 }, 0x41, 0x20000, 0x1000 }, + { "m128", "ATMega128", { 0x00, 0x00, 0x00 }, 0x00, 0x20000, 0x1000 }, // unknown devicecode! + { "\0", "\0", { 0, 0, 0 }, 0, 0, 0 } }; -void show_usage(); +#define F_FLASH 0x01 +#define F_FLASH_FILE 0x02 +#define F_EEPROM 0x04 +#define F_EEPROM_FILE 0x08 +#define F_VERIFY 0x10 +#define F_RESET 0x20 -int main(int argc, char *argv[]) -{ - char arg; +struct _cfg { + int mode; + CHIP *avr; - printf("\nISP for Atmel-AVRs:\n"); - if (argc <= 1) { - show_usage(); - exit(-1); - } + char *flash_file; + int fd_flash; - for (arg= 1; arg ", ser_device); - ser = open(ser_device, O_RDWR | O_NOCTTY ); - if (ser <0) - { - printf("ERROR: Wrong (?) RS232-device\n"); - end_prg(0); - } - printf("OK\n"); - - /* save rs232 settings */ - tcgetattr(ser,&oldtio); /* save current port settings */ - bzero(&newtio, sizeof(newtio)); - newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; - newtio.c_iflag = IGNPAR; - newtio.c_oflag = 0; - newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */ - newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ - newtio.c_cc[VMIN] = 1; /* blocking read until 5 chars received */ - tcflush(ser, TCIFLUSH); - tcsetattr(ser,TCSANOW,&newtio); - - /* detecting avr-isp adapter */ - printf(" Detecting ISP ----------> "); - write (ser,"S",1); - usleep(10000); - read (ser,inbuf,7); - inbuf[7]=0x00; - if (!strcmp(inbuf, "AVR ISP")) - printf ("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(1); - } + char *eeprom_file; + int fd_eeprom; - /* set avr-device in avr-isp adapter */ - switch (avr_device) - { - case 0: printf(" Set device AT90S1200 ---> "); - outbuf[1]=0x12; - break; - - case 1: printf(" Set device AT90S2313 ---> "); - outbuf[1]=0x12; - break; - - case 2: printf(" Set device AT90S2323 ---> "); - outbuf[1]=0x00; - break; - - case 3: printf(" Set device AT90S2343 ---> "); - outbuf[1]=0x00; - break; - - case 4: printf(" Set device AT90S4414 ---> "); - outbuf[1]=0x00; - break; - - case 5: printf(" Set device AT90S8515 ---> "); - outbuf[1]=0x38; - break; - } - outbuf[0]=0x54; - write (ser,outbuf,2); - usleep(10000); - read (ser,inbuf,1); - if (inbuf[0]==0x0D) - printf("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(1); - } - - /* switch on red LED */ - write (ser,"x",1); - usleep(10000); - read (ser,inbuf,1); + char *ser_device; + int fd_ser; + struct termios oldtio; +} cfg; - /* enter programming mode */ - printf(" Set Prg Mode -----------> "); - write (ser,"P",1); - usleep(10000); - read (ser,inbuf,1); - if (inbuf[0]==0x0D) - printf("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(1); - } - - /* check the signature */ - printf(" Checking Signature -----> "); - write (ser,"s",1); - usleep(10000); - read (ser,inbuf,3); - if (sign[avr_device][0] == inbuf[0] && sign[avr_device][1] == inbuf[1] && sign[avr_device][2] == inbuf[2]) - printf ("OK\n"); - else - { - printf("ERROR: Wrong signature: "); - printf ("%2.2X %2.2X %2.2X <-> ",inbuf[0], inbuf[1], inbuf[2]); - printf ("%2.2X %2.2X %2.2X\n",sign[avr_device][0], sign[avr_device][1], sign[avr_device][2]); - end_prg(2); - } +int debug = 0; +int isp_check(int fd) { + char buf[8]; - if (!reset) - { - /* clear the chip */ - printf(" Erase FLASH & EEPROM ---> "); - write (ser,"e",1); - usleep(10000); - read (ser,inbuf,1); - if (inbuf[0]==0x0D) - printf("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(2); - } - } - - /* reset the chip after clear */ - printf(" Reseting AVR-Device ----> "); - write (ser,"L",1); - usleep(10000); - read (ser,inbuf,1); - if (inbuf[0]!=0x0D) - { - printf("ERROR: No response\n"); - end_prg(2); - } + write(fd, "S", 1); + read_ser(fd, buf, 7); + if (debug) + printf(" (expected: 'AVR ISP', got: '%7s')\n", buf); - if (reset) - { - printf("OK\n"); - end_prg(2); - } - - /* enter programming mode */ - write (ser,"P",1); - usleep(10000); - read (ser,inbuf,1); - if (inbuf[0]==0x0D) - printf("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(2); - } - - /* writing flash */ - if (flash == 2) - { - printf(" Writing FLASH DATA -----> "); - fdat = open(flash_file, O_RDWR); - if (fdat <0) - { - printf("ERROR: <%s> not found\n", flash_file); - } - else - { - t=0; - while (read (fdat,databuf,2) == 2 && t < (mem_size[avr_device][0]/2)) - { - outbuf[0]=0x41; - outbuf[1]=(unsigned char)(t>>8) & 0xFF; - outbuf[2]=(unsigned char)t & 0xFF; - write (ser,outbuf,3); - read (ser,inbuf,1); - - outbuf[0]=0x63; //Lowbyte - outbuf[1]=databuf[0]; - write (ser,outbuf,2); - read (ser,inbuf,1); - - outbuf[0]=0x43; //Highbyte - outbuf[1]=databuf[1]; - write (ser,outbuf,2); - read (ser,inbuf,1); - t++; - } - close (fdat); - printf("%4.4Xh bytes\n",t*2); - } - } - - /* verify flash */ - if (verify == 1 && flash == 2) - { - printf(" Verify FLASH DATA ------> "); - fdat = open(flash_file, O_RDWR); - if (fdat <0) - { - printf("ERROR: <%s> not found\n", flash_file); - } - else - { - t=0; - while (read (fdat,databuf,2) == 2 && t < (mem_size[avr_device][0]/2)) - { - outbuf[0]=0x41; - outbuf[1]=(unsigned char)(t>>8) & 0xFF; - outbuf[2]=(unsigned char)t & 0xFF; - write (ser,outbuf,3); - read (ser,inbuf,1); - - write (ser,"R",1); - read (ser,inbuf,2); - if (inbuf[0]!=databuf[1] || inbuf[1]!=databuf[0]) - printf("Verify Error %4.4X: %2.2X.%2.2X - %2.2X.%2.2X\n", t, databuf[1], databuf[0], inbuf[0], inbuf[1]); - t++; - } - close (fdat); - printf("%4.4Xh bytes\n",t*2); - } - } - - /* writing eeprom */ - if (eeprom == 2) - { - printf(" Writing EEPROM DATA ----> "); - eedat = open(eeprom_file, O_RDWR); - if (eedat <0) - { - printf("ERROR: <%s> not found\n", eeprom_file); - } - else - { - t=0; - while (read (eedat,databuf,1) == 1 && t < (mem_size[avr_device][1]/2)) - { - outbuf[0]=0x41; - outbuf[1]=(unsigned char)(t>>8) & 0xFF; - outbuf[2]=(unsigned char)t & 0xFF; - write (ser,outbuf,3); - read (ser,inbuf,1); - - outbuf[0]=0x44; - outbuf[1]=databuf[0]; - write (ser,outbuf,2); - read (ser,inbuf,1); - t++; - } - close (eedat); - printf("%4.4Xh bytes\n",t); - } - } - - /* verify eeprom */ - if (verify == 1 && eeprom == 2) - { - printf(" Verify EEPROM DATA -----> "); - eedat = open(eeprom_file, O_RDWR); - if (eedat <0) - { - printf("ERROR: <%s> not found\n", eeprom_file); - } - else - { - t=0; - while (read (eedat,databuf,1) == 1 && t < (mem_size[avr_device][1]/2)) - { - outbuf[0]=0x41; - outbuf[1]=(unsigned char)(t>>8) & 0xFF; - outbuf[2]=(unsigned char)t & 0xFF; - write (ser,outbuf,3); - read (ser,inbuf,1); - - outbuf[0]=0x64; - write (ser,outbuf,1); - read (ser,inbuf,1); - if (inbuf[0]!=databuf[0]) - printf("Verify Error %4.4X: %2.2X - %2.2X\n", t, databuf[0], inbuf[0]); - t++; - } - close (eedat); - printf("%4.4Xh Bytes\n",t); - } - } - - /* release chip */ - printf(" Leave Prg Mode ---------> "); - write (ser,"L",1); - read (ser,inbuf,1); - if (inbuf[0]==0x0D) - printf("OK\n"); - else - { - printf("ERROR: No response\n"); - end_prg(2); - } - end_prg(2); + return strncmp(buf, "AVR ISP", 7); } +int isp_set_device(int fd, char device) { + char buf[2]; -void end_prg(char level) -{ - switch (level) - { - case 2: write (ser,"y",1); - read (ser,0,1); + buf[0] = 'T'; + buf[1] = device; + write(fd, buf, 2); + read_ser(fd, buf, 1); + if (debug) + printf(" (expected: '0x0D', got: '0x%X')\n", buf[0]); - case 1: tcsetattr(ser,TCSANOW,&oldtio); + return (buf[0] != 0x0D); +} - case 0: printf("\n***************************************\n\n"); - } - exit (0); +int isp_enter_progmode(int fd) { + char buf; + + write(fd, "P", 1); + read_ser(fd, &buf, 1); + if (debug) + printf(" (expected: '0x0D', got: '0x%X')\n", buf); + + return (buf != 0x0D); +} + +int isp_led(int fd, int mode) { + char buf= (mode == 0) ? 'y' : 'x'; + + write(fd, &buf, 1); + read_ser(fd, &buf, 1); + if (debug) + printf(" (expected: '0x0D', got: '0x%X')\n", buf); + + return (buf != 0x0D); +} + +void isp_led_off() { + isp_led(cfg.fd_ser, 0); +} + +int isp_check_sig(int fd, char *sig) { + char buf[3]; + + write(fd, "s", 1); + read_ser(fd, buf, 3); + if (debug) + printf(" (expected: '0x%X 0x%X 0x%X', got: '0x%X 0x%X 0x%X')\n", (*sig & 0xFF), (*(sig+1) & 0xFF), (*(sig+2) & 0xFF), (buf[0] & 0xFF), (buf[1] & 0xFF), (buf[2] & 0xFF)); + + return !((buf[0] & 0xFF) == (*sig & 0xFF) && (buf[1] & 0xFF) == (*(sig+1) & 0xFF) && (buf[2] & 0xFF) == (*(sig+2) & 0xFF)); +} + +int isp_chip_erase(int fd) { + char buf; + + write(fd, "e", 1); + read_ser(fd, &buf, 1); + if (debug) + printf(" (expected: '0x0D', got: '0x%X')\n", buf); + + return (buf != 0x0D); +} + +int isp_leave_progmode(int fd) { + char buf; + + write(fd, "L", 1); + read_ser(fd, &buf, 1); + if (debug) + printf(" (expected: '0x0D', got: '0x%X')\n", buf); + + return (buf != 0x0D); +} + +int isp_set_address(int fd, int addr) { + char buf[3]; + + buf[0] = 'A'; + buf[1] = (addr >> 8) & 0xFF; + buf[2] = addr & 0xFF; + write(fd, buf, 3); + + read_ser(fd, buf, 1); + return (buf[0] != 0x0D); +} + +int isp_prg_flash(int fd, char *buf) { + char outbuf[2]; + char ret[2]; + + outbuf[0] = 0x63; + outbuf[1] = *buf & 0xFF; + write(fd, outbuf, 2); + read_ser(fd, &ret[0], 1); + + outbuf[0] = 0x43; + outbuf[1] = *(buf +1) & 0xFF; + write(fd, outbuf, 2); + read_ser(fd, &ret[1], 1); + + return !(ret[0] == 0x0D && ret[1] == 0x0D); +} + +int isp_verify_flash(int fd, char *buf) { + char inbuf[2]; + + write(fd, "R", 1); + read_ser(fd, inbuf, 2); + + if (debug) + printf(" (expected: '0x%X 0x%X', got: '0x%X 0x%X')\n", (*buf & 0xFF), (*(buf+1) & 0xFF), (inbuf[1] & 0xFF), (inbuf[0] & 0xFF)); + + return !((inbuf[1] & 0xFF) == (*buf & 0xFF) && (inbuf[0] & 0xFF) == (*(buf+1) & 0xFF)); +} + +int isp_prg_eeprom(int fd, char val) { + char buf[2]; + + buf[0] = 'D'; + buf[1] = val & 0xFF; + write(fd, buf, 2); + + read_ser(fd, buf, 1); + return (buf[0] != 0x0D); +} + +int isp_verify_eeprom(int fd, char val) { + char buf; + + write(fd, "d", 1); + read_ser(fd, &buf, 1); + + if (debug) + printf(" (expected: '0x%X', got: '0x%X')\n", (val & 0xFF), (buf & 0xFF)); + + return (val != buf); +} + +void init_ser() { + struct termios newtio; + + /* open rs232-device */ + if ((cfg.fd_ser = open(cfg.ser_device, O_RDWR | O_NOCTTY | O_NONBLOCK)) <= 0) { + perror("init_ser(): open()"); + exit(-1); + } + + /* save old settings */ + if (tcgetattr(cfg.fd_ser, &cfg.oldtio) != 0) { + perror("init_ser(): tcgetattr()"); + exit(-1); + } + + /* alte settings on exit wiederherstellen */ + if (atexit(close_ser) != 0) { + perror("init_ser(): atexit()"); + exit(-1); + } + + /* neue settings */ + bzero(&newtio, sizeof(newtio)); + newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; + newtio.c_iflag = IGNPAR; + newtio.c_oflag = 0; + newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */ + newtio.c_cc[VTIME] = 100; /* inter-character timer unused */ + newtio.c_cc[VMIN] = 100; /* blocking read until 5 chars received */ + + /* buffer flushen */ + tcflush(cfg.fd_ser, TCIOFLUSH); + + /* neue settings schreiben */ + if (tcsetattr(cfg.fd_ser, TCSANOW, &newtio) != 0) { + perror("init_ser(): tcsetattr()"); + exit(-1); + } +} + +void close_ser() { + tcsetattr(cfg.fd_ser, TCSANOW, &cfg.oldtio); + close(cfg.fd_ser); +} + +ssize_t read_ser(int fd, void *buf, size_t count) { + int timeouts = 10; + int mytimeout = TIMEOUT; + size_t myread = 0; + ssize_t retval; + + while (count > 0 && timeouts > 0) { + usleep(mytimeout); + retval = read(fd, buf + myread, count); + if (retval > 0) { + myread+= retval; + count-= retval; + } + timeouts--; + mytimeout*= 2; + } + return myread; } void show_usage() { - printf("USAGE:\n"); - printf(" isp_down [OPTIONS] \n\n"); - printf("OPTIONS:\n"); - printf(" -avr selects AVR-device\n"); - printf(" 1200 -> AT90S1200 1kB FLASH / 64 bytes EEPROM\n"); - printf(" 2313 -> AT90S2313 2kB FLASH / 128 bytes EEPROM\n"); - printf(" 2323 -> AT90S2323 2kB FLASH / 128 bytes EEPROM\n"); - printf(" 2343 -> AT90S2343 2kB FLASH / 128 bytes EEPROM\n"); - printf(" 4414 -> AT90S4414 4kB FLASH / 256 bytes EEPROM\n"); - printf(" 8515 -> AT90S8515 8kB FLASH / 512 bytes EEPROM (default)\n\n"); - printf(" -dev selects RS232-device (default: /dev/ttyS0)\n"); - printf(" -flash Write (1st) file to FLASH\n"); - printf(" -eeprom Write (2nd) file to EEPROM\n"); - printf(" -verify Verify writing\n"); - printf(" -reset Only resets AVR\n"); + CHIP *p = chips; + + printf("USAGE:\n"); + printf(" isp_down [OPTIONS] \n\n"); + printf("OPTIONS:\n"); + printf(" -avr selects AVR-device\n"); + while (p->shortname[0] != 0) { + printf(" %s -> %s %6d byte FLASH %4d byte EEPROM\n", p->shortname, p->longname, p->flash_size, p->eeprom_size); + p++; + } + printf(" -dev selects RS232-device (default: "DEVICE")\n"); + printf(" -flash Write (1st) file to FLASH\n"); + printf(" -eeprom Write (2nd) file to EEPROM\n"); + printf(" -verify Verify writing\n"); + printf(" -reset Only resets AVR\n"); + printf(" -debug Prints debugging Information\n"); } + +int main(int argc, char *argv[]) +{ + CHIP *p; + int arg; + + /* Usage anzeigen */ + if (argc <= 1) { + show_usage(); + exit(-1); + } + + /* cfg structur loeschen */ + bzero(&cfg, sizeof(cfg)); + cfg.ser_device = DEVICE; + + for (arg = 1; arg < argc; arg++) { + if (!strcmp(argv[arg], "-avr")) { + + /* check AVR-device */ + if (++arg == argc) { + printf("ERROR: No AVR-Device\n\n"); + exit(-1); + } + + /* shortname suchen */ + p = chips; + while (p->shortname[0] != 0) { + if (!strcmp(argv[arg], p->shortname)) { + cfg.avr = p; + break; + } + p++; + } + + if (cfg.avr == NULL) { + printf(" ERROR: Unknown AVR-Device\n"); + exit(-1); + } + + } else if (!strcmp (argv[arg], "-dev")) { + /* check RS232 device */ + if (++arg == argc) { + printf(" ERROR: No RS232-device\n"); + exit(-1); + } + cfg.ser_device = argv[arg]; + + } else if (!strcmp (argv[arg], "-flash")) { + /* check flash */ + if (++arg == argc) { + printf(" ERROR: No FLASH File\n"); + exit(-1); + } + cfg.mode |= F_FLASH; + cfg.flash_file = argv[arg]; + + } else if (!strcmp (argv[arg], "-eeprom")) { + /* check eeprom */ + if (++arg == argc) { + printf(" ERROR: No EEPROM File\n"); + exit(-1); + } + cfg.mode |= F_EEPROM; + cfg.eeprom_file = argv[arg]; + + } else if (!strcmp (argv[arg], "-verify")) { + /* check verify */ + cfg.mode |= F_VERIFY; + + } else if (!strcmp (argv[arg], "-reset")) { + /* check reset */ + cfg.mode |= F_RESET; + + } else if (!strcmp (argv[arg], "-debug")) { + /* check debug */ + debug= 1; + + } else { + /* wrong parameter */ + printf(" ERROR: Unknown parameter\n"); + exit(-1); + } + } + + if (!(cfg.mode & (F_FLASH | F_EEPROM | F_RESET))) { + printf (" ERROR: Nothing to do\n"); + exit(-1); + } + + if (cfg.mode & F_FLASH) { + if ((cfg.fd_flash = open(cfg.flash_file, O_RDONLY)) <= 0) { + perror("init_files(): open(flash_file)"); + exit(-1); + } + } + + if (cfg.mode & F_EEPROM) { + if ((cfg.fd_eeprom = open(cfg.eeprom_file, O_RDONLY)) <= 0) { + perror("init_files(): open(eeprom_file)"); + exit(-1); + } + } + + init_ser(); + + /* checken ob ein adapter vorhanden ist */ + printf("checking avrisp\n"); + if (isp_check(cfg.fd_ser)) { + printf(" ERROR: avr isp adapter not found\n"); + exit(-1); + } + + /* device code setzen */ + printf("setting device code for %s\n", cfg.avr->longname); + if (isp_set_device(cfg.fd_ser, cfg.avr->devicecode)) { + printf(" ERROR: could not set device type\n"); + exit(-1); + } + + /* progammiermodus */ + printf("entering programming mode\n"); + if (isp_enter_progmode(cfg.fd_ser)) { + printf(" ERROR: could not enter programming mode\n"); + exit(-1); + } + + /* rote led an */ + isp_led(cfg.fd_ser, 1); + atexit(isp_led_off); + + /* signatur checken */ + printf("checking signature\n"); + if (isp_check_sig(cfg.fd_ser, cfg.avr->signature)) { + printf(" ERROR: wrong signature\n"); + exit(-1); + } + + /* chip loeschen */ + if (cfg.mode & (F_FLASH | F_EEPROM)) { + printf("erase flash & eeprom\n"); + if (isp_chip_erase(cfg.fd_ser)) { + printf(" ERROR: chip erase failed\n"); + exit(-1); + } + } + + /* progmode verlassen */ + if (cfg.mode & (F_FLASH | F_EEPROM | F_RESET)) { + printf("resetting device\n"); + if (isp_leave_progmode(cfg.fd_ser)) { + printf(" ERROR: device reset failed\n"); + exit(-1); + } + } + + /* -reset abgeschlossen */ + if (cfg.mode & F_RESET) { + exit(0); + } + + /* progammiermodus erneut aufrufen, da zwischenzeitlich reset */ + if (cfg.mode & (F_FLASH | F_EEPROM)) { + printf("entering programming mode\n"); + if (isp_enter_progmode(cfg.fd_ser)) { + printf(" ERROR: could not enter programming mode\n"); + exit(-1); + } + } + + if (cfg.mode & F_FLASH) { + int addr= 0; + char buf[2]; + + printf("programming flash\n"); + while ((read(cfg.fd_flash, buf, 2) > 0) && (addr < (cfg.avr->flash_size/2))) { + + if (isp_set_address(cfg.fd_ser, addr)) { + printf(" ERROR: could not set address %d\n", addr); + exit(-1); + } + + if (isp_prg_flash(cfg.fd_ser, buf)) { + printf(" ERROR: programming failed on addr %d\n", addr); + exit(-1); + } + addr++; + } + printf("programming flash successful\n"); + + if (cfg.mode & F_VERIFY) { + addr= 0; + lseek(cfg.fd_flash, 0, SEEK_SET); + + printf("verify flash\n"); + while ((read(cfg.fd_flash, buf, 2) > 0) && (addr < (cfg.avr->flash_size/2))) { + + if (isp_set_address(cfg.fd_ser, addr)) { + printf(" ERROR: could not set address %d\n", addr); + exit(-1); + } + + if (isp_verify_flash(cfg.fd_ser, buf)) { + printf(" ERROR: verify failed on addr %d\n", addr); + exit(-1); + } + + addr++; + } + printf("verify flash successful\n"); + } + } + + if (cfg.mode & F_EEPROM) { + int addr= 0; + char buf; + + printf("programming eeprom\n"); + while ((read(cfg.fd_eeprom, &buf, 1) > 0) && (addr < cfg.avr->eeprom_size)) { + + if (isp_set_address(cfg.fd_ser, addr)) { + printf(" ERROR: could not set address %d\n", addr); + exit(-1); + } + + if (isp_prg_eeprom(cfg.fd_ser, buf)) { + printf(" ERROR: programming failed on addr %d\n", addr); + exit(-1); + } + addr++; + } + printf("programming eeprom successful\n"); + + if (cfg.mode & F_EEPROM) { + addr= 0; + lseek(cfg.fd_eeprom, 0, SEEK_SET); + + printf("verify eeprom\n"); + while ((read(cfg.fd_eeprom, &buf, 1) > 0) && (addr < cfg.avr->eeprom_size)) { + + if (isp_set_address(cfg.fd_ser, addr)) { + printf(" ERROR: could not set address %d\n", addr); + exit(-1); + } + + if (isp_verify_eeprom(cfg.fd_ser, buf)) { + printf(" ERROR: verify failed on addr %d\n", addr); + exit(-1); + } + + addr++; + } + printf("verify eeprom successful\n"); + } + } + + /* progmode verlassen */ + printf("resetting device\n"); + if (isp_leave_progmode(cfg.fd_ser)) { + printf(" ERROR: device reset failed\n"); + exit(-1); + } + + exit(0); +} + +