/* * Copyright 2001 Brian S. Dean * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRIAN S. DEAN BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * */ /* $Id$ */ #include #include #include #include #include #include "avr.h" #include "config.h" #include "pindefs.h" #include "ppi.h" extern char * progname; extern char progbuf[]; extern PROGRAMMER * pgm; struct command { char * name; int (*func)(int fd, struct avrpart * p, int argc, char *argv[]); char * desc; }; char * term_version = "$Id$"; int cmd_dump (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_write (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_erase (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_sig (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_cal (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_part (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_help (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_quit (int fd, struct avrpart * p, int argc, char *argv[]); int cmd_send (int fd, struct avrpart * p, int argc, char *argv[]); struct command cmd[] = { { "dump", cmd_dump, "dump memory : %s [eeprom|flash] " }, { "read", cmd_dump, "alias for dump" }, { "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" } }; #define NCMDS (sizeof(cmd)/sizeof(struct command)) int nexttok(char * buf, char ** tok, char ** next) { char * q, * n; q = buf; while (isspace(*q)) q++; /* isolate first token */ n = q+1; while (*n && !isspace(*n)) n++; if (*n) { *n = 0; n++; } /* find start of next token */ while (isspace(*n)) n++; *tok = q; *next = n; return 0; } int hexdump_line(char * buffer, unsigned char * p, int n, int pad) { char * hexdata = "0123456789abcdef"; char * b; int i, j; b = buffer; j = 0; for (i=0; i> 4]; b[j++] = hexdata[(p[i] & 0x0f)]; if (i < 15) b[j++] = ' '; } for (i=j; i len) n = len; hexdump_line(dst1, p, n, 48); chardump_line(dst2, p, n, 16); fprintf(stdout, "%04x %s |%s|\n", addr, dst1, dst2); len -= n; addr += n; p += n; } return 0; } int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[]) { char * e; int i, l; char * buf; int maxsize; static int memtype=AVR_M_FLASH; static unsigned short addr=0; static int len=64; if (argc == 1) { addr += len; } else { if (!((argc == 2) || (argc == 4))) { fprintf(stderr, "Usage: dump flash|eeprom|fuse|lock [ ]\n"); return -1; } l = strlen(argv[1]); if (strncasecmp(argv[1],"flash",l)==0) { memtype = AVR_M_FLASH; } 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]); return -1; } if (argc == 4) { addr = strtoul(argv[2], &e, 0); if (*e || (e == argv[2])) { fprintf(stderr, "%s (dump): can't parse address \"%s\"\n", progname, argv[2]); return -1; } len = strtol(argv[3], &e, 0); if (*e || (e == argv[3])) { fprintf(stderr, "%s (dump): can't parse length \"%s\"\n", progname, argv[3]); return -1; } } } 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; len = maxsize; } if (addr > maxsize) { fprintf(stderr, "%s (dump): address 0x%04x is out of range for %s memory\n", progname, addr, avr_memtstr(memtype)); return -1; } /* trim len if nessary to not read past the end of memory */ if ((addr + len) > maxsize) len = maxsize - addr; buf = malloc(len); if (buf == NULL) { fprintf(stderr, "%s (dump): out of memory\n", progname); return -1; } for (i=0; i " " ... byteN>\n"); return -1; } l = strlen(argv[1]); if (strncasecmp(argv[1],"flash",l)==0) { memtype = AVR_M_FLASH; } 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; } maxsize = 0; 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])) { fprintf(stderr, "%s (write): can't parse address \"%s\"\n", progname, argv[2]); return -1; } if (addr > maxsize) { fprintf(stderr, "%s (write): address 0x%04x is out of range for %s memory\n", progname, addr, avr_memtstr(memtype)); return -1; } /* number of bytes to write at the specified address */ len = argc - 3; if ((addr + len) > maxsize) { fprintf(stderr, "%s (write): selected address and # bytes exceed " "range for %s memory\n", progname, avr_memtstr(memtype)); return -1; } buf = malloc(len); if (buf == NULL) { fprintf(stderr, "%s (write): out of memory\n", progname); return -1; } for (i=3; ipinno[PIN_LED_ERR]); for (werror=0, i=0; ipinno[PIN_LED_ERR]); } } free(buf); fprintf(stdout, "\n"); return 0; } int cmd_send(int fd, struct avrpart * p, int argc, char * argv[]) { unsigned char cmd[4], res[4]; char * e; int i; int len; if (argc != 5) { fprintf(stderr, "Usage: send \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 ")) != NULL) { len = strlen(cmdbuf); if (len >= 1) add_history(cmdbuf); /* * find the start of the command, skipping any white space */ q = cmdbuf; while (*q && isspace(*q)) q++; /* skip blank lines and comments */ if (!*q || (*q == '#')) continue; /* tokenize command line */ argc = tokenize(q, &argv); fprintf(stdout, ">>> "); for (i=0; i 0) { rc = 0; break; } free(cmdbuf); } return rc; }