diff --git a/avr.c b/avr.c index cad0443e..40e3b1f3 100644 --- a/avr.c +++ b/avr.c @@ -49,75 +49,6 @@ extern PROGRAMMER * pgm; char * avr_version = "$Id$"; -/* Need to add information for 2323, 2343, and 4414 */ - -#if 0 -struct avrpart parts[] = { - {"AT90S1200", "1200", 20000, - {{0, 64, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ - {0, 1024, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */ - - {"AT90S2313", "2313", 20000, - {{0, 128, 0, 0, 9000, 20000, {0x80, 0x7f }, NULL}, /* eeprom */ - {0, 2048, 0, 0, 9000, 20000, {0x7f, 0 }, NULL}}}, /* flash */ - - {"AT90S2333", "2333", 20000, - {{0, 128, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ - {0, 2048, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */ - - {"AT90S4433", "4433", 20000, - {{0, 256, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ - {0, 4096, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */ - - {"AT90S4434", "4434", 20000, - {{0, 256, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ - {0, 4096, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */ - - {"AT90S8515", "8515", 20000, - {{0, 512, 0, 0, 9000, 20000, {0x80, 0x7f }, NULL}, /* eeprom */ - {0, 8192, 0, 0, 9000, 20000, {0x7f, 0x00 }, NULL}}}, /* flash */ - - {"AT90S8535", "8535", 20000, - {{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */ - {0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */ - - {"ATMEGA103", "103", 56000*2, - {{0, 4096, 0, 0, 64000, 69000, {0x80, 0x7f }, NULL}, /* eeprom */ - {1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */ - -}; - -#define N_AVRPARTS (sizeof(parts)/sizeof(struct avrpart)) - - -int avr_list_parts(FILE * f, char * prefix) -{ - int i; - - for (i=0; ipinno[PIN_LED_PGM]); + LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); + + cmd[0] = 0x38; + cmd[1] = 0x00; /* don't care */ + cmd[2] = 0x00; + cmd[3] = 0x00; /* don't care */ + + avr_cmd(fd, cmd, res); + + LED_OFF(fd, pgm->pinno[PIN_LED_PGM]); + + return res[3]; /* calibration byte */ +} + + +/* + * read a fuse byte + */ +unsigned char avr_read_fuse(int fd, AVRPART * p, int high) +{ + unsigned char cmd[4]; + unsigned char res[4]; + static unsigned char cmdbyte1[2] = { 0x50, 0x58 }; + static unsigned char cmdbyte2[2] = { 0x00, 0x08 }; + + LED_ON(fd, pgm->pinno[PIN_LED_PGM]); + LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); + + cmd[0] = cmdbyte1[high]; + cmd[1] = cmdbyte2[high]; + cmd[2] = 0; /* don't care */ + cmd[3] = 0; /* don't care */ + + avr_cmd(fd, cmd, res); + + LED_OFF(fd, pgm->pinno[PIN_LED_PGM]); + + return res[3]; /* fuse bits */ +} + + +/* + * write a fuse byte + */ +int avr_write_fuse(int fd, AVRPART * p, int high, unsigned char b) +{ + unsigned char cmd[4]; + unsigned char res[4]; + static unsigned char cmdbyte[2] = { 0xa0, 0xa8 }; + + LED_ON(fd, pgm->pinno[PIN_LED_PGM]); + LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); + + cmd[0] = 0xac; + cmd[1] = cmdbyte[high]; + cmd[2] = 0x00; /* don't care */ + cmd[3] = b; /* fuse bits */ + + avr_cmd(fd, cmd, res); + + usleep(2000); + + LED_OFF(fd, pgm->pinno[PIN_LED_PGM]); + + return 0; +} + + +/* + * read a lock byte + */ +unsigned char avr_read_lock(int fd, AVRPART * p) +{ + unsigned char cmd[4]; + unsigned char res[4]; + + LED_ON(fd, pgm->pinno[PIN_LED_PGM]); + LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); + + cmd[0] = 0x58; + cmd[1] = 0x00; + cmd[2] = 0; + cmd[3] = 0; /* don't care */ + + avr_cmd(fd, cmd, res); + + LED_OFF(fd, pgm->pinno[PIN_LED_PGM]); + + return res[3]; /* lock bits */ +} + + +/* + * write a lock byte + */ +int avr_write_lock(int fd, AVRPART * p, unsigned char b) +{ + unsigned char cmd[4]; + unsigned char res[4]; + + LED_ON(fd, pgm->pinno[PIN_LED_PGM]); + LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); + + cmd[0] = 0x5c; + cmd[1] = 0xe0; + cmd[2] = 0; /* don't care */ + cmd[3] = b; /* lock bits */ + + avr_cmd(fd, cmd, res); + + usleep(2000); + + LED_OFF(fd, pgm->pinno[PIN_LED_PGM]); + + return 0; +} + + /* * read a byte of data from the indicated memory region */ @@ -265,19 +323,20 @@ unsigned char avr_read_byte(int fd, AVRPART * p, /* * Read the entirety of the specified memory type into the - * corresponding buffer of the avrpart pointed to by 'p'. + * corresponding buffer of the avrpart pointed to by 'p'. If size = + * 0, read the entire contents, otherwize, read 'size' bytes. * - * Return the number of bytes read, or -1 if an error occurs. - */ -int avr_read(int fd, AVRPART * p, int memtype) + * Return the number of bytes read, or -1 if an error occurs. */ +int avr_read(int fd, AVRPART * p, int memtype, int size) { unsigned char rbyte; unsigned long i; unsigned char * buf; - int size; buf = p->mem[memtype].buf; - size = p->mem[memtype].size; + if (size == 0) { + size = p->mem[memtype].size; + } for (i=0; i " }, @@ -77,7 +81,9 @@ struct command cmd[] = { { "write", cmd_write, "write memory : %s [eeprom|flash] ... " }, { "erase", cmd_erase, "perform a chip erase" }, { "sig", cmd_sig, "display device signature bytes" }, + { "cal", cmd_cal, "display device calibration byte" }, { "part", cmd_part, "display the current part settings" }, + { "send", cmd_send, "send a command : %s " }, { "help", cmd_help, "help" }, { "?", cmd_help, "help" }, { "quit", cmd_quit, "quit" } @@ -215,7 +221,7 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) } else { if (!((argc == 2) || (argc == 4))) { - fprintf(stderr, "Usage: dump flash|eeprom [ ]\n"); + fprintf(stderr, "Usage: dump flash|eeprom|fuse|lock [ ]\n"); return -1; } @@ -226,6 +232,14 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) else if (strncasecmp(argv[1],"eeprom",l)==0) { memtype = AVR_M_EEPROM; } + else if ((strncasecmp(argv[1],"fuse",l)==0)|| + (strncasecmp(argv[1],"fuse-bit",l)==0)) { + memtype = AVR_M_FUSE; + } + else if ((strncasecmp(argv[1],"lock",l)==0)|| + (strncasecmp(argv[1],"lock-bit",l)==0)) { + memtype = AVR_M_LOCK; + } else { fprintf(stderr, "%s (dump): invalid memory type \"%s\"\n", progname, argv[1]); @@ -249,7 +263,20 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) } } - maxsize = p->mem[memtype].size; + maxsize = 0; + + switch (memtype) { + case AVR_M_FLASH: + case AVR_M_EEPROM: + maxsize = p->mem[memtype].size; + break; + case AVR_M_FUSE: + maxsize = 2; + break; + case AVR_M_LOCK: + maxsize = 1; + break; + } if (argc == 2) { addr = 0; @@ -273,8 +300,20 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) return -1; } - for (i=0; i ... byteN>\n"); + fprintf(stderr, "Usage: write flash|eeprom|fuse " + " ... byteN>\n"); return -1; } @@ -310,19 +349,39 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[]) else if (strncasecmp(argv[1],"eeprom",l)==0) { memtype = AVR_M_EEPROM; } + else if ((strncasecmp(argv[1],"fuse",l)==0)|| + (strncasecmp(argv[1],"fuse-bit",l)==0)) { + memtype = AVR_M_FUSE; + } + else if ((strncasecmp(argv[1],"lock",l)==0)|| + (strncasecmp(argv[1],"lock-bit",l)==0)) { + memtype = AVR_M_LOCK; + } else { fprintf(stderr, "%s (write): invalid memory type \"%s\"\n", progname, argv[1]); return -1; } - if (p->mem[memtype].paged) { - fprintf(stderr, "%s (write): sorry, interactive write of page addressed " - "memory is not supported\n", progname); - return -1; - } + maxsize = 0; - maxsize = p->mem[memtype].size; + switch (memtype) { + case AVR_M_FLASH: + case AVR_M_EEPROM: + if (p->mem[memtype].paged) { + fprintf(stderr, "%s (write): sorry, interactive write of page " + "addressed memory is not supported\n", progname); + return -1; + } + maxsize = p->mem[memtype].size; + break; + case AVR_M_FUSE: + maxsize = 2; + break; + case AVR_M_LOCK: + maxsize = 1; + break; + } addr = strtoul(argv[2], &e, 0); if (*e || (e == argv[2])) { @@ -360,13 +419,28 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[]) if (*e || (e == argv[i])) { fprintf(stderr, "%s (write): can't parse byte \"%s\"\n", progname, argv[i]); + free(buf); return -1; } } LED_OFF(fd, pgm->pinno[PIN_LED_ERR]); for (werror=0, i=0; i \n"); + return -1; + } + + /* number of bytes to write at the specified address */ + len = argc - 1; + + /* load command bytes */ + for (i=1; ipinno[PIN_LED_ERR]); + + avr_cmd(fd, cmd, res); + + /* + * display results + */ + fprintf(stderr, "results:"); + for (i=0; i