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.

That effectively leaves the various module C files as something like
an "avrdude library", with main.c being the currently only frontend
program for that library.  In theory, it should be possible to write
different frontends using the same library backend functions though.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@722 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch 2007-01-24 22:43:46 +00:00
parent 1cae809b9b
commit 07c1079415
39 changed files with 935 additions and 634 deletions

View File

@ -1,4 +1,51 @@
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
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 <j@uriah.heep.sax.de>
Move all "extern" declarations into a centreal header file.
* Makefile.am: Add new avrdude.h.

View File

@ -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

54
avr.c
View File

@ -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. */
}

13
avr.h
View File

@ -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

View File

@ -34,8 +34,8 @@
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "pgm.h"
#include "avr910.h"
#include "serial.h"

View File

@ -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 */

View File

@ -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 <windows.h>
#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

View File

@ -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";

View File

@ -20,16 +20,14 @@
/* $Id$ */
#ifndef __avrpart_h__
#define __avrpart_h__
#ifndef avrpart_h
#define avrpart_h
#include <limits.h>
#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 */

View File

@ -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

View File

@ -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 */

View File

@ -21,11 +21,13 @@
#include "ac_cfg.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#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;
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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];

View File

@ -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

View File

@ -22,7 +22,15 @@
#ifndef jtagmkI_h
#define jtagmkI_h
#ifdef __cplusplus
extern "C" {
#endif
void jtagmkI_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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

View File

@ -35,8 +35,6 @@
#include "config_gram.h"
#include "lists.h"
void pyytext(void);
#define YY_NO_UNPUT
%}

12
lists.h
View File

@ -28,8 +28,8 @@
Author : Brian Dean
Date : 10 January, 1990
----------------------------------------------------------------------*/
#ifndef __lists_h__
#define __lists_h__
#ifndef lists_h
#define lists_h
#include <stdio.h>
@ -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

501
main.c
View File

@ -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 ? "<stdout>" : 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 ? "<stdin>" : 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) {

12
par.h
View File

@ -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

46
pgm.c
View File

@ -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;
}

35
pgm.h
View File

@ -19,8 +19,8 @@
/* $Id$ */
#ifndef __pgm_h__
#define __pgm_h__
#ifndef pgm_h
#define pgm_h
#include <limits.h>
@ -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 <windows.h>
/* 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

3
ppi.c
View File

@ -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;

12
ppi.h
View File

@ -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

View File

@ -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 */

10
serbb.h
View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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,

View File

@ -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

91
term.c
View File

@ -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;

12
term.h
View File

@ -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

373
update.c Normal file
View File

@ -0,0 +1,373 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
* 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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#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 ? "<stdout>" : 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 ? "<stdin>" : 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;
}

55
update.h Normal file
View File

@ -0,0 +1,55 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
* 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

View File

@ -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 */