/* * Copyright 2000 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 "avr.h" #include "fileio.h" extern char * progname; extern char progbuf[]; int b2ihex ( unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf ); int ihex2b ( char * infile, FILE * inf, unsigned char * outbuf, int bufsize ); int fileio_rbin ( struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size ); int fileio_ihex ( struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size ); int fileio_srec ( struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size ); int fmt_autodetect ( char * fname ); char * fmtstr ( FILEFMT format ) { switch (format) { case FMT_AUTO : return "auto-detect"; break; case FMT_SREC : return "Motorola S-Record"; break; case FMT_IHEX : return "Intel Hex"; break; case FMT_RBIN : return "raw binary"; break; default : return "invalid format"; break; }; } int b2ihex ( unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf ) { unsigned char * buf; unsigned int nextaddr; int n, nbytes; int i; unsigned char cksum; if (recsize > 255) { fprintf ( stderr, "%s: recsize=%d, must be < 256\n", progname, recsize ); return -1; } nextaddr = startaddr; buf = inbuf; nbytes = 0; while (bufsize) { n = recsize; if (n > bufsize) n = bufsize; if (n) { cksum = 0; fprintf ( outf, ":%02X%04X00", n, nextaddr ); cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff); for (i=0; i> 8) & 0x0ff) + (nextaddr & 0x0ff) + 1; cksum = -cksum; fprintf ( outf, "%02X\n", cksum ); return nbytes; } int ihex2b ( char * infile, FILE * inf, unsigned char * outbuf, int bufsize ) { unsigned char buffer [ MAX_LINE_LEN ]; unsigned char * buf; unsigned int nextaddr; unsigned int b; int n, nbytes; int i, j; unsigned int cksum, rectype; int lineno; lineno = 0; buf = outbuf; nbytes = 0; while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) { lineno++; if (buffer[0] != ':') continue; if (sscanf((char *)&buffer[1], "%02x%04x%02x", &n, &nextaddr, &rectype) != 3) { fprintf(stderr, "%s: invalid record at line %d of \"%s\"\n", progname, lineno, infile); exit(1); } if ((rectype != 0) && (rectype != 1)) { fprintf(stderr, "%s: don't know how to deal with rectype=%d " "at line %d of %s\n", progname, rectype, lineno, infile); exit(1); } if (n && ((nextaddr + n) > bufsize)) { fprintf(stderr, "%s: address 0x%04x out of range at line %d of %s\n", progname, nextaddr+n, lineno, infile); return -1; } /* start computing a checksum */ cksum = n + ((nextaddr >> 8 ) & 0x0ff) + (nextaddr & 0x0ff) + rectype; for (i=0; iop) { case FIO_READ: rc = fread(buf, 1, size, f); break; case FIO_WRITE: rc = fwrite(buf, 1, size, f); break; default: fprintf(stderr, "%s: fileio: invalid operation=%d\n", progname, fio->op); return -1; } if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) { fprintf(stderr, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n", progname, fio->iodesc, fio->dir, filename, strerror(errno), fio->rw, rc, size); return -1; } return rc; } int fileio_ihex ( struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size ) { int rc; switch (fio->op) { case FIO_WRITE: rc = b2ihex(buf, size, 32, 0, filename, f); if (rc < 0) { return -1; } break; case FIO_READ: rc = ihex2b(filename, f, buf, size); if (rc < 0) return -1; break; default: fprintf(stderr, "%s: invalid Intex Hex file I/O operation=%d\n", progname, fio->op); return -1; break; } return rc; } int fileio_srec ( struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size ) { fprintf(stderr, "%s: Motorola S-Record %s format not yet supported\n", progname, fio->iodesc); return -1; } int fileio_setparms ( int op, struct fioparms * fp ) { fp->op = op; switch (op) { case FIO_READ: fp->mode = "r"; fp->iodesc = "input"; fp->dir = "from"; fp->rw = "read"; break; case FIO_WRITE: fp->mode = "w"; fp->iodesc = "output"; fp->dir = "to"; fp->rw = "wrote"; break; default: fprintf(stderr, "%s: invalid I/O operation %d\n", progname, op); return -1; break; } return 0; } int fmt_autodetect ( char * fname ) { FILE * f; unsigned char buf[MAX_LINE_LEN]; int i; int len; int found; f = fopen(fname, "r"); if (f == NULL) { fprintf(stderr, "%s: error opening %s: %s\n", progname, fname, strerror(errno)); return -1; } while (fgets((char *)buf, MAX_LINE_LEN, f)!=NULL) { buf[MAX_LINE_LEN-1] = 0; len = strlen((char *)buf); if (buf[len-1] == '\n') buf[--len] = 0; /* check for binary data */ found = 0; for (i=0; i 127) { found = 1; break; } } if (found) return FMT_RBIN; /* check for lines that look like intel hex */ if ((buf[0] == ':') && (len >= 11)) { found = 1; for (i=1; i= 10) && isdigit(buf[1])) { found = 1; for (i=1; imem[memtype]; if (fio.op == FIO_READ) size = p->memsize[memtype]; if (fio.op == FIO_READ) { /* 0xff fill unspecified memory */ for (i=0; i