diff --git a/build.sh b/build.sh index bbb2f586..879c0a73 100755 --- a/build.sh +++ b/build.sh @@ -53,9 +53,9 @@ case "${ostype}" in # Apple M1 (may be new version of homebrew also) if [ -d /opt/homebrew ] then - build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar" + build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar -D HAVE_LIBREADLINE:FILEPATH=/opt/homebrew/lib/libreadline.dylib" else - build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar" + build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar -D HAVE_LIBREADLINE:FILEPATH=/usr/local/lib/libreadline.dylib" fi fi ;; diff --git a/src/avr.c b/src/avr.c index 553e3ec4..336780d3 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1036,13 +1036,14 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) { int rc; - report_progress (0,1,"Reading"); + if(verbose > 1) + report_progress(0, 1, "Reading"); rc = avr_read(pgm, p, "signature", 0); if (rc < LIBAVRDUDE_SUCCESS) { pmsg_error("unable to read signature data for part %s, rc=%d\n", p->desc, rc); return rc; } - report_progress (1,1,NULL); + report_progress(1, 1, NULL); return LIBAVRDUDE_SUCCESS; } diff --git a/src/avrcache.c b/src/avrcache.c index c573014b..a0fa9082 100644 --- a/src/avrcache.c +++ b/src/avrcache.c @@ -126,6 +126,9 @@ int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) { } +#define fallback_read_byte (pgm->read_byte != avr_read_byte_cached? pgm->read_byte: avr_read_byte_default) +#define fallback_write_byte (pgm->write_byte != avr_write_byte_cached? pgm->write_byte: avr_write_byte_default) + /* * Read the page containing addr from the device into buf * - Caller to ensure buf has mem->page_size bytes @@ -141,14 +144,14 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM unsigned char *pagecopy = cfg_malloc("avr_read_page_default()", pgsize); if(pgsize == 1) - return pgm->read_byte(pgm, p, mem, addr, buf); + return fallback_read_byte(pgm, p, mem, addr, buf); memcpy(pagecopy, mem->buf + base, pgsize); if((rc = pgm->paged_load(pgm, p, mem, pgsize, base, pgsize)) >= 0) memcpy(buf, mem->buf + base, pgsize); memcpy(mem->buf + base, pagecopy, pgsize); - if(rc < 0) { + if(rc < 0 && pgm->read_byte != avr_read_byte_cached) { rc = LIBAVRDUDE_SUCCESS; for(int i=0; iread_byte(pgm, p, mem, base+i, pagecopy+i) < 0) { @@ -179,7 +182,7 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM unsigned char *pagecopy = cfg_malloc("avr_write_page_default()", pgsize); if(pgsize == 1) - return pgm->write_byte(pgm, p, mem, addr, *data); + return fallback_write_byte(pgm, p, mem, addr, *data); memcpy(pagecopy, mem->buf + base, pgsize); memcpy(mem->buf + base, data, pgsize); @@ -261,18 +264,25 @@ static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int base, int nlOnErr) { // Write modified page cont to device; if unsuccessful try bytewise access if(avr_write_page_default(pgm, p, mem, base, cp->cont + base) < 0) { - for(int i=0; i < cp->page_size; i++) - if(cp->cont[base+i] != cp->copy[base+i]) - if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 || - pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) { - report_progress(1, -1, NULL); - if(nlOnErr && quell_progress) - msg_info("\n"); - pmsg_error("writeCachePage() %s access error at addr 0x%04x\n", mem->desc, base+i); - return LIBAVRDUDE_GENERAL_FAILURE; - } + if(pgm->read_byte != avr_read_byte_cached && pgm->write_byte != avr_write_byte_cached) { + for(int i=0; i < cp->page_size; i++) + if(cp->cont[base+i] != cp->copy[base+i]) + if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 || + pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) { + report_progress(1, -1, NULL); + if(nlOnErr && quell_progress) + msg_info("\n"); + pmsg_error("%s access error at addr 0x%04x\n", mem->desc, base+i); + return LIBAVRDUDE_GENERAL_FAILURE; + } - return LIBAVRDUDE_SUCCESS; // Bytewise writes & reads successful + return LIBAVRDUDE_SUCCESS; // Bytewise writes & reads successful + } + report_progress(1, -1, NULL); + if(nlOnErr && quell_progress) + msg_info("\n"); + pmsg_error("write %s page error at addr 0x%04x\n", mem->desc, base); + return LIBAVRDUDE_GENERAL_FAILURE; } // Read page back from device and update copy to what is on device if(avr_read_page_default(pgm, p, mem, base, cp->copy + base) < 0) { @@ -552,7 +562,7 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * // Use pgm->read_byte() if not EEPROM/flash or no paged access if(!avr_has_paged_access(pgm, mem)) - return pgm->read_byte(pgm, p, mem, addr, value); + return fallback_read_byte(pgm, p, mem, addr, value); // If address is out of range synchronise cache and, if successful, pretend reading a zero if(addr >= (unsigned long) mem->size) { @@ -592,9 +602,9 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data) { - // Use pgm->read_byte() if not EEPROM/flash or no paged access + // Use pgm->write_byte() if not EEPROM/flash or no paged access if(!avr_has_paged_access(pgm, mem)) - return pgm->write_byte(pgm, p, mem, addr, data); + return fallback_write_byte(pgm, p, mem, addr, data); // If address is out of range synchronise caches with device and return whether successful if(addr >= (unsigned long) mem->size) @@ -687,7 +697,7 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return LIBAVRDUDE_GENERAL_FAILURE; if(mem->page_size == 1) { - if(pgm->write_byte(pgm, p, mem, uaddr, 0xff) < 0) + if(fallback_write_byte(pgm, p, mem, uaddr, 0xff) < 0) return LIBAVRDUDE_GENERAL_FAILURE; } else { if(!pgm->page_erase || pgm->page_erase(pgm, p, mem, uaddr) < 0) diff --git a/src/avrdude.h b/src/avrdude.h index a4079974..7ee21bf6 100644 --- a/src/avrdude.h +++ b/src/avrdude.h @@ -21,6 +21,8 @@ #ifndef avrdude_h #define avrdude_h +#include + #define SYSTEM_CONF_FILE "avrdude.conf" #if defined(WIN32) #define USER_CONF_FILE "avrdude.rc" @@ -37,7 +39,7 @@ extern int verbose; // verbosity level (-v, -vv, ...) extern int quell_progress; // quell progress report -q, reduce effective verbosity level (-qq, -qqq) int avrdude_message(int msglvl, const char *format, ...); -int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *format, ...); +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...); #define MSG_EXT_ERROR (-3) // OS-type error, no -v option, can be suppressed with -qqqqq #define MSG_ERROR (-2) // Avrdude error, no -v option, can be suppressed with -qqqq @@ -50,41 +52,45 @@ int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *for #define MSG_TRACE2 5 // Displayed with -vvvvv #define MSG2_PROGNAME 1 // Start by printing progname -#define MSG2_FUNCTION 2 // Print calling function (1st arg) after progname -#define MSG2_TYPE 4 // Print message type after function or progname -#define MSG2_INDENT1 8 // Start by printing indentation of progname+1 blanks -#define MSG2_INDENT2 16 // Start by printing indentation of progname+2 blanks -#define MSG2_FLUSH 32 // Flush before and after printing +#define MSG2_FUNCTION 2 // Print calling function (1st arg) after progname if >= notice +#define MSG2_FILELINE 4 // Print source file and line number after function if >= debug +#define MSG2_TYPE 8 // Print message type after function or progname +#define MSG2_INDENT1 16 // Start by printing indentation of progname+1 blanks +#define MSG2_INDENT2 32 // Start by printing indentation of progname+2 blanks +#define MSG2_FLUSH 64 // Flush before and after printing // Shortcuts -#define msg_ext_error(...) avrdude_message2(__func__, 0, MSG_EXT_ERROR, __VA_ARGS__) -#define msg_error(...) avrdude_message2(__func__, 0, MSG_ERROR, __VA_ARGS__) -#define msg_warning(...) avrdude_message2(__func__, 0, MSG_WARNING, __VA_ARGS__) -#define msg_info(...) avrdude_message2(__func__, 0, MSG_INFO, __VA_ARGS__) -#define msg_notice(...) avrdude_message2(__func__, 0, MSG_NOTICE, __VA_ARGS__) -#define msg_notice2(...) avrdude_message2(__func__, 0, MSG_NOTICE2, __VA_ARGS__) -#define msg_debug(...) avrdude_message2(__func__, 0, MSG_DEBUG, __VA_ARGS__) -#define msg_trace(...) avrdude_message2(__func__, 0, MSG_TRACE, __VA_ARGS__) -#define msg_trace2(...) avrdude_message2(__func__, 0, MSG_TRACE2, __VA_ARGS__) +#define msg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_EXT_ERROR, __VA_ARGS__) +#define msg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_ERROR, __VA_ARGS__) +#define msg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_WARNING, __VA_ARGS__) +#define msg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_INFO, __VA_ARGS__) +#define msg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_NOTICE, __VA_ARGS__) +#define msg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_NOTICE2, __VA_ARGS__) +#define msg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_DEBUG, __VA_ARGS__) +#define msg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_TRACE, __VA_ARGS__) +#define msg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_TRACE2, __VA_ARGS__) -#define pmsg_ext_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__) -#define pmsg_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__) -#define pmsg_warning(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__) -#define pmsg_info(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_INFO, __VA_ARGS__) -#define pmsg_notice(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__) -#define pmsg_notice2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__) -#define pmsg_debug(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__) -#define pmsg_trace(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__) -#define pmsg_trace2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__) +#define pmsg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__) +#define pmsg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__) +#define pmsg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__) +#define pmsg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_INFO, __VA_ARGS__) +#define pmsg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__) +#define pmsg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__) +#define pmsg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__) +#define pmsg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__) +#define pmsg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__) -#define imsg_ext_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__) -#define imsg_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__) -#define imsg_warning(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__) -#define imsg_info(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_INFO, __VA_ARGS__) -#define imsg_notice(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__) -#define imsg_notice2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__) -#define imsg_debug(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__) -#define imsg_trace(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__) -#define imsg_trace2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__) +#define imsg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__) +#define imsg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__) +#define imsg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__) +#define imsg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_INFO, __VA_ARGS__) +#define imsg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__) +#define imsg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__) +#define imsg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__) +#define imsg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__) +#define imsg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__) + +#define term_out(...) avrdude_message2(stdout, __LINE__, __FILE__, __func__, MSG2_FLUSH, MSG_INFO, __VA_ARGS__) +#define fmsg_out(fp, ...) avrdude_message2(fp, __LINE__, __FILE__, __func__, MSG2_FLUSH, MSG_INFO, __VA_ARGS__) #endif diff --git a/src/avrpart.c b/src/avrpart.c index 49a55dba..cf4fa996 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -498,22 +498,15 @@ void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m, int i, j; char * optr; - if (m == NULL) { + if (m == NULL || verbose > 2) { fprintf(f, "%s Block Poll Page Polled\n" "%sMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n" "%s----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n", prefix, prefix, prefix); } - else { - if (verbose > 2) { - fprintf(f, - "%s Block Poll Page Polled\n" - "%sMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n" - "%s----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n", - prefix, prefix, prefix); - } + if (m != NULL) { // Only print memory section if the previous section printed isn't identical if(prev_mem_offset != m->offset || prev_mem_size != m->size || (strcmp(p->family_id, "") == 0)) { prev_mem_offset = m->offset; diff --git a/src/flip2.c b/src/flip2.c index 50275f46..84609576 100644 --- a/src/flip2.c +++ b/src/flip2.c @@ -121,6 +121,8 @@ enum flip2_mem_unit { FLIP2_MEM_UNIT_EXT_MEM_DF = 0x10 }; +#ifdef HAVE_LIBUSB + /* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */ static int flip2_open(PROGRAMMER *pgm, const char *port_spec); @@ -146,8 +148,6 @@ static void flip2_setup(PROGRAMMER * pgm); static void flip2_teardown(PROGRAMMER * pgm); /* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */ -#ifdef HAVE_LIBUSB -// The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB static void flip2_show_info(struct flip2 *flip2); diff --git a/src/jtag3.c b/src/jtag3.c index e3e39fbe..b6770b5b 100644 --- a/src/jtag3.c +++ b/src/jtag3.c @@ -103,7 +103,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v); -void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p); +void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes); @@ -1077,7 +1077,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { if (PDATA(pgm)->set_sck(pgm, parm) < 0) return -1; } - jtag3_print_parms1(pgm, progbuf); + jtag3_print_parms1(pgm, progbuf, stderr); if (conn == PARM3_CONN_JTAG) { pmsg_notice2("jtag3_initialize(): " @@ -2333,12 +2333,12 @@ static void jtag3_display(const PROGRAMMER *pgm, const char *p) { } -void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { +void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char buf[3]; if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) return; - msg_info("%sVtarget %s: %.2f V\n", p, + fmsg_out(fp, "%sVtarget %s: %.2f V\n", p, verbose? "": " ", b2_to_u16(buf)/1000.0); // Print features unique to the Power Debugger @@ -2350,7 +2350,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) return; analog_raw_data = b2_to_u16(buf); - msg_info("%sVout set %s: %.2f V\n", p, + fmsg_out(fp, "%sVout set %s: %.2f V\n", p, verbose? "": " ", analog_raw_data / 1000.0); // Read measured generator voltage value (VOUT) @@ -2362,7 +2362,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { else { if (analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - msg_info("%sVout measured %s: %.02f V\n", p, + fmsg_out(fp, "%sVout measured %s: %.02f V\n", p, verbose? "": " ", ((float) analog_raw_data / -200.0)); } @@ -2375,7 +2375,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { else { if (analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - msg_info("%sCh A voltage %s: %.03f V\n", p, + fmsg_out(fp, "%sCh A voltage %s: %.03f V\n", p, verbose? "": " ", ((float) analog_raw_data / -200.0)); } @@ -2386,7 +2386,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { if (buf[0] != 0x90) pmsg_error("invalid PARM3_ANALOG_A_CURRENT data packet format\n"); else - msg_info("%sCh A current %s: %.3f mA\n", p, + fmsg_out(fp, "%sCh A current %s: %.3f mA\n", p, verbose? "": " ", (float) analog_raw_data * 0.003472); // Read channel B voltage @@ -2398,7 +2398,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { else { if (analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - msg_info("%sCh B voltage %s: %.03f V\n", p, + fmsg_out(fp, "%sCh B voltage %s: %.03f V\n", p, verbose? "": " ", (float) analog_raw_data / -200.0); } @@ -2411,7 +2411,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { else { if (analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - msg_info("%sCh B current %s: %.3f mA\n", p, + fmsg_out(fp, "%sCh B current %s: %.3f mA\n", p, verbose? "": " ", (float) analog_raw_data * 0.555556); } break; @@ -2422,33 +2422,33 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) { return; if (b2_to_u16(buf) > 0) { - msg_info("%sJTAG clock megaAVR/program : %u kHz\n", p, b2_to_u16(buf)); + fmsg_out(fp, "%sJTAG clock megaAVR/program : %u kHz\n", p, b2_to_u16(buf)); } if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0) return; if (b2_to_u16(buf) > 0) { - msg_info("%sJTAG clock megaAVR/debug : %u kHz\n", p, b2_to_u16(buf)); + fmsg_out(fp, "%sJTAG clock megaAVR/debug : %u kHz\n", p, b2_to_u16(buf)); } if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0) return; if (b2_to_u16(buf) > 0) { - msg_info("%sJTAG clock Xmega : %u kHz\n", p, b2_to_u16(buf)); + fmsg_out(fp, "%sJTAG clock Xmega : %u kHz\n", p, b2_to_u16(buf)); } if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0) return; if (b2_to_u16(buf) > 0) { - msg_info("%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p, b2_to_u16(buf)); + fmsg_out(fp, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p, b2_to_u16(buf)); } } -static void jtag3_print_parms(const PROGRAMMER *pgm) { - jtag3_print_parms1(pgm, ""); +static void jtag3_print_parms(const PROGRAMMER *pgm, FILE *fp) { + jtag3_print_parms1(pgm, "", fp); } static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) { diff --git a/src/jtag3.h b/src/jtag3.h index 945ddcb2..7ee95b5b 100644 --- a/src/jtag3.h +++ b/src/jtag3.h @@ -38,7 +38,7 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, unsigned char *value, unsigned char length); int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen, unsigned char **resp, const char *descr); -void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p); +void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage); extern const char jtag3_desc[]; extern const char jtag3_dw_desc[]; diff --git a/src/jtagmkI.c b/src/jtagmkI.c index 796a9cb3..9c3be6dd 100644 --- a/src/jtagmkI.c +++ b/src/jtagmkI.c @@ -104,7 +104,7 @@ static int jtagmkI_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char * value); static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char value); -static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p); +static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon); @@ -1170,13 +1170,13 @@ static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) { msg_info("%sICE HW version: 0x%02x\n", p, hw); msg_info("%sICE FW version: 0x%02x\n", p, fw); - jtagmkI_print_parms1(pgm, p); + jtagmkI_print_parms1(pgm, p, stderr); return; } -static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p) { +static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char vtarget, jtag_clock; const char *clkstr; double clk; @@ -1211,15 +1211,15 @@ static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p) { clk = 1e6; } - msg_info("%sVtarget : %.1f V\n", p, 6.25 * (unsigned)vtarget / 255.0); - msg_info("%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, 6.25 * (unsigned)vtarget / 255.0); + fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk); return; } -static void jtagmkI_print_parms(const PROGRAMMER *pgm) { - jtagmkI_print_parms1(pgm, ""); +static void jtagmkI_print_parms(const PROGRAMMER *pgm, FILE *fp) { + jtagmkI_print_parms1(pgm, "", fp); } const char jtagmkI_desc[] = "Atmel JTAG ICE mkI"; diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 9e3f1bbb..2f6425cf 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -144,7 +144,7 @@ static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags); static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v); static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char * value); -static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p); +static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes); @@ -2508,13 +2508,13 @@ static void jtagmkII_display(const PROGRAMMER *pgm, const char *p) { PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]); - jtagmkII_print_parms1(pgm, p); + jtagmkII_print_parms1(pgm, p, stderr); return; } -static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) { +static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char vtarget[4], jtag_clock[4]; char clkbuf[20]; double clk; @@ -2522,7 +2522,7 @@ static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) { if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0) return; - msg_info("%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0); if ((pgm->flag & PGM_FL_IS_JTAG)) { if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0) @@ -2541,15 +2541,15 @@ static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) { sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]); clk = 5.35e6 / (double)jtag_clock[0]; - msg_info("%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk); + fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk); } } return; } -static void jtagmkII_print_parms(const PROGRAMMER *pgm) { - jtagmkII_print_parms1(pgm, ""); +static void jtagmkII_print_parms(const PROGRAMMER *pgm, FILE *fp) { + jtagmkII_print_parms1(pgm, "", fp); } static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) { diff --git a/src/libavrdude.h b/src/libavrdude.h index b63dcd27..f4f2146d 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -783,7 +783,8 @@ typedef struct programmer_t { unsigned long addr, unsigned char *value); int (*read_sig_bytes) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m); int (*read_sib) (const struct programmer_t *pgm, const AVRPART *p, char *sib); - void (*print_parms) (const struct programmer_t *pgm); + int (*term_keep_alive)(const struct programmer_t *pgm, const AVRPART *p); + void (*print_parms) (const struct programmer_t *pgm, FILE *fp); int (*set_vtarget) (const struct programmer_t *pgm, double v); int (*set_varef) (const struct programmer_t *pgm, unsigned int chan, double v); int (*set_fosc) (const struct programmer_t *pgm, double v); diff --git a/src/main.c b/src/main.c index 035a15f3..8d4409f4 100644 --- a/src/main.c +++ b/src/main.c @@ -87,36 +87,48 @@ static const char *avrdude_message_type(int msglvl) { } } -int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *format, ...) { +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) { int rc = 0; va_list ap; + if(msglvl <= MSG_ERROR) // Serious error? Freee progress bars (if any) + report_progress(1, -1, NULL); + if(msgmode & MSG2_FLUSH) { fflush(stdout); fflush(stderr); } - // Reduce effective verbosity level by number of -q above one - if ((quell_progress < 2? verbose: verbose+1-quell_progress) >= msglvl) { + // Reduce effective verbosity level by number of -q above one when printing to stderr + if ((quell_progress < 2 || fp != stderr? verbose: verbose+1-quell_progress) >= msglvl) { if(msgmode & MSG2_PROGNAME) { - fprintf(stderr, "%s", progname); + fprintf(fp, "%s", progname); if(verbose >= MSG_NOTICE && (msgmode & MSG2_FUNCTION)) - fprintf(stderr, " %s()", fname); + fprintf(fp, " %s()", func); + if(verbose >= MSG_DEBUG && (msgmode & MSG2_FILELINE)) { + const char *pr = strrchr(file, '/'); // only print basename +#if defined (WIN32) + if(!pr) + pr = strrchr(file, '\\'); +#endif + pr = pr? pr+1: file; + fprintf(fp, " [%s:%d]", pr, lno); + } if(msgmode & MSG2_TYPE) - fprintf(stderr, " %s", avrdude_message_type(msglvl)); - fprintf(stderr, ": "); + fprintf(fp, " %s", avrdude_message_type(msglvl)); + fprintf(fp, ": "); } else if(msgmode & MSG2_INDENT1) { - fprintf(stderr, "%*s", (int) strlen(progname)+1, ""); + fprintf(fp, "%*s", (int) strlen(progname)+1, ""); } else if(msgmode & MSG2_INDENT2) { - fprintf(stderr, "%*s", (int) strlen(progname)+2, ""); + fprintf(fp, "%*s", (int) strlen(progname)+2, ""); } va_start(ap, format); - rc = vfprintf(stderr, format, ap); + rc = vfprintf(fp, format, ap); va_end(ap); } if(msgmode & MSG2_FLUSH) - fflush(stderr); + fflush(fp); return rc; } diff --git a/src/pgm.c b/src/pgm.c index b1836e00..ccded0cc 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -140,6 +140,7 @@ PROGRAMMER *pgm_new(void) { pgm->write_setup = NULL; pgm->read_sig_bytes = NULL; pgm->read_sib = NULL; + pgm->term_keep_alive= NULL; pgm->print_parms = NULL; pgm->set_vtarget = NULL; pgm->set_varef = NULL; diff --git a/src/stk500.c b/src/stk500.c index fecd8525..35fff2c5 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -47,7 +47,7 @@ static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value); static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value); -static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p); +static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { @@ -1160,13 +1160,13 @@ static void stk500_display(const PROGRAMMER *pgm, const char *p) { msg_info("%sTopcard : %s\n", p, n); } if(strcmp(pgm->type, "Arduino") != 0) - stk500_print_parms1(pgm, p); + stk500_print_parms1(pgm, p, stderr); return; } -static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) { +static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration; stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget); @@ -1175,11 +1175,11 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) { stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch); stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration); - msg_info("%sVtarget : %.1f V\n", p, vtarget / 10.0); - msg_info("%sVaref : %.1f V\n", p, vadjust / 10.0); - msg_info("%sOscillator : ", p); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0); + fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0); + fmsg_out(fp, "%sOscillator : ", p); if (osc_pscale == 0) - msg_info("Off\n"); + fmsg_out(fp, "Off\n"); else { int prescale = 1; double f = STK500_XTAL / 2; @@ -1203,16 +1203,16 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) { unit = "kHz"; } else unit = "Hz"; - msg_info("%.3f %s\n", f, unit); + fmsg_out(fp, "%.3f %s\n", f, unit); } - msg_info("%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05); return; } -static void stk500_print_parms(const PROGRAMMER *pgm) { - stk500_print_parms1(pgm, ""); +static void stk500_print_parms(const PROGRAMMER *pgm, FILE *fp) { + stk500_print_parms1(pgm, "", fp); } static void stk500_setup(PROGRAMMER * pgm) diff --git a/src/stk500v2.c b/src/stk500v2.c index 042041a2..edf26cae 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -262,7 +262,7 @@ static int stk500v2_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned static int stk500v2_getparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int *value); static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int value); static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsigned char value); -static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p); +static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes); @@ -3075,7 +3075,7 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { stk500v2_getparm2(pgm, PARAM2_EC_ID_TABLE_REV, &rev); msg_info("%sEC_ID table rev : %d\n", p, rev); } - stk500v2_print_parms1(pgm, p); + stk500v2_print_parms1(pgm, p, stderr); return; } @@ -3095,7 +3095,7 @@ f_to_kHz_MHz(double f, const char **unit) return f; } -static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { +static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller unsigned int sck_stk600, clock_conf, dac, oct, varef; unsigned char vtarget_jtag[4]; @@ -3110,8 +3110,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { pgmcp->cookie = PDATA(pgm)->chained_pdata; jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag); pgm_free(pgmcp); - msg_info("%sVtarget : %.1f V\n", p, - b2_to_u16(vtarget_jtag) / 1000.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget_jtag) / 1000.0); } else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) { PROGRAMMER *pgmcp = pgm_dup(pgm); pgmcp->cookie = PDATA(pgm)->chained_pdata; @@ -3119,11 +3118,11 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { // Copy pgm->id contents over to pgmcp->id for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) ladd(pgmcp->id, cfg_strdup("stk500v2_print_parms1()", ldata(ln))); - jtag3_print_parms1(pgmcp, p); + jtag3_print_parms1(pgmcp, p, fp); pgm_free(pgmcp); } else { stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget); - msg_info("%sVtarget : %.1f V\n", p, vtarget / 10.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0); } switch (PDATA(pgm)->pgmtype) { @@ -3132,12 +3131,12 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust); stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale); stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch); - msg_info("%sSCK period : %.1f us\n", p, + fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_to_us(pgm, sck_duration)); - msg_info("%sVaref : %.1f V\n", p, vadjust / 10.0); - msg_info("%sOscillator : ", p); + fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0); + fmsg_out(fp, "%sOscillator : ", p); if (osc_pscale == 0) - msg_info("Off\n"); + fmsg_out(fp, "Off\n"); else { prescale = 1; f = STK500V2_XTAL / 2; @@ -3153,14 +3152,14 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { f /= prescale; f /= (osc_cmatch + 1); f = f_to_kHz_MHz(f, &unit); - msg_info("%.3f %s\n", f, unit); + fmsg_out(fp, "%.3f %s\n", f, unit); } break; case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); - msg_info("%sSCK period : %.2f us\n", p, + fmsg_out(fp, "%sSCK period : %.2f us\n", p, (float) 1000000 / avrispmkIIfreqs[sck_duration]); break; @@ -3172,7 +3171,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { unsigned int sck = cmd[1] | (cmd[2] << 8); - msg_info("%sSCK period : %.2f us\n", p, + fmsg_out(fp, "%sSCK period : %.2f us\n", p, (float)(1E6 / (1000.0 * sck))); } } @@ -3180,23 +3179,23 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { case PGMTYPE_STK600: stk500v2_getparm2(pgm, PARAM2_AREF0, &varef); - msg_info("%sVaref 0 : %.2f V\n", p, varef / 100.0); + fmsg_out(fp, "%sVaref 0 : %.2f V\n", p, varef / 100.0); stk500v2_getparm2(pgm, PARAM2_AREF1, &varef); - msg_info("%sVaref 1 : %.2f V\n", p, varef / 100.0); + fmsg_out(fp, "%sVaref 1 : %.2f V\n", p, varef / 100.0); stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600); - msg_info("%sSCK period : %.2f us\n", p, + fmsg_out(fp, "%sSCK period : %.2f us\n", p, (float) (sck_stk600 + 1) / 8.0); stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf); oct = (clock_conf & 0xf000) >> 12u; dac = (clock_conf & 0x0ffc) >> 2u; f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); f = f_to_kHz_MHz(f, &unit); - msg_info("%sOscillator : %.3f %s\n", + fmsg_out(fp, "%sOscillator : %.3f %s\n", p, f, unit); break; default: - msg_info("%sSCK period : %.1f us\n", p, + fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500V2_XTAL + 0.05); break; } @@ -3205,8 +3204,8 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) { } -static void stk500v2_print_parms(const PROGRAMMER *pgm) { - stk500v2_print_parms1(pgm, ""); +static void stk500v2_print_parms(const PROGRAMMER *pgm, FILE *fp) { + stk500v2_print_parms1(pgm, "", fp); } static int stk500v2_perform_osccal(const PROGRAMMER *pgm) { diff --git a/src/term.c b/src/term.c index 321722f7..cd0cdc16 100644 --- a/src/term.c +++ b/src/term.c @@ -33,10 +33,21 @@ #include #if defined(HAVE_LIBREADLINE) -# include -# include +#include +#include + +#ifdef _MSC_VER +#include "msvc/unistd.h" +#else +#include #endif +#ifdef WIN32 +#include +#endif +#endif + + #include "avrdude.h" #include "term.h" @@ -114,7 +125,7 @@ static int nexttok(char *buf, char **tok, char **next) { n = q; uint8_t quotes = 0; while (*n && (!isspace(*n) || quotes)) { - // poor man's quote and escape processing + // Poor man's quote and escape processing if (*n == '"' || *n == '\'') quotes++; else if(*n == '\\' && n[1]) @@ -173,7 +184,7 @@ static int chardump_line(char *buffer, unsigned char *p, int n, int pad) { int i; unsigned char b[128]; - // sanity check + // Sanity check n = n < 1? 1: n > sizeof b? sizeof b: n; memcpy(b, p, n); @@ -202,7 +213,7 @@ static int hexdump_buf(FILE *f, int startaddr, unsigned char *buf, int len) { n = len; hexdump_line(dst1, p, n, 48); chardump_line(dst2, p, n, 16); - fprintf(f, "%04x %s |%s|\n", addr, dst1, dst2); + term_out("%04x %s |%s|\n", addr, dst1, dst2); len -= n; addr += n; p += n; @@ -214,7 +225,7 @@ static int hexdump_buf(FILE *f, int startaddr, unsigned char *buf, int len) { static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (argc < 2 || argc > 4) { - terminal_message(MSG_INFO, + msg_error( "Usage: %s \n" " %s ...\n" " %s \n" @@ -229,8 +240,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *memtype = argv[1]; AVRMEM *mem = avr_locate_mem(p, memtype); if (mem == NULL) { - terminal_message(MSG_INFO, "%s (dump): %s memory type not defined for part %s\n", - progname, memtype, p->desc); + pmsg_error("(dump) %s memory type not defined for part %s\n", memtype, p->desc); return -1; } int maxsize = mem->size; @@ -242,12 +252,10 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (argc >= 3 && strcmp(argv[2], "...") != 0) { addr = strtoul(argv[2], &end_ptr, 0); if (*end_ptr || (end_ptr == argv[2])) { - terminal_message(MSG_INFO, "%s (dump): can't parse address %s\n", - progname, argv[2]); + pmsg_error("(dump) cannot parse address %s\n", argv[2]); return -1; } else if (addr < 0 || addr >= maxsize) { - terminal_message(MSG_INFO, "%s (dump): %s address 0x%05x is out of range [0, 0x%05x]\n", - progname, mem->desc, addr, maxsize-1); + pmsg_error("(dump) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1); return -1; } } @@ -263,8 +271,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { } else if (argc == 4) { len = strtol(argv[3], &end_ptr, 0); if (*end_ptr || (end_ptr == argv[3])) { - terminal_message(MSG_INFO, "%s (dump): can't parse length %s\n", - progname, argv[3]); + pmsg_error("(dump) cannot parse length %s\n", argv[3]); return -1; } } else { @@ -288,7 +295,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { uint8_t *buf = malloc(len); if (buf == NULL) { - terminal_message(MSG_INFO, "%s (dump): out of memory\n", progname); + pmsg_error("(dump) out of memory\n"); return -1; } @@ -297,11 +304,9 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int rc = pgm->read_byte_cached(pgm, p, mem, addr + i, &buf[i]); if (rc != 0) { report_progress(1, -1, NULL); - terminal_message(MSG_INFO, "%s (dump): error reading %s address 0x%05lx of part %s\n", - progname, mem->desc, (long) addr + i, p->desc); + pmsg_error("(dump) error reading %s address 0x%05lx of part %s\n", mem->desc, (long) addr + i, p->desc); if (rc == -1) - terminal_message(MSG_INFO, "%*sread operation not supported on memory type %s\n", - (int) strlen(progname)+9, "", mem->desc); + imsg_error("%*sread operation not supported on memory type %s\n", 7, "", mem->desc); return -1; } report_progress(i, len, NULL); @@ -309,7 +314,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { report_progress(1, 1, NULL); hexdump_buf(stdout, addr, buf, len); - fprintf(stdout, "\n"); + term_out("\n"); free(buf); @@ -365,7 +370,7 @@ static int is_mantissa_only(char *p) { static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (argc < 4) { - terminal_message(MSG_INFO, + msg_error( "Usage: write [,] {[,]}\n" " write [,] {[,]} ...\n" "\n" @@ -399,14 +404,13 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { } int i; - uint8_t write_mode; // Operation mode, "standard" or "fill" - uint8_t start_offset; // Which argc argument - int len; // Number of bytes to write to memory - char *memtype = argv[1]; // Memory name string + uint8_t write_mode; // Operation mode, "standard" or "fill" + uint8_t start_offset; // Which argc argument + int len; // Number of bytes to write to memory + char *memtype = argv[1]; // Memory name string AVRMEM *mem = avr_locate_mem(p, memtype); if (mem == NULL) { - terminal_message(MSG_INFO, "%s (write): %s memory type not defined for part %s\n", - progname, memtype, p->desc); + pmsg_error("(write) %s memory type not defined for part %s\n", memtype, p->desc); return -1; } int maxsize = mem->size; @@ -414,21 +418,19 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *end_ptr; int addr = strtoul(argv[2], &end_ptr, 0); if (*end_ptr || (end_ptr == argv[2])) { - terminal_message(MSG_INFO, "%s (write): can't parse address %s\n", - progname, argv[2]); + pmsg_error("(write) cannot parse address %s\n", argv[2]); return -1; } if (addr < 0 || addr >= maxsize) { - terminal_message(MSG_INFO, "%s (write): %s address 0x%05x is out of range [0, 0x%05x]\n", - progname, mem->desc, addr, maxsize-1); + pmsg_error("(write) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1); return -1; } // Allocate a buffer guaranteed to be large enough uint8_t *buf = calloc(mem->size + 8 + maxstrlen(argc-3, argv+3)+1, sizeof(uint8_t)); if (buf == NULL) { - terminal_message(MSG_INFO, "%s (write): out of memory\n", progname); + pmsg_error("(write) out of memory\n"); return -1; } @@ -438,8 +440,7 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { start_offset = 4; len = strtoul(argv[3], &end_ptr, 0); if (*end_ptr || (end_ptr == argv[3])) { - terminal_message(MSG_INFO, "%s (write ...): can't parse length %s\n", - progname, argv[3]); + pmsg_error("(write ...) cannot parse length %s\n", argv[3]); free(buf); return -1; } @@ -471,8 +472,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { }; if(sizeof(long long) != sizeof(int64_t) || (data.a[0]^data.a[7]) != 1) - terminal_message(MSG_INFO, "%s (write): assumption on data types not met? " - "Check source and recompile\n", progname); + pmsg_error("(write) assumption on data types not met? " + "Check source and recompile\n"); bool is_big_endian = data.a[7]; for (i = start_offset; i < len + start_offset; i++) { @@ -518,7 +519,7 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { bool is_out_of_range = 0; int nhexdigs = p-argi-2; - if(is_signed) { // Is input in range for int64_t? + if(is_signed) { // Is input in range for int64_t? errno = 0; (void) strtoll(argi, NULL, 0); is_outside_int64_t = errno == ERANGE; } @@ -566,9 +567,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { } if(is_outside_int64_t || is_out_of_range) - terminal_message(MSG_INFO, "%s (write): %s out of int%d_t range, " - "interpreted as %d-byte %lld; consider 'U' suffix\n", - progname, argi, data.size*8, data.size, data.ll); + pmsg_error("(write) %s out of int%d_t range, " + "interpreted as %d-byte %lld; consider 'U' suffix\n", argi, data.size*8, data.size, (long long int) data.ll); } } } @@ -583,8 +583,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { data.f = strtof(argi, &end_ptr); if (end_ptr != argi && toupper(*end_ptr) == 'F' && end_ptr[1] == 0) data.size = 4; - if (end_ptr != argi && *end_ptr == 0) // no suffix defaults to float but ... - // ... do not accept valid mantissa-only floats that are integer rejects (eg, 078 or ULL overflows) + if (end_ptr != argi && *end_ptr == 0) // No suffix defaults to float but ... + // ... do not accept valid mantissa-only floats that are integer rejects (eg, 078 or ULL overflows) if (!is_mantissa_only(argi)) data.size = 4; } @@ -593,29 +593,27 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if ((*argi == '\'' && argi[arglen-1] == '\'') || (*argi == '\"' && argi[arglen-1] == '\"')) { char *s = calloc(arglen-1, 1); if (s == NULL) { - terminal_message(MSG_INFO, "%s (write str): out of memory\n", progname); + pmsg_error("(write str) out of memory\n"); free(buf); return -1; } // Strip start and end quotes, and unescape C string strncpy(s, argi+1, arglen-2); cfg_unescape(s, s); - if (*argi == '\'') { // Single C-style character + if (*argi == '\'') { // Single C-style character if(*s && s[1]) - terminal_message(MSG_INFO, "%s (write): only using first character of %s\n", - progname, argi); + pmsg_error("(write) only using first character of %s\n", argi); data.ll = *s; data.size = 1; free(s); - } else { // C-style string + } else { // C-style string data.str_ptr = s; } } } if(!data.size && !data.str_ptr) { - terminal_message(MSG_INFO, "%s (write): can't parse data %s\n", - progname, argi); + pmsg_error("(write) cannot parse data %s\n", argi); free(buf); return -1; } @@ -644,8 +642,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { data.bytes_grown = 0; if ((addr + len + data.bytes_grown) > maxsize) { - terminal_message(MSG_INFO, "%s (write): selected address and # bytes exceed " - "range for %s memory\n", progname, memtype); + pmsg_error("(write) selected address and # bytes exceed " + "range for %s memory\n", memtype); free(buf); return -1; } @@ -653,11 +651,11 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if(data.str_ptr) free(data.str_ptr); - terminal_message(MSG_NOTICE, "Info: writing %d bytes starting from address 0x%02lx", + pmsg_notice2("(write) writing %d bytes starting from address 0x%02lx", len + data.bytes_grown, (long) addr); if (write_mode == WRITE_MODE_FILL) - terminal_message(MSG_NOTICE, "; remaining space filled with %s", argv[argc - 2]); - terminal_message(MSG_NOTICE, "\n"); + msg_notice2("; remaining space filled with %s", argv[argc - 2]); + msg_notice2("\n"); pgm->err_led(pgm, OFF); bool werror = false; @@ -665,19 +663,16 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { for (i = 0; i < len + data.bytes_grown; i++) { int rc = pgm->write_byte_cached(pgm, p, mem, addr+i, buf[i]); if (rc) { - terminal_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n", - progname, buf[i], (long) addr+i, (int) rc); + pmsg_error("(write) error writing 0x%02x at 0x%05lx, rc=%d\n", buf[i], (long) addr+i, (int) rc); if (rc == -1) - terminal_message(MSG_INFO, "%*swrite operation not supported on memory type %s\n", - (int) strlen(progname)+10, "", mem->desc); + imsg_error("%*swrite operation not supported on memory type %s\n", 8, "", mem->desc); werror = true; } uint8_t b; rc = pgm->read_byte_cached(pgm, p, mem, addr+i, &b); if (b != buf[i]) { - terminal_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n", - progname, buf[i], (long) addr+i, b); + pmsg_error("(write) error writing 0x%02x at 0x%05lx cell=0x%02x\n", buf[i], (long) addr+i, b); werror = true; } @@ -713,14 +708,13 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int len; if (spi_mode && (pgm->spi == NULL)) { - terminal_message(MSG_INFO, "%s (send): the %s programmer does not support direct SPI transfers\n", - progname, pgm->type); + pmsg_error("(send) the %s programmer does not support direct SPI transfers\n", pgm->type); return -1; } if ((argc > 5) || ((argc < 5) && (!spi_mode))) { - terminal_message(MSG_INFO, spi_mode? + msg_error(spi_mode? "Usage: send [ [ []]]\n": "Usage: send \n"); return -1; @@ -733,8 +727,7 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { for (i=1; ichip_erase_cached(pgm, p); @@ -771,20 +762,18 @@ static int cmd_erase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if(argc < 3) { - terminal_message(MSG_INFO, "Usage: pgerase \n"); + msg_error("Usage: pgerase \n"); return -1; } char *memtype = argv[1]; AVRMEM *mem = avr_locate_mem(p, memtype); if(!mem) { - terminal_message(MSG_INFO, "%s (pgerase): %s memory type not defined for part %s\n", - progname, memtype, p->desc); + pmsg_error("(pgerase) %s memory type not defined for part %s\n", memtype, p->desc); return -1; } if(!avr_has_paged_access(pgm, mem)) { - terminal_message(MSG_INFO, "%s (pgerase): %s memory cannot be paged addressed by %s\n", - progname, memtype, ldata(lfirst(pgm->id))); + pmsg_error("(pgerase) %s memory cannot be paged addressed by %s\n", memtype, (char *) ldata(lfirst(pgm->id))); return -1; } @@ -793,21 +782,17 @@ static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *end_ptr; int addr = strtoul(argv[2], &end_ptr, 0); if(*end_ptr || (end_ptr == argv[2])) { - terminal_message(MSG_INFO, "%s (pgerase): can't parse address %s\n", - progname, argv[2]); + pmsg_error("(pgerase) cannot parse address %s\n", argv[2]); return -1; } if (addr < 0 || addr >= maxsize) { - terminal_message(MSG_INFO, "%s (pgerase): %s address 0x%05x is out of range [0, 0x%05x]\n", - progname, mem->desc, addr, maxsize-1); + pmsg_error("(pgerase) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1); return -1; } - // terminal_message(MSG_INFO, "%s: %s page erase 0x%05x\n", progname, mem->desc, addr & ~(mem->page_size-1)); if(pgm->page_erase_cached(pgm, p, mem, (unsigned int) addr) < 0) { - terminal_message(MSG_INFO, "%s (pgerase): unable to erase %s page at 0x%05x\n", - progname, mem->desc, addr); + pmsg_error("(pgerase) unable to erase %s page at 0x%05x\n", mem->desc, addr); return -1; } @@ -816,9 +801,9 @@ static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int cmd_part(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { - fprintf(stdout, "\n"); + term_out("\n"); avr_display(stdout, p, "", 0); - fprintf(stdout, "\n"); + term_out("\n"); return 0; } @@ -831,20 +816,18 @@ static int cmd_sig(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { rc = avr_signature(pgm, p); if (rc != 0) { - terminal_message(MSG_INFO, "%s (sig): error reading signature data, rc=%d\n", - progname, rc); + pmsg_error("(sig) error reading signature data, rc=%d\n", rc); } m = avr_locate_mem(p, "signature"); if (m == NULL) { - terminal_message(MSG_INFO, "%s (sig): signature data not defined for device %s\n", - progname, p->desc); + pmsg_error("(sig) signature data not defined for device %s\n", p->desc); } else { - fprintf(stdout, "Device signature = 0x"); + term_out("Device signature = 0x"); for (i=0; isize; i++) - fprintf(stdout, "%02x", m->buf[i]); - fprintf(stdout, "\n\n"); + term_out("%02x", m->buf[i]); + term_out("\n\n"); } return 0; @@ -861,8 +844,8 @@ static int cmd_quit(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int cmd_parms(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { - pgm->print_parms(pgm); - terminal_message(MSG_INFO, "\n"); + pgm->print_parms(pgm, stdout); + term_out("\n"); return 0; } @@ -873,18 +856,16 @@ static int cmd_vtarg(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *endp; if (argc != 2) { - terminal_message(MSG_INFO, "Usage: vtarg \n"); + msg_error("Usage: vtarg \n"); return -1; } v = strtod(argv[1], &endp); if (endp == argv[1]) { - terminal_message(MSG_INFO, "%s (vtarg): can't parse voltage %s\n", - progname, argv[1]); + pmsg_error("(vtarg) cannot parse voltage %s\n", argv[1]); return -1; } if ((rc = pgm->set_vtarget(pgm, v)) != 0) { - terminal_message(MSG_INFO, "%s (vtarg): unable to set V[target] (rc = %d)\n", - progname, rc); + pmsg_error("(vtarg) unable to set V[target] (rc = %d)\n", rc); return -3; } return 0; @@ -897,7 +878,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *endp; if (argc != 2) { - terminal_message(MSG_INFO, "Usage: fosc [M|k] | off\n"); + msg_error("Usage: fosc [M|k] | off\n"); return -1; } v = strtod(argv[1], &endp); @@ -905,8 +886,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (strcmp(argv[1], "off") == 0) v = 0.0; else { - terminal_message(MSG_INFO, "%s (fosc): can't parse frequency %s\n", - progname, argv[1]); + pmsg_error("(fosc) cannot parse frequency %s\n", argv[1]); return -1; } } @@ -915,8 +895,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { else if (*endp == 'k' || *endp == 'K') v *= 1e3; if ((rc = pgm->set_fosc(pgm, v)) != 0) { - terminal_message(MSG_INFO, "%s (fosc): unable to set oscillator frequency (rc = %d)\n", - progname, rc); + pmsg_error("(fosc) unable to set oscillator frequency (rc = %d)\n", rc); return -3; } return 0; @@ -929,19 +908,17 @@ static int cmd_sck(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *endp; if (argc != 2) { - terminal_message(MSG_INFO, "Usage: sck \n"); + msg_error("Usage: sck \n"); return -1; } v = strtod(argv[1], &endp); if (endp == argv[1]) { - terminal_message(MSG_INFO, "%s (sck): can't parse period %s\n", - progname, argv[1]); + pmsg_error("(sck) cannot parse period %s\n", argv[1]); return -1; } - v *= 1e-6; /* Convert from microseconds to seconds. */ + v *= 1e-6; // Convert from microseconds to seconds if ((rc = pgm->set_sck_period(pgm, v)) != 0) { - terminal_message(MSG_INFO, "%s (sck): unable to set SCK period (rc = %d)\n", - progname, rc); + pmsg_error("(sck) unable to set SCK period (rc = %d)\n", rc); return -3; } return 0; @@ -955,34 +932,30 @@ static int cmd_varef(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *endp; if (argc != 2 && argc != 3) { - terminal_message(MSG_INFO, "Usage: varef [channel] \n"); + msg_error("Usage: varef [channel] \n"); return -1; } if (argc == 2) { chan = 0; v = strtod(argv[1], &endp); if (endp == argv[1]) { - terminal_message(MSG_INFO, "%s (varef): can't parse voltage %s\n", - progname, argv[1]); + pmsg_error("(varef) cannot parse voltage %s\n", argv[1]); return -1; } } else { chan = strtoul(argv[1], &endp, 10); if (endp == argv[1]) { - terminal_message(MSG_INFO, "%s (varef): can't parse channel %s\n", - progname, argv[1]); + pmsg_error("(varef) cannot parse channel %s\n", argv[1]); return -1; } v = strtod(argv[2], &endp); if (endp == argv[2]) { - terminal_message(MSG_INFO, "%s (varef): can't parse voltage %s\n", - progname, argv[2]); + pmsg_error("(varef) cannot parse voltage %s\n", argv[2]); return -1; } } if ((rc = pgm->set_varef(pgm, chan, v)) != 0) { - terminal_message(MSG_INFO, "%s (varef): unable to set V[aref] (rc = %d)\n", - progname, rc); + pmsg_error("(varef) unable to set V[aref] (rc = %d)\n", rc); return -3; } return 0; @@ -992,19 +965,19 @@ static int cmd_varef(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int cmd_help(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int i; - fprintf(stdout, "Valid commands:\n"); + term_out("Valid commands:\n"); for (i=0; i]\n"); + msg_error("Usage: verbose []\n"); return -1; } if (argc == 1) { - terminal_message(MSG_INFO, "Verbosity level: %d\n", verbose); + msg_error("Verbosity level: %d\n", verbose); return 0; } nverb = strtol(argv[1], &endp, 0); if (endp == argv[1] || *endp) { - terminal_message(MSG_INFO, "%s (verbose): can't parse verbosity level %s\n", - progname, argv[1]); + pmsg_error("(verbose) cannot parse verbosity level %s\n", argv[1]); return -1; } if (nverb < 0) { - terminal_message(MSG_INFO, "%s: verbosity level must not be negative: %d\n", - progname, nverb); + pmsg_error("(verbose) level must not be negative: %d\n", nverb); return -1; } verbose = nverb; - terminal_message(MSG_INFO, "New verbosity level: %d\n", verbose); + term_out("New verbosity level: %d\n", verbose); return 0; } @@ -1055,26 +1026,24 @@ static int cmd_quell(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { char *endp; if (argc != 1 && argc != 2) { - terminal_message(MSG_INFO, "Usage: quell []\n"); + msg_error("Usage: quell []\n"); return -1; } if (argc == 1) { - terminal_message(MSG_INFO, "Quell level: %d\n", quell_progress); + msg_error("Quell level: %d\n", quell_progress); return 0; } nquell = strtol(argv[1], &endp, 0); if (endp == argv[1] || *endp) { - terminal_message(MSG_INFO, "%s (quell): can't parse quell level %s\n", - progname, argv[1]); + pmsg_error("(quell) cannot parse quell level %s\n", argv[1]); return -1; } if (nquell < 0) { - terminal_message(MSG_INFO, "%s: quell level must not be negative: %d\n", - progname, nquell); + pmsg_error("(quell) level must not be negative: %d\n", nquell); return -1; } quell_progress = nquell; - terminal_message(MSG_INFO, "New quell level: %d\n", quell_progress); + term_out("New quell level: %d\n", quell_progress); if(quell_progress > 0) update_progress = NULL; @@ -1195,8 +1164,7 @@ static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { return cmd[i].func(pgm, p, argc, argv); if (len && strncasecmp(argv[0], cmd[i].name, len)==0) { if (hold != -1) { - terminal_message(MSG_INFO, "%s (cmd): command %s is ambiguous\n", - progname, argv[0]); + pmsg_error("(cmd) command %s is ambiguous\n", argv[0]); return -1; } hold = i; @@ -1206,104 +1174,177 @@ static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (hold != -1) return cmd[hold].func(pgm, p, argc, argv); - terminal_message(MSG_INFO, "%s (cmd): invalid command %s\n", - progname, argv[0]); + pmsg_error("(cmd) invalid command %s\n", argv[0]); return -1; } char *terminal_get_input(const char *prompt) { -#if defined(HAVE_LIBREADLINE) && !defined(WIN32) - char *input; - input = readline(prompt); - if ((input != NULL) && (strlen(input) >= 1)) - add_history(input); - - return input; -#else char input[256]; - fprintf(stdout, "%s", prompt); - if (fgets(input, sizeof(input), stdin)) - { - /* FIXME: readline strips the '\n', should this too? */ - return strdup(input); + + term_out("%s", prompt); + if(fgets(input, sizeof(input), stdin)) { + int len = strlen(input); + if(len > 0 && input[len-1] == '\n') + input[len-1] = 0; + return cfg_strdup(__func__, input); } - else - return NULL; -#endif + + return NULL; } -int terminal_mode(PROGRAMMER *pgm, AVRPART *p) { - char *cmdbuf; - char *q; - int rc; - int argc; - char **argv; +static int process_line(char *cmdbuf, PROGRAMMER *pgm, struct avrpart *p) { + int argc, rc; + char **argv = NULL, *q; - rc = 0; - while ((cmdbuf = terminal_get_input("avrdude> ")) != NULL) { - /* - * find the start of the command, skipping any white space - */ - q = cmdbuf; - while (*q && isspace((unsigned char) *q)) - q++; + // Find the start of the command, skipping any white space + q = cmdbuf; + while(*q && isspace((unsigned char) *q)) + q++; - /* skip blank lines and comments */ - if (!*q || (*q == '#')) - continue; + // Skip blank lines and comments + if (!*q || (*q == '#')) + return 0; - /* tokenize command line */ - argc = tokenize(q, &argv); - if (argc < 0) { - free(cmdbuf); - return argc; - } + // Tokenize command line + argc = tokenize(q, &argv); + + if(!argv) + return -1; #if !defined(HAVE_LIBREADLINE) || defined(WIN32) || defined(__APPLE__) - fprintf(stdout, ">>> "); + term_out(">>> "); for (int i=0; i 0) { - rc = 0; - break; + // Run the command + rc = do_cmd(pgm, p, argc, argv); + free(argv); + + return rc; +} + + + +#if defined(HAVE_LIBREADLINE) + +static PROGRAMMER *term_pgm; +static struct avrpart *term_p; + +static int term_running; + +// Any character in standard input available (without sleeping)? +static int readytoread() { +#ifdef WIN32 + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + + while(1) { + INPUT_RECORD input[1] = { 0 }; + DWORD dwNumberOfEventsRead = 0; + + if(!PeekConsoleInputA(hStdin, input, ARRAYSIZE(input), &dwNumberOfEventsRead)) { + DWORD dwError = GetLastError(); + + // Stdin redirected from a pipe or file (FIXME: reading from a pipe may sleep) + if(dwError == ERROR_INVALID_HANDLE) + return 1; + + pmsg_warning("PeekConsoleInputA() failed with error code %u\n", (unsigned int) dwError); + return -1; + } + + if(dwNumberOfEventsRead <= 0) // Nothing in the input buffer + return 0; + + // Filter out all the events that readline does not handle ... + if((input[0].EventType & KEY_EVENT) != 0 && input[0].Event.KeyEvent.bKeyDown) + return 1; + + // Drain other events not handled by readline + if(!ReadConsoleInputA(hStdin, input, ARRAYSIZE(input), &dwNumberOfEventsRead)) { + pmsg_warning("ReadConsoleInputA() failed with error code %u\n", (unsigned int) GetLastError()); + return -1; } - free(cmdbuf); } +#else + struct timeval tv = { 0L, 0L }; + fd_set fds; + FD_ZERO(&fds); + FD_SET(0, &fds); - pgm->flush_cache(pgm, p); + return select(1, &fds, NULL, NULL, &tv) > 0; +#endif +} - return rc; +// Callback processes commands whenever readline() has finished +void term_gotline(char *cmdstr) { + if(cmdstr) { + if(*cmdstr) { + add_history(cmdstr); + // only quit/abort returns a value > 0 + if(process_line(cmdstr, term_pgm, term_p) > 0) + term_running = 0; + } + free(cmdstr); + } else { + // call quit at end of file or terminal ^D + term_out("\n"); + cmd_quit(term_pgm, term_p, 0, NULL); + term_running = 0; + } } -int terminal_message(const int msglvl, const char *format, ...) { +int terminal_mode(PROGRAMMER *pgm, struct avrpart *p) { + term_pgm = pgm; // For callback routine + term_p = p; + + rl_callback_handler_install("avrdude> ", term_gotline); + + term_running = 1; + for(int n=1; term_running; n++) { + if(n%16 == 0) { // Every 100 ms (16*6.25 us) reset bootloader watchdog timer + if(pgm->term_keep_alive) + pgm->term_keep_alive(pgm, NULL); + } + usleep(6250); + if(readytoread() > 0 && term_running) + rl_callback_read_char(); + } + + rl_callback_handler_remove(); + + return pgm->flush_cache(pgm, p); +} + +#else + + +int terminal_mode(PROGRAMMER *pgm, struct avrpart *p) { + char *cmdbuf; int rc = 0; - va_list ap; - fflush(stdout); fflush(stderr); - if (verbose >= msglvl) { - va_start(ap, format); - rc = vfprintf(stderr, format, ap); - va_end(ap); + while((cmdbuf = terminal_get_input("avrdude> "))) { + int rc = process_line(cmdbuf, pgm, p); + free(cmdbuf); + if(rc > 0) + break; } - fflush(stderr); - return rc; + if(rc <= 0) + cmd_quit(pgm, p, 0, NULL); + return pgm->flush_cache(pgm, p); } +#endif static void update_progress_tty(int percent, double etime, const char *hdr, int finish) { static char *header; - static int last, done; + static int last, done = 1; int i; setvbuf(stderr, (char *) NULL, _IONBF, 0); @@ -1330,7 +1371,7 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int hashes[i/2] = '#'; hashes[50] = 0; - msg_info("\r%s | %s | %d%% %0.2fs", header, hashes, showperc, etime); + msg_info("\r%s | %s | %d%% %0.2f s ", header, hashes, showperc, etime); if(percent == 100) { if(finish) msg_info("\n\n"); @@ -1343,7 +1384,7 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int } static void update_progress_no_tty(int percent, double etime, const char *hdr, int finish) { - static int last, done; + static int last, done = 1; setvbuf(stderr, (char *) NULL, _IONBF, 0); diff --git a/src/term.h b/src/term.h index a89927ea..61c4916c 100644 --- a/src/term.h +++ b/src/term.h @@ -35,7 +35,6 @@ typedef enum { int terminal_mode(PROGRAMMER * pgm, struct avrpart * p); char * terminal_get_input(const char *prompt); void terminal_setup_update_progress(); -int terminal_message(const int msglvl, const char *format, ...); #ifdef __cplusplus } diff --git a/src/update.c b/src/update.c index e1a272c6..13580536 100644 --- a/src/update.c +++ b/src/update.c @@ -335,11 +335,11 @@ int update_is_readable(const char *fn) { static void ioerror(const char *iotype, UPDATE *upd) { int errnocp = errno; - pmsg_ext_error("file %s is not %s", update_outname(upd->filename), iotype); + pmsg_ext_error("file %s is not %s: ", update_outname(upd->filename), iotype); if(errnocp) - msg_ext_error("memstats(): %s", strerror(errnocp)); + msg_ext_error("%s", strerror(errnocp)); else if(upd->filename && *upd->filename) - msg_ext_error(" (not a regular or character file?)"); + msg_ext_error("(not a regular or character file?)"); msg_ext_error("\n"); } @@ -456,7 +456,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f } pmsg_info("reading %s%s memory ...\n", mem->desc, alias_mem_desc); - report_progress(0, 1, "Reading"); + if(mem->size > 32 || verbose > 1) + report_progress(0, 1, "Reading"); rc = avr_read(pgm, p, upd->memtype, 0); report_progress(1, 1, NULL); @@ -511,7 +512,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f update_plural(fs.nbytes), mem->desc, alias_mem_desc); if (!(flags & UF_NOWRITE)) { - report_progress(0, 1, "Writing"); + if(mem->size > 32 || verbose > 1) + report_progress(0, 1, "Writing"); rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0); report_progress(1, 1, NULL); } else { @@ -569,7 +571,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f pmsg_notice2("reading on-chip %s%s data ...\n", mem->desc, alias_mem_desc); } - report_progress (0,1,"Reading"); + if(mem->size > 32 || verbose > 1) + report_progress (0,1,"Reading"); rc = avr_read(pgm, p, upd->memtype, v); report_progress (1,1,NULL); if (rc < 0) {