diff --git a/ChangeLog b/ChangeLog index 6617d0d8..374a8afe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,51 @@ -2007-01-13 Joerg Wunsch +2007-01-24 Joerg Wunsch + + Major code cleanup. + - Make all internal functions "static". + - Make sure each module's header and implementation file match. + - Remove all library-like functionality from main.c, so only + the actual frontend remains in main.c. + - Add C++ brackets to all header files. + * avr.c: (Ditto.) + * avr.h: (Ditto.) + * avr910.c: (Ditto.) + * avr910.h: (Ditto.) + * avrdude.h: (Ditto.) + * avrpart.c: (Ditto.) + * avrpart.h: (Ditto.) + * bitbang.h: (Ditto.) + * butterfly.h: (Ditto.) + * config.c: (Ditto.) + * config.h: (Ditto.) + * confwin.h: (Ditto.) + * crc16.c: (Ditto.) + * crc16.h: (Ditto.) + * fileio.c: (Ditto.) + * fileio.h: (Ditto.) + * jtagmkI.h: (Ditto.) + * jtagmkII.h: (Ditto.) + * lexer.l: (Ditto.) + * lists.h: (Ditto.) + * main.c: (Ditto.) + * par.h: (Ditto.) + * pgm.c: (Ditto.) + * pgm.h: (Ditto.) + * ppi.c: (Ditto.) + * ppi.h: (Ditto.) + * safemode.h: (Ditto.) + * serbb.h: (Ditto.) + * serial.h: (Ditto.) + * stk500.h: (Ditto.) + * stk500v2.c: (Ditto.) + * stk500v2.h: (Ditto.) + * term.c: (Ditto.) + * term.h: (Ditto.) + * usbasp.h: (Ditto.) + * update.c: New file. + * update.h: New file. + * Makefile.am: Include update.c and update.h. + +2007-01-24 Joerg Wunsch Move all "extern" declarations into a centreal header file. * Makefile.am: Add new avrdude.h. diff --git a/Makefile.am b/Makefile.am index b2c0c4ff..0318eac1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,7 +131,9 @@ avrdude_SOURCES = \ usbasp.c \ usbasp.h \ usbdevs.h \ - usb_libusb.c + usb_libusb.c \ + update.h \ + update.c man_MANS = avrdude.1 diff --git a/avr.c b/avr.c index 108f5337..b0d24133 100644 --- a/avr.c +++ b/avr.c @@ -35,6 +35,9 @@ #include "pindefs.h" #include "ppi.h" #include "safemode.h" +#include "update.h" + +FP_UpdateProgress update_progress; #define DEBUG 0 @@ -804,3 +807,54 @@ int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p) return rc; } + +/* + * Report the progress of a read or write operation from/to the + * device. + * + * The first call of report_progress() should look like this (for a write op): + * + * report_progress (0, 1, "Writing"); + * + * Then hdr should be passed NULL on subsequent calls while the + * operation is progressing. Once the operation is complete, a final + * call should be made as such to ensure proper termination of the + * progress report: + * + * report_progress (1, 1, NULL); + * + * It would be nice if we could reduce the usage to one and only one + * call for each of start, during and end cases. As things stand now, + * that is not possible and makes maintenance a bit more work. + */ +void report_progress (int completed, int total, char *hdr) +{ + static int last = 0; + static double start_time; + int percent = (completed * 100) / total; + struct timeval tv; + double t; + + if (update_progress == NULL) + return; + + gettimeofday(&tv, NULL); + t = tv.tv_sec + ((double)tv.tv_usec)/1000000; + + if (hdr) { + last = 0; + start_time = t; + update_progress (percent, t - start_time, hdr); + } + + if (percent > 100) + percent = 100; + + if (percent > last) { + last = percent; + update_progress (percent, t - start_time, hdr); + } + + if (percent == 100) + last = 0; /* Get ready for next time. */ +} diff --git a/avr.h b/avr.h index 5928cf6f..15b979ce 100644 --- a/avr.h +++ b/avr.h @@ -27,10 +27,15 @@ #include "avrpart.h" #include "pgm.h" - +typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr); extern struct avrpart parts[]; +extern FP_UpdateProgress update_progress; + +#ifdef __cplusplus +extern "C" { +#endif int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char * value); @@ -62,6 +67,10 @@ int avr_mem_hiaddr(AVRMEM * mem); int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p); -extern void report_progress (int completed, int total, char *hdr); +void report_progress (int completed, int total, char *hdr); + +#ifdef __cplusplus +} +#endif #endif diff --git a/avr910.c b/avr910.c index b1fefe26..8a5b598d 100644 --- a/avr910.c +++ b/avr910.c @@ -34,8 +34,8 @@ #include #include "avrdude.h" - #include "avr.h" +#include "config.h" #include "pgm.h" #include "avr910.h" #include "serial.h" diff --git a/avr910.h b/avr910.h index 28d9e992..ed8b2c56 100644 --- a/avr910.h +++ b/avr910.h @@ -19,11 +19,19 @@ /* $Id$ */ -#ifndef __avr910_h__ -#define __avr910_h__ +#ifndef avr910_h +#define avr910_h #include "avrpart.h" +#ifdef __cplusplus +extern "C" { +#endif + void avr910_initpgm (PROGRAMMER * pgm); -#endif /* __avr910_h__ */ +#ifdef __cplusplus +} +#endif + +#endif /* avr910_h */ diff --git a/avrdude.h b/avrdude.h index fc00f7eb..189103fd 100644 --- a/avrdude.h +++ b/avrdude.h @@ -30,4 +30,32 @@ extern int ovsigck; /* override signature check (-F) */ extern int verbose; /* verbosity level (-v, -vv, ...) */ extern int quell_progress; /* quiteness level (-q, -qq) */ +#if defined(WIN32NATIVE) + +#include "ac_cfg.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* usleep replacements */ +/* sleep Windows in ms, Unix usleep in us + #define usleep(us) Sleep((us)<20000?20:us/1000) + #define usleep(us) Sleep(us/1000) + #define ANTIWARP 3 + #define usleep(us) Sleep(us/1000*ANTIWARP) +*/ +void usleep(unsigned long us); + +#if !defined(HAVE_GETTIMEOFDAY) +struct timezone; +int gettimeofday(struct timeval *tv, struct timezone *tz); +#ifdef __cplusplus +} +#endif +#endif /* HAVE_GETTIMEOFDAY */ + +#endif /* defined(WIN32NATIVE) */ + #endif diff --git a/avrpart.c b/avrpart.c index d737f34d..0c4eeeb5 100644 --- a/avrpart.c +++ b/avrpart.c @@ -162,7 +162,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data) } -char * avr_op_str(int op) +static char * avr_op_str(int op) { switch (op) { case AVR_OP_READ : return "READ"; break; @@ -182,7 +182,7 @@ char * avr_op_str(int op) } -char * bittype(int type) +static char * bittype(int type) { switch (type) { case AVR_CMDBIT_IGNORE : return "IGNORE"; break; @@ -449,7 +449,7 @@ void list_parts(FILE * f, char * prefix, LISTID parts) } -char * reset_disp_str(int r) +static char * reset_disp_str(int r) { switch (r) { case RESET_DEDICATED : return "dedicated"; @@ -459,7 +459,7 @@ char * reset_disp_str(int r) } -char * pin_name(int pinno) +static char * pin_name(int pinno) { switch (pinno) { case PIN_AVR_RESET : return "RESET"; diff --git a/avrpart.h b/avrpart.h index 747b3495..5b5f6714 100644 --- a/avrpart.h +++ b/avrpart.h @@ -20,16 +20,14 @@ /* $Id$ */ -#ifndef __avrpart_h__ -#define __avrpart_h__ +#ifndef avrpart_h +#define avrpart_h #include #include "lists.h" -extern LISTID part_list; - /* * AVR serial programming instructions */ @@ -182,6 +180,10 @@ typedef struct avrmem { OPCODE * op[AVR_OP_MAX]; /* opcodes */ } AVRMEM; +#ifdef __cplusplus +extern "C" { +#endif + /* Functions for OPCODE structures */ OPCODE * avr_new_opcode(void); int avr_set_bits(OPCODE * op, unsigned char * cmd); @@ -205,4 +207,8 @@ AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode); void list_parts(FILE * f, char * prefix, LISTID parts); void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose); +#ifdef __cplusplus +} #endif + +#endif /* avrpart_h */ diff --git a/bitbang.h b/bitbang.h index a0cf32e6..71aecb52 100644 --- a/bitbang.h +++ b/bitbang.h @@ -22,6 +22,10 @@ #ifndef bitbang_h #define bitbang_h +#ifdef __cplusplus +extern "C" { +#endif + int bitbang_setpin(int fd, int pin, int value); int bitbang_getpin(int fd, int pin); int bitbang_highpulsepin(int fd, int pin); @@ -43,4 +47,8 @@ int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p); void bitbang_disable (PROGRAMMER * pgm); void bitbang_enable (PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif diff --git a/butterfly.h b/butterfly.h index 5cd485e4..51abdc0a 100644 --- a/butterfly.h +++ b/butterfly.h @@ -19,9 +19,17 @@ /* $Id$ */ -#ifndef __butterfly_h__ -#define __butterfly_h__ +#ifndef butterfly_h +#define butterfly_h + +#ifdef __cplusplus +extern "C" { +#endif void butterfly_initpgm (PROGRAMMER * pgm); -#endif /* __butterfly_h__ */ +#ifdef __cplusplus +} +#endif + +#endif /* butterfly_h */ diff --git a/config.c b/config.c index 5114a5a4..e1256c90 100644 --- a/config.c +++ b/config.c @@ -21,11 +21,13 @@ #include "ac_cfg.h" +#include #include #include #include #include +#include "avrdude.h" #include "avr.h" #include "config.h" #include "config_gram.h" @@ -281,3 +283,24 @@ char * dup_string(char * str) return s; } +int read_config(char * file) +{ + FILE * f; + + f = fopen(file, "r"); + if (f == NULL) { + fprintf(stderr, "%s: can't open config file \"%s\": %s\n", + progname, file, strerror(errno)); + return -1; + } + + lineno = 1; + infile = file; + yyin = f; + + yyparse(); + + fclose(f); + + return 0; +} diff --git a/config.h b/config.h index 7bdb054f..8cff5dec 100644 --- a/config.h +++ b/config.h @@ -19,8 +19,8 @@ /* $Id$ */ -#ifndef __config_h__ -#define __config_h__ +#ifndef config_h +#define config_h #include "lists.h" #include "pindefs.h" @@ -52,6 +52,8 @@ extern int lineno; extern char * infile; extern LISTID string_list; extern LISTID number_list; +extern LISTID part_list; +extern LISTID programmers; extern char default_programmer[]; extern char default_parallel[]; extern char default_serial[]; @@ -66,6 +68,10 @@ extern YYSTYPE yylval; extern char string_buf[MAX_STR_CONST]; extern char *string_buf_ptr; +#ifdef __cplusplus +extern "C" { +#endif + int yyparse(void); @@ -89,12 +95,14 @@ TOKEN * keyword(int primary); void print_token(TOKEN * tkn); -PROGRAMMER * new_programmer(void); - -AVRPART * new_part(void); - -AVRPART * dup_part(AVRPART * d); +void pyytext(void); char * dup_string(char * str); +int read_config(char * file); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/confwin.h b/confwin.h index 9f100596..7ab33385 100644 --- a/confwin.h +++ b/confwin.h @@ -20,14 +20,19 @@ #if defined(WIN32NATIVE) -#ifndef __confwin_h__ -#define __confwin_h__ +#ifndef confwin_h +#define confwin_h +#ifdef __cplusplus +extern "C" { +#endif void win_sys_config_set(char sys_config[PATH_MAX]); void win_usr_config_set(char usr_config[PATH_MAX]); - +#ifdef __cplusplus +} +#endif #endif #endif diff --git a/crc16.c b/crc16.c index ed0e7e0f..0177c9da 100644 --- a/crc16.c +++ b/crc16.c @@ -5,7 +5,7 @@ #include "crc16.h" /* CRC16 Definitions */ -const unsigned short crc_table[256] = { +static const unsigned short crc_table[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, diff --git a/crc16.h b/crc16.h index 54647fd0..db10131d 100644 --- a/crc16.h +++ b/crc16.h @@ -1,5 +1,10 @@ #ifndef CRC16_H #define CRC16_H + +#ifdef __cplusplus +extern "C" { +#endif + /* * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel * Appnote AVR067. Converted from C++ to C. @@ -22,4 +27,8 @@ extern int crcverify(const unsigned char* message, extern void crcappend(unsigned char* message, unsigned long length); +#ifdef __cplusplus +} +#endif + #endif diff --git a/fileio.c b/fileio.c index 1b0eac58..97752418 100644 --- a/fileio.c +++ b/fileio.c @@ -47,38 +47,38 @@ struct ihexrec { }; -int b2ihex(unsigned char * inbuf, int bufsize, +static int b2ihex(unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf); -int ihex2b(char * infile, FILE * inf, +static int ihex2b(char * infile, FILE * inf, unsigned char * outbuf, int bufsize); -int b2srec(unsigned char * inbuf, int bufsize, +static int b2srec(unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf); -int srec2b(char * infile, FILE * inf, +static int srec2b(char * infile, FILE * inf, unsigned char * outbuf, int bufsize); -int ihex_readrec(struct ihexrec * ihex, char * rec); +static int ihex_readrec(struct ihexrec * ihex, char * rec); -int srec_readrec(struct ihexrec * srec, char * rec); +static int srec_readrec(struct ihexrec * srec, char * rec); -int fileio_rbin(struct fioparms * fio, +static int fileio_rbin(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size); -int fileio_ihex(struct fioparms * fio, +static int fileio_ihex(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size); -int fileio_srec(struct fioparms * fio, +static int fileio_srec(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size); -int fileio_num(struct fioparms * fio, +static int fileio_num(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size, FILEFMT fmt); -int fmt_autodetect(char * fname); +static int fmt_autodetect(char * fname); @@ -95,7 +95,7 @@ char * fmtstr(FILEFMT format) -int b2ihex(unsigned char * inbuf, int bufsize, +static int b2ihex(unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf) { @@ -173,7 +173,7 @@ int b2ihex(unsigned char * inbuf, int bufsize, } -int ihex_readrec(struct ihexrec * ihex, char * rec) +static int ihex_readrec(struct ihexrec * ihex, char * rec) { int i, j; char buf[8]; @@ -262,7 +262,7 @@ int ihex_readrec(struct ihexrec * ihex, char * rec) * * */ -int ihex2b(char * infile, FILE * inf, +static int ihex2b(char * infile, FILE * inf, unsigned char * outbuf, int bufsize) { char buffer [ MAX_LINE_LEN ]; @@ -357,7 +357,7 @@ int ihex2b(char * infile, FILE * inf, } -int b2srec(unsigned char * inbuf, int bufsize, +static int b2srec(unsigned char * inbuf, int bufsize, int recsize, int startaddr, char * outfile, FILE * outf) { @@ -463,7 +463,7 @@ int b2srec(unsigned char * inbuf, int bufsize, } -int srec_readrec(struct ihexrec * srec, char * rec) +static int srec_readrec(struct ihexrec * srec, char * rec) { int i, j; char buf[8]; @@ -539,7 +539,7 @@ int srec_readrec(struct ihexrec * srec, char * rec) } -int srec2b(char * infile, FILE * inf, +static int srec2b(char * infile, FILE * inf, unsigned char * outbuf, int bufsize) { char buffer [ MAX_LINE_LEN ]; @@ -699,7 +699,7 @@ static char *itoa_simple(int n, char *buf, int base) -int fileio_rbin(struct fioparms * fio, +static int fileio_rbin(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size) { int rc; @@ -729,7 +729,7 @@ int fileio_rbin(struct fioparms * fio, } -int fileio_imm(struct fioparms * fio, +static int fileio_imm(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size) { int rc = 0; @@ -772,7 +772,7 @@ int fileio_imm(struct fioparms * fio, } -int fileio_ihex(struct fioparms * fio, +static int fileio_ihex(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size) { int rc; @@ -802,7 +802,7 @@ int fileio_ihex(struct fioparms * fio, } -int fileio_srec(struct fioparms * fio, +static int fileio_srec(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size) { int rc; @@ -833,7 +833,7 @@ int fileio_srec(struct fioparms * fio, } -int fileio_num(struct fioparms * fio, +static int fileio_num(struct fioparms * fio, char * filename, FILE * f, unsigned char * buf, int size, FILEFMT fmt) { @@ -936,7 +936,7 @@ int fileio_setparms(int op, struct fioparms * fp) -int fmt_autodetect(char * fname) +static int fmt_autodetect(char * fname) { FILE * f; unsigned char buf[MAX_LINE_LEN]; diff --git a/fileio.h b/fileio.h index 08efc492..2fe3f209 100644 --- a/fileio.h +++ b/fileio.h @@ -19,8 +19,8 @@ /* $Id$ */ -#ifndef __fileio_h__ -#define __fileio_h__ +#ifndef fileio_h +#define fileio_h typedef enum { FMT_AUTO, @@ -47,11 +47,19 @@ enum { FIO_WRITE }; +#ifdef __cplusplus +extern "C" { +#endif + char * fmtstr(FILEFMT format); int fileio_setparms(int op, struct fioparms * fp); -int fileio(int op, char * filename, FILEFMT format, +int fileio(int op, char * filename, FILEFMT format, struct avrpart * p, char * memtype, int size); +#ifdef __cplusplus +} +#endif + #endif diff --git a/jtagmkI.h b/jtagmkI.h index 99534108..d6669b11 100644 --- a/jtagmkI.h +++ b/jtagmkI.h @@ -22,7 +22,15 @@ #ifndef jtagmkI_h #define jtagmkI_h +#ifdef __cplusplus +extern "C" { +#endif + void jtagmkI_initpgm (PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif diff --git a/jtagmkII.h b/jtagmkII.h index 87023357..9bdbae5d 100644 --- a/jtagmkII.h +++ b/jtagmkII.h @@ -22,6 +22,10 @@ #ifndef jtagmkII_h #define jtagmkII_h +#ifdef __cplusplus +extern "C" { +#endif + int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len); int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg); void jtagmkII_close(PROGRAMMER * pgm); @@ -34,5 +38,9 @@ void jtagmkII_dw_initpgm (PROGRAMMER * pgm); void jtagmkII_dragon_initpgm (PROGRAMMER * pgm); void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lexer.l b/lexer.l index 8d843063..a1b38a14 100644 --- a/lexer.l +++ b/lexer.l @@ -35,8 +35,6 @@ #include "config_gram.h" #include "lists.h" -void pyytext(void); - #define YY_NO_UNPUT %} diff --git a/lists.h b/lists.h index 6b48d0de..bae43ffd 100644 --- a/lists.h +++ b/lists.h @@ -28,8 +28,8 @@ Author : Brian Dean Date : 10 January, 1990 ----------------------------------------------------------------------*/ -#ifndef __lists_h__ -#define __lists_h__ +#ifndef lists_h +#define lists_h #include @@ -67,6 +67,10 @@ typedef void * LNODEID; #define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */ +#ifdef __cplusplus +extern "C" { +#endif + /* .................... Function Prototypes .................... */ LISTID lcreat ( void * liststruct, int poolsize ); @@ -104,4 +108,8 @@ void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2)); int lprint ( FILE * f, LISTID lid ); +#ifdef __cplusplus +} +#endif + #endif diff --git a/main.c b/main.c index e3b8a703..8c4e3d7a 100644 --- a/main.c +++ b/main.c @@ -53,22 +53,7 @@ #include "pindefs.h" #include "term.h" #include "safemode.h" - - -enum { - DEVICE_READ, - DEVICE_WRITE, - DEVICE_VERIFY -}; - - -typedef struct update_t { - char * memtype; - int op; - char * filename; - int format; -} UPDATE; - +#include "update.h" /* Get VERSION from ac_cfg.h */ @@ -79,9 +64,7 @@ char progbuf[PATH_MAX]; /* temporary buffer of spaces the same length as progname; used for lining up multiline messages */ -PROGRAMMER * pgm = NULL; - -LISTID updates; +static LISTID updates; /* * global options @@ -95,7 +78,7 @@ int ovsigck; /* 1=override sig check, 0=don't */ /* * usage message */ -void usage(void) +static void usage(void) { fprintf(stderr, "Usage: %s [options]\n" @@ -132,135 +115,6 @@ void usage(void) } -int read_config(char * file) -{ - FILE * f; - - f = fopen(file, "r"); - if (f == NULL) { - fprintf(stderr, "%s: can't open config file \"%s\": %s\n", - progname, file, strerror(errno)); - return -1; - } - - lineno = 1; - infile = file; - yyin = f; - - yyparse(); - - fclose(f); - - return 0; -} - - - - -void programmer_display(char * p) -{ - fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type); - fprintf(stderr, "%sDescription : %s\n", p, pgm->desc); - - pgm->display(pgm, p); -} - - - -PROGRAMMER * locate_programmer(LISTID programmers, char * configid) -{ - LNODEID ln1, ln2; - PROGRAMMER * p = NULL; - char * id; - int found; - - found = 0; - - for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { - p = ldata(ln1); - for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) { - id = ldata(ln2); - if (strcasecmp(configid, id) == 0) - found = 1; - } - } - - if (found) - return p; - - return NULL; -} - -void list_programmers(FILE * f, char * prefix, LISTID programmers) -{ - LNODEID ln1; - PROGRAMMER * p; - - for (ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { - p = ldata(ln1); - fprintf(f, "%s%-8s = %-30s [%s:%d]\n", - prefix, (char *)ldata(lfirst(p->id)), p->desc, - p->config_file, p->lineno); - } - - return; -} - -typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr); - -static FP_UpdateProgress update_progress; - -/* - * Report the progress of a read or write operation from/to the - * device. - * - * The first call of report_progress() should look like this (for a write op): - * - * report_progress (0, 1, "Writing"); - * - * Then hdr should be passed NULL on subsequent calls while the - * operation is progressing. Once the operation is complete, a final - * call should be made as such to ensure proper termination of the - * progress report: - * - * report_progress (1, 1, NULL); - * - * It would be nice if we could reduce the usage to one and only one - * call for each of start, during and end cases. As things stand now, - * that is not possible and makes maintenance a bit more work. - */ -void report_progress (int completed, int total, char *hdr) -{ - static int last = 0; - static double start_time; - int percent = (completed * 100) / total; - struct timeval tv; - double t; - - if (update_progress == NULL) - return; - - gettimeofday(&tv, NULL); - t = tv.tv_sec + ((double)tv.tv_usec)/1000000; - - if (hdr) { - last = 0; - start_time = t; - update_progress (percent, t - start_time, hdr); - } - - if (percent > 100) - percent = 100; - - if (percent > last) { - last = percent; - update_progress (percent, t - start_time, hdr); - } - - if (percent == 100) - last = 0; /* Get ready for next time. */ -} - static void update_progress_tty (int percent, double etime, char *hdr) { static char hashes[51]; @@ -319,351 +173,6 @@ static void update_progress_no_tty (int percent, double etime, char *hdr) last = (percent>>1)*2; /* Make last a multiple of 2. */ } - -UPDATE * parse_op(char * s) -{ - char buf[1024]; - char * p, * cp, c; - UPDATE * upd; - int i; - size_t fnlen; - - upd = (UPDATE *)malloc(sizeof(UPDATE)); - if (upd == NULL) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - - i = 0; - p = s; - while ((i < (sizeof(buf)-1) && *p && (*p != ':'))) - buf[i++] = *p++; - - if (*p != ':') { - upd->memtype = (char *)malloc(strlen("flash")+1); - if (upd->memtype == NULL) { - outofmem: - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - strcpy(upd->memtype, "flash"); - upd->op = DEVICE_WRITE; - upd->filename = (char *)malloc(strlen(buf) + 1); - if (upd->filename == NULL) - goto outofmem; - strcpy(upd->filename, buf); - upd->format = FMT_AUTO; - return upd; - } - - buf[i] = 0; - - upd->memtype = (char *)malloc(strlen(buf)+1); - if (upd->memtype == NULL) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - strcpy(upd->memtype, buf); - - p++; - if (*p == 'r') { - upd->op = DEVICE_READ; - } - else if (*p == 'w') { - upd->op = DEVICE_WRITE; - } - else if (*p == 'v') { - upd->op = DEVICE_VERIFY; - } - else { - fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n", - progname, *p); - fprintf(stderr, - " allowed values are:\n" - " r = read device\n" - " w = write device\n" - " v = verify device\n"); - free(upd->memtype); - free(upd); - return NULL; - } - - p++; - - if (*p != ':') { - fprintf(stderr, "%s: invalid update specification\n", progname); - free(upd->memtype); - free(upd); - return NULL; - } - - p++; - - /* - * Now, parse the filename component. Instead of looking for the - * leftmost possible colon delimiter, we look for the rightmost one. - * If we found one, we do have a trailing :format specifier, and - * process it. Otherwise, the remainder of the string is our file - * name component. That way, the file name itself is allowed to - * contain a colon itself (e. g. C:/some/file.hex), except the - * optional format specifier becomes mandatory then. - */ - cp = p; - p = strrchr(cp, ':'); - if (p == NULL) { - upd->format = FMT_AUTO; - fnlen = strlen(cp); - upd->filename = (char *)malloc(fnlen + 1); - } else { - fnlen = p - cp; - upd->filename = (char *)malloc(fnlen +1); - c = *++p; - if (c && p[1]) - /* More than one char - force failure below. */ - c = '?'; - switch (c) { - case 'a': upd->format = FMT_AUTO; break; - case 's': upd->format = FMT_SREC; break; - case 'i': upd->format = FMT_IHEX; break; - case 'r': upd->format = FMT_RBIN; break; - case 'm': upd->format = FMT_IMM; break; - case 'b': upd->format = FMT_BIN; break; - case 'd': upd->format = FMT_DEC; break; - case 'h': upd->format = FMT_HEX; break; - case 'o': upd->format = FMT_OCT; break; - default: - fprintf(stderr, "%s: invalid file format '%s' in update specifier\n", - progname, p); - free(upd->memtype); - free(upd); - return NULL; - } - } - - if (upd->filename == NULL) { - fprintf(stderr, "%s: out of memory\n", progname); - free(upd->memtype); - free(upd); - return NULL; - } - memcpy(upd->filename, cp, fnlen); - upd->filename[fnlen] = 0; - - return upd; -} - - -UPDATE * dup_update(UPDATE * upd) -{ - UPDATE * u; - - u = (UPDATE *)malloc(sizeof(UPDATE)); - if (u == NULL) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - - memcpy(u, upd, sizeof(UPDATE)); - - u->memtype = strdup(upd->memtype); - u->filename = strdup(upd->filename); - - return u; -} - - - -UPDATE * new_update(int op, char * memtype, int filefmt, char * filename) -{ - UPDATE * u; - - u = (UPDATE *)malloc(sizeof(UPDATE)); - if (u == NULL) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - - u->memtype = strdup(memtype); - u->filename = strdup(filename); - u->op = op; - u->format = filefmt; - - return u; -} - - - -int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite, - int verify) -{ - struct avrpart * v; - AVRMEM * mem; - int size, vsize; - int rc; - - mem = avr_locate_mem(p, upd->memtype); - if (mem == NULL) { - fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n", - upd->memtype, p->desc); - return -1; - } - - if (upd->op == DEVICE_READ) { - /* - * read out the specified device memory and write it to a file - */ - if (quell_progress < 2) { - fprintf(stderr, "%s: reading %s memory:\n", - progname, mem->desc); - } - report_progress(0,1,"Reading"); - rc = avr_read(pgm, p, upd->memtype, 0, 1); - if (rc < 0) { - fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", - progname, mem->desc, rc); - return -1; - } - report_progress(1,1,NULL); - size = rc; - - if (quell_progress < 2) { - fprintf(stderr, - "%s: writing output file \"%s\"\n", - progname, - strcmp(upd->filename, "-")==0 ? "" : upd->filename); - } - rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size); - if (rc < 0) { - fprintf(stderr, "%s: write to file '%s' failed\n", - progname, upd->filename); - return -1; - } - } - else if (upd->op == DEVICE_WRITE) { - /* - * write the selected device memory using data from a file; first - * read the data from the specified file - */ - if (quell_progress < 2) { - fprintf(stderr, - "%s: reading input file \"%s\"\n", - progname, - strcmp(upd->filename, "-")==0 ? "" : upd->filename); - } - rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1); - if (rc < 0) { - fprintf(stderr, "%s: write to file '%s' failed\n", - progname, upd->filename); - return -1; - } - size = rc; - - /* - * write the buffer contents to the selected memory type - */ - if (quell_progress < 2) { - fprintf(stderr, "%s: writing %s (%d bytes):\n", - progname, mem->desc, size); - } - - if (!nowrite) { - report_progress(0,1,"Writing"); - rc = avr_write(pgm, p, upd->memtype, size, 1); - report_progress(1,1,NULL); - } - else { - /* - * test mode, don't actually write to the chip, output the buffer - * to stdout in intel hex instead - */ - rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size); - } - - if (rc < 0) { - fprintf(stderr, "%s: failed to write %s memory, rc=%d\n", - progname, mem->desc, rc); - return -1; - } - - vsize = rc; - - if (quell_progress < 2) { - fprintf(stderr, "%s: %d bytes of %s written\n", progname, - vsize, mem->desc); - } - - } - else if (upd->op == DEVICE_VERIFY) { - /* - * verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM]) - * is the same as what is on the chip - */ - pgm->vfy_led(pgm, ON); - - v = avr_dup_part(p); - - if (quell_progress < 2) { - fprintf(stderr, "%s: verifying %s memory against %s:\n", - progname, mem->desc, upd->filename); - - fprintf(stderr, "%s: load data %s data from input file %s:\n", - progname, mem->desc, upd->filename); - } - - rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1); - if (rc < 0) { - fprintf(stderr, "%s: read from file '%s' failed\n", - progname, upd->filename); - return -1; - } - size = rc; - if (quell_progress < 2) { - fprintf(stderr, "%s: input file %s contains %d bytes\n", - progname, upd->filename, size); - fprintf(stderr, "%s: reading on-chip %s data:\n", - progname, mem->desc); - } - - report_progress (0,1,"Reading"); - rc = avr_read(pgm, v, upd->memtype, size, 1); - if (rc < 0) { - fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", - progname, mem->desc, rc); - pgm->err_led(pgm, ON); - return -1; - } - report_progress (1,1,NULL); - - - - if (quell_progress < 2) { - fprintf(stderr, "%s: verifying ...\n", progname); - } - rc = avr_verify(p, v, upd->memtype, size); - if (rc < 0) { - fprintf(stderr, "%s: verification error; content mismatch\n", - progname); - pgm->err_led(pgm, ON); - return -1; - } - - if (quell_progress < 2) { - fprintf(stderr, "%s: %d bytes of %s verified\n", - progname, rc, mem->desc); - } - - pgm->vfy_led(pgm, OFF); - } - else { - fprintf(stderr, "%s: invalid update operation (%d) requested\n", - progname, upd->op); - return -1; - } - - return 0; -} - - /* * main routine */ @@ -680,6 +189,8 @@ int main(int argc, char * argv []) struct stat sb; UPDATE * upd; LNODEID * ln; + PROGRAMMER * pgm; + /* options / operating mode variables */ int erase; /* 1=erase chip, 0=don't */ @@ -1176,7 +687,7 @@ int main(int argc, char * argv []) if (verbose) { avr_display(stderr, p, progbuf, verbose); fprintf(stderr, "\n"); - programmer_display(progbuf); + programmer_display(pgm, progbuf); } if (quell_progress < 2) { diff --git a/par.h b/par.h index 77a349d4..7d9b2416 100644 --- a/par.h +++ b/par.h @@ -19,11 +19,17 @@ /* $Id$ */ -#ifndef __par_h__ -#define __par_h__ +#ifndef par_h +#define par_h + +#ifdef __cplusplus +extern "C" { +#endif void par_initpgm (PROGRAMMER * pgm); +#ifdef __cplusplus +} #endif - +#endif diff --git a/pgm.c b/pgm.c index a26e7a48..2cd42289 100644 --- a/pgm.c +++ b/pgm.c @@ -167,3 +167,49 @@ static void pgm_default_6 (struct programmer_t * pgm, char * p) } +void programmer_display(PROGRAMMER * pgm, char * p) +{ + fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type); + fprintf(stderr, "%sDescription : %s\n", p, pgm->desc); + + pgm->display(pgm, p); +} + +PROGRAMMER * locate_programmer(LISTID programmers, char * configid) +{ + LNODEID ln1, ln2; + PROGRAMMER * p = NULL; + char * id; + int found; + + found = 0; + + for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { + p = ldata(ln1); + for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) { + id = ldata(ln2); + if (strcasecmp(configid, id) == 0) + found = 1; + } + } + + if (found) + return p; + + return NULL; +} + +void list_programmers(FILE * f, char * prefix, LISTID programmers) +{ + LNODEID ln1; + PROGRAMMER * p; + + for (ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + p = ldata(ln1); + fprintf(f, "%s%-8s = %-30s [%s:%d]\n", + prefix, (char *)ldata(lfirst(p->id)), p->desc, + p->config_file, p->lineno); + } + + return; +} diff --git a/pgm.h b/pgm.h index 78efd350..4064b597 100644 --- a/pgm.h +++ b/pgm.h @@ -19,8 +19,8 @@ /* $Id$ */ -#ifndef __pgm_h__ -#define __pgm_h__ +#ifndef pgm_h +#define pgm_h #include @@ -36,8 +36,6 @@ #define PGM_PORTLEN PATH_MAX #define PGM_TYPELEN 32 -extern LISTID programmers; - typedef enum { EXIT_VCC_UNSPEC, EXIT_VCC_ENABLED, @@ -106,29 +104,18 @@ typedef struct programmer_t { char flag; /* for private use of the programmer */ } PROGRAMMER; +#ifdef __cplusplus +extern "C" { +#endif PROGRAMMER * pgm_new(void); -#if defined(WIN32NATIVE) - -#include "ac_cfg.h" -#include - -/* usleep replacements */ -/* sleep Windows in ms, Unix usleep in us - #define usleep(us) Sleep((us)<20000?20:us/1000) - #define usleep(us) Sleep(us/1000) - #define ANTIWARP 3 - #define usleep(us) Sleep(us/1000*ANTIWARP) -*/ -void usleep(unsigned long us); - -#if !defined(HAVE_GETTIMEOFDAY) -struct timezone; -int gettimeofday(struct timeval *tv, struct timezone *tz); -#endif /* HAVE_GETTIMEOFDAY */ - -#endif /* __win32native_h */ +void programmer_display(PROGRAMMER * pgm, char * p); +PROGRAMMER * locate_programmer(LISTID programmers, char * configid); +void list_programmers(FILE * f, char * prefix, LISTID programmers); +#ifdef __cplusplus +} +#endif #endif diff --git a/ppi.c b/ppi.c index 64295981..ed50212b 100644 --- a/ppi.c +++ b/ppi.c @@ -53,7 +53,8 @@ enum { PPI_SHADOWREAD }; -int ppi_shadow_access(union filedescriptor *fdp, int reg, unsigned char *v, unsigned char action) +static int ppi_shadow_access(union filedescriptor *fdp, int reg, + unsigned char *v, unsigned char action) { static unsigned char shadow[3]; int shadow_num; diff --git a/ppi.h b/ppi.h index dd031e41..f12b839b 100644 --- a/ppi.h +++ b/ppi.h @@ -19,8 +19,8 @@ /* $Id$ */ -#ifndef __ppi_h__ -#define __ppi_h__ +#ifndef ppi_h +#define ppi_h /* * PPI registers @@ -31,7 +31,9 @@ enum { PPISTATUS }; - +#ifdef __cplusplus +extern "C" { +#endif int ppi_get (union filedescriptor *fdp, int reg, int bit); @@ -49,6 +51,10 @@ void ppi_open (char * port, union filedescriptor *fdp); void ppi_close (union filedescriptor *fdp); +#ifdef __cplusplus +} +#endif + #endif diff --git a/safemode.h b/safemode.h index 5c1792bc..4c8ba4fa 100644 --- a/safemode.h +++ b/safemode.h @@ -20,9 +20,13 @@ */ -#ifndef __safemode_h__ -#define __safemode_h__ +#ifndef safemode_h +#define safemode_h +#ifdef __cplusplus +extern "C" { +#endif + /* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries amount of times before giving up */ int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries, int verbose); @@ -36,4 +40,8 @@ pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits i if user requests fuse bits are changed, the requested value is now verified */ int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse); -#endif //__safemode_h +#ifdef __cplusplus +} +#endif + +#endif /* safemode_h */ diff --git a/serbb.h b/serbb.h index 0760f6e0..f466569c 100644 --- a/serbb.h +++ b/serbb.h @@ -22,11 +22,15 @@ #ifndef serbb_h #define serbb_h +#ifdef __cplusplus +extern "C" { +#endif + void serbb_initpgm (PROGRAMMER * pgm); -int serbb_setpin(int fd, int pin, int value); -int serbb_getpin(int fd, int pin); -int serbb_highpulsepin(int fd, int pin); +#ifdef __cplusplus +} +#endif #endif diff --git a/serial.h b/serial.h index 19ce5b4e..0b4662e6 100644 --- a/serial.h +++ b/serial.h @@ -27,8 +27,8 @@ The target file will be selected at configure time. */ -#ifndef __serial_h__ -#define __serial_h__ +#ifndef serial_h +#define serial_h extern long serial_recv_timeout; union filedescriptor @@ -65,4 +65,4 @@ extern struct serial_device avrdoper_serdev; #define serial_recv (serdev->recv) #define serial_drain (serdev->drain) -#endif /* __serial_h__ */ +#endif /* serial_h */ diff --git a/stk500.h b/stk500.h index 0950f529..f6ed3f1b 100644 --- a/stk500.h +++ b/stk500.h @@ -19,11 +19,19 @@ /* $Id$ */ -#ifndef __stk500_h__ -#define __stk500_h__ +#ifndef stk500_h +#define stk500_h + +#ifdef __cplusplus +extern "C" { +#endif void stk500_initpgm (PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif diff --git a/stk500v2.c b/stk500v2.c index 71ce5df1..cf573f8e 100644 --- a/stk500v2.c +++ b/stk500v2.c @@ -1886,7 +1886,7 @@ static int stk500v2_set_fosc(PROGRAMMER * pgm, double v) /* The list of SCK frequencies supported by the AVRISP mkII, as listed * in AVR069 */ -double avrispmkIIfreqs[] = { +static double avrispmkIIfreqs[] = { 8000000, 4000000, 2000000, 1000000, 500000, 250000, 125000, 96386, 89888, 84211, 79208, 74767, 70797, 67227, 64000, 61069, 58395, 55945, 51613, 49690, 47905, 46243, 43244, diff --git a/stk500v2.h b/stk500v2.h index c347b84a..56b64fef 100644 --- a/stk500v2.h +++ b/stk500v2.h @@ -20,8 +20,12 @@ /* $Id$ */ -#ifndef stk500v2_h__ -#define stk500v2_h__ +#ifndef stk500v2_h +#define stk500v2_h + +#ifdef __cplusplus +extern "C" { +#endif void stk500v2_initpgm (PROGRAMMER * pgm); void stk500hvsp_initpgm (PROGRAMMER * pgm); @@ -31,6 +35,10 @@ void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm); void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm); void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif diff --git a/term.c b/term.c index 00f8ff9b..d70564c1 100644 --- a/term.c +++ b/term.c @@ -49,31 +49,44 @@ struct command { }; -int cmd_dump (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_write (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_write (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_erase (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_sig (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_part (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_part (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_help (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_help (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_send (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); -int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); +static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, + int argc, char *argv[]); struct command cmd[] = { @@ -100,7 +113,7 @@ struct command cmd[] = { -int nexttok(char * buf, char ** tok, char ** next) +static int nexttok(char * buf, char ** tok, char ** next) { char * q, * n; @@ -129,7 +142,7 @@ int nexttok(char * buf, char ** tok, char ** next) } -int hexdump_line(char * buffer, unsigned char * p, int n, int pad) +static int hexdump_line(char * buffer, unsigned char * p, int n, int pad) { char * hexdata = "0123456789abcdef"; char * b; @@ -161,7 +174,7 @@ int hexdump_line(char * buffer, unsigned char * p, int n, int pad) } -int chardump_line(char * buffer, unsigned char * p, int n, int pad) +static int chardump_line(char * buffer, unsigned char * p, int n, int pad) { int i; char b [ 128 ]; @@ -184,7 +197,7 @@ int chardump_line(char * buffer, unsigned char * p, int n, int pad) } -int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len) +static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len) { int addr; int i, n; @@ -211,7 +224,8 @@ int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len) } -int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { static char prevmem[128] = {0}; char * e; @@ -310,7 +324,8 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { char * e; int len, maxsize; @@ -415,7 +430,8 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_send(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { unsigned char cmd[4], res[4]; char * e; @@ -465,7 +481,8 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { fprintf(stderr, "%s: erasing chip\n", progname); pgm->chip_erase(pgm, p); @@ -473,7 +490,8 @@ int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_part(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { fprintf(stdout, "\n"); avr_display(stdout, p, "", 0); @@ -483,7 +501,8 @@ int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int i; int rc; @@ -512,13 +531,15 @@ int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { return 1; } -int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { if (pgm->print_parms == NULL) { fprintf(stderr, @@ -533,7 +554,8 @@ int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int rc; double v; @@ -563,7 +585,8 @@ int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int rc; double v; @@ -602,7 +625,8 @@ int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int rc; double v; @@ -634,7 +658,8 @@ int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int rc; double v; @@ -664,7 +689,8 @@ int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int cmd_help(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int i; @@ -682,7 +708,7 @@ int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) } -int tokenize(char * s, char *** argv) +static int tokenize(char * s, char *** argv) { int i, n, l, nargs, offset; int len, slen; @@ -759,7 +785,8 @@ int tokenize(char * s, char *** argv) } -int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) +static int do_cmd(PROGRAMMER * pgm, struct avrpart * p, + int argc, char * argv[]) { int i; int hold; diff --git a/term.h b/term.h index e88ab0aa..42d8a7a2 100644 --- a/term.h +++ b/term.h @@ -19,13 +19,21 @@ /* $Id$ */ -#ifndef __term_h__ -#define __term_h__ +#ifndef term_h +#define term_h #include "avr.h" #include "pgm.h" +#ifdef __cplusplus +extern "C" { +#endif + int terminal_mode(PROGRAMMER * pgm, struct avrpart * p); char * terminal_get_input(const char *prompt); +#ifdef __cplusplus +} +#endif + #endif diff --git a/update.c b/update.c new file mode 100644 index 00000000..51952cdc --- /dev/null +++ b/update.c @@ -0,0 +1,373 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000-2005 Brian S. Dean + * Copyright (C) 2007 Joerg Wunsch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include + +#include "avrdude.h" +#include "avr.h" +#include "config.h" +#include "confwin.h" +#include "fileio.h" +#include "update.h" + +UPDATE * parse_op(char * s) +{ + char buf[1024]; + char * p, * cp, c; + UPDATE * upd; + int i; + size_t fnlen; + + upd = (UPDATE *)malloc(sizeof(UPDATE)); + if (upd == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + + i = 0; + p = s; + while ((i < (sizeof(buf)-1) && *p && (*p != ':'))) + buf[i++] = *p++; + + if (*p != ':') { + upd->memtype = (char *)malloc(strlen("flash")+1); + if (upd->memtype == NULL) { + outofmem: + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + strcpy(upd->memtype, "flash"); + upd->op = DEVICE_WRITE; + upd->filename = (char *)malloc(strlen(buf) + 1); + if (upd->filename == NULL) + goto outofmem; + strcpy(upd->filename, buf); + upd->format = FMT_AUTO; + return upd; + } + + buf[i] = 0; + + upd->memtype = (char *)malloc(strlen(buf)+1); + if (upd->memtype == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + strcpy(upd->memtype, buf); + + p++; + if (*p == 'r') { + upd->op = DEVICE_READ; + } + else if (*p == 'w') { + upd->op = DEVICE_WRITE; + } + else if (*p == 'v') { + upd->op = DEVICE_VERIFY; + } + else { + fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n", + progname, *p); + fprintf(stderr, + " allowed values are:\n" + " r = read device\n" + " w = write device\n" + " v = verify device\n"); + free(upd->memtype); + free(upd); + return NULL; + } + + p++; + + if (*p != ':') { + fprintf(stderr, "%s: invalid update specification\n", progname); + free(upd->memtype); + free(upd); + return NULL; + } + + p++; + + /* + * Now, parse the filename component. Instead of looking for the + * leftmost possible colon delimiter, we look for the rightmost one. + * If we found one, we do have a trailing :format specifier, and + * process it. Otherwise, the remainder of the string is our file + * name component. That way, the file name itself is allowed to + * contain a colon itself (e. g. C:/some/file.hex), except the + * optional format specifier becomes mandatory then. + */ + cp = p; + p = strrchr(cp, ':'); + if (p == NULL) { + upd->format = FMT_AUTO; + fnlen = strlen(cp); + upd->filename = (char *)malloc(fnlen + 1); + } else { + fnlen = p - cp; + upd->filename = (char *)malloc(fnlen +1); + c = *++p; + if (c && p[1]) + /* More than one char - force failure below. */ + c = '?'; + switch (c) { + case 'a': upd->format = FMT_AUTO; break; + case 's': upd->format = FMT_SREC; break; + case 'i': upd->format = FMT_IHEX; break; + case 'r': upd->format = FMT_RBIN; break; + case 'm': upd->format = FMT_IMM; break; + case 'b': upd->format = FMT_BIN; break; + case 'd': upd->format = FMT_DEC; break; + case 'h': upd->format = FMT_HEX; break; + case 'o': upd->format = FMT_OCT; break; + default: + fprintf(stderr, "%s: invalid file format '%s' in update specifier\n", + progname, p); + free(upd->memtype); + free(upd); + return NULL; + } + } + + if (upd->filename == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + free(upd->memtype); + free(upd); + return NULL; + } + memcpy(upd->filename, cp, fnlen); + upd->filename[fnlen] = 0; + + return upd; +} + +UPDATE * dup_update(UPDATE * upd) +{ + UPDATE * u; + + u = (UPDATE *)malloc(sizeof(UPDATE)); + if (u == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + + memcpy(u, upd, sizeof(UPDATE)); + + u->memtype = strdup(upd->memtype); + u->filename = strdup(upd->filename); + + return u; +} + +UPDATE * new_update(int op, char * memtype, int filefmt, char * filename) +{ + UPDATE * u; + + u = (UPDATE *)malloc(sizeof(UPDATE)); + if (u == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + + u->memtype = strdup(memtype); + u->filename = strdup(filename); + u->op = op; + u->format = filefmt; + + return u; +} + +int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite, + int verify) +{ + struct avrpart * v; + AVRMEM * mem; + int size, vsize; + int rc; + + mem = avr_locate_mem(p, upd->memtype); + if (mem == NULL) { + fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n", + upd->memtype, p->desc); + return -1; + } + + if (upd->op == DEVICE_READ) { + /* + * read out the specified device memory and write it to a file + */ + if (quell_progress < 2) { + fprintf(stderr, "%s: reading %s memory:\n", + progname, mem->desc); + } + report_progress(0,1,"Reading"); + rc = avr_read(pgm, p, upd->memtype, 0, 1); + if (rc < 0) { + fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", + progname, mem->desc, rc); + return -1; + } + report_progress(1,1,NULL); + size = rc; + + if (quell_progress < 2) { + fprintf(stderr, + "%s: writing output file \"%s\"\n", + progname, + strcmp(upd->filename, "-")==0 ? "" : upd->filename); + } + rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size); + if (rc < 0) { + fprintf(stderr, "%s: write to file '%s' failed\n", + progname, upd->filename); + return -1; + } + } + else if (upd->op == DEVICE_WRITE) { + /* + * write the selected device memory using data from a file; first + * read the data from the specified file + */ + if (quell_progress < 2) { + fprintf(stderr, + "%s: reading input file \"%s\"\n", + progname, + strcmp(upd->filename, "-")==0 ? "" : upd->filename); + } + rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1); + if (rc < 0) { + fprintf(stderr, "%s: write to file '%s' failed\n", + progname, upd->filename); + return -1; + } + size = rc; + + /* + * write the buffer contents to the selected memory type + */ + if (quell_progress < 2) { + fprintf(stderr, "%s: writing %s (%d bytes):\n", + progname, mem->desc, size); + } + + if (!nowrite) { + report_progress(0,1,"Writing"); + rc = avr_write(pgm, p, upd->memtype, size, 1); + report_progress(1,1,NULL); + } + else { + /* + * test mode, don't actually write to the chip, output the buffer + * to stdout in intel hex instead + */ + rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size); + } + + if (rc < 0) { + fprintf(stderr, "%s: failed to write %s memory, rc=%d\n", + progname, mem->desc, rc); + return -1; + } + + vsize = rc; + + if (quell_progress < 2) { + fprintf(stderr, "%s: %d bytes of %s written\n", progname, + vsize, mem->desc); + } + + } + else if (upd->op == DEVICE_VERIFY) { + /* + * verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM]) + * is the same as what is on the chip + */ + pgm->vfy_led(pgm, ON); + + v = avr_dup_part(p); + + if (quell_progress < 2) { + fprintf(stderr, "%s: verifying %s memory against %s:\n", + progname, mem->desc, upd->filename); + + fprintf(stderr, "%s: load data %s data from input file %s:\n", + progname, mem->desc, upd->filename); + } + + rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1); + if (rc < 0) { + fprintf(stderr, "%s: read from file '%s' failed\n", + progname, upd->filename); + return -1; + } + size = rc; + if (quell_progress < 2) { + fprintf(stderr, "%s: input file %s contains %d bytes\n", + progname, upd->filename, size); + fprintf(stderr, "%s: reading on-chip %s data:\n", + progname, mem->desc); + } + + report_progress (0,1,"Reading"); + rc = avr_read(pgm, v, upd->memtype, size, 1); + if (rc < 0) { + fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", + progname, mem->desc, rc); + pgm->err_led(pgm, ON); + return -1; + } + report_progress (1,1,NULL); + + + + if (quell_progress < 2) { + fprintf(stderr, "%s: verifying ...\n", progname); + } + rc = avr_verify(p, v, upd->memtype, size); + if (rc < 0) { + fprintf(stderr, "%s: verification error; content mismatch\n", + progname); + pgm->err_led(pgm, ON); + return -1; + } + + if (quell_progress < 2) { + fprintf(stderr, "%s: %d bytes of %s verified\n", + progname, rc, mem->desc); + } + + pgm->vfy_led(pgm, OFF); + } + else { + fprintf(stderr, "%s: invalid update operation (%d) requested\n", + progname, upd->op); + return -1; + } + + return 0; +} + diff --git a/update.h b/update.h new file mode 100644 index 00000000..32e445d4 --- /dev/null +++ b/update.h @@ -0,0 +1,55 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000-2005 Brian S. Dean + * Copyright (C) 2007 Joerg Wunsch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id$ */ + +#ifndef update_h +#define update_h + +enum { + DEVICE_READ, + DEVICE_WRITE, + DEVICE_VERIFY +}; + + +typedef struct update_t { + char * memtype; + int op; + char * filename; + int format; +} UPDATE; + +#ifdef __cplusplus +extern "C" { +#endif + +extern UPDATE * parse_op(char * s); +extern UPDATE * dup_update(UPDATE * upd); +extern UPDATE * new_update(int op, char * memtype, int filefmt, + char * filename); +extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, + int nowrite, int verify); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/usbasp.h b/usbasp.h index f2959628..003a6088 100644 --- a/usbasp.h +++ b/usbasp.h @@ -50,6 +50,14 @@ #define USB_ERROR_ACCESS 2 #define USB_ERROR_IO 3 +#ifdef __cplusplus +extern "C" { +#endif + void usbasp_initpgm (PROGRAMMER * pgm); +#ifdef __cplusplus +} +#endif + #endif /* usbasp_h */