diff --git a/src/avrcache.c b/src/avrcache.c index 8ced34c6..299e9288 100644 --- a/src/avrcache.c +++ b/src/avrcache.c @@ -44,6 +44,9 @@ * * int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); * + * int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const + * AVRMEM *mem, unsigned int baseaddr); + * * int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); * * avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged @@ -82,6 +85,9 @@ * cache preset to all 0xff otherwise the cache discards all pending writes * to EEPROM and is left unchanged otherwise. * + * The avr_page_erase_cached() function erases a page and synchronises it + * with the cache. + * * Finally, avr_reset_cache() resets the cache without synchronising pending * writes() to the device. * @@ -188,21 +194,18 @@ static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) { } -static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem, int level) { +static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem) { int cacheaddr = addr + (int) (mem->offset - cp->offset); if(cacheaddr < 0 || cacheaddr >= cp->size) { // Should never happen (unless offsets wrong in avrdude.conf) - if(level != MSG_INFO) - avrdude_message(level, "%s: ", progname); - avrdude_message(level, "cacheAddress() %s cache address 0x%04x out of range [0, 0x%04x]\n", mem->desc, cacheaddr, cp->size); + avrdude_message(MSG_INFO, "%s: cacheAddress() %s cache address 0x%04x out of range [0, 0x%04x]\n", + progname, mem->desc, cacheaddr, cp->size); return LIBAVRDUDE_GENERAL_FAILURE; } if(mem->page_size != cp->page_size) { // Should never happen (unless incompatible page sizes in avrdude.conf) - if(level != MSG_INFO) - avrdude_message(level, "%s: ", progname); - avrdude_message(level, "cacheAddress() %s page size %d incompatible with cache page size %d\n", - mem->desc, mem->page_size, cp->page_size); + avrdude_message(MSG_INFO, "%s: cacheAddress() %s page size %d incompatible with cache page size %d\n", + progname, mem->desc, mem->page_size, cp->page_size); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -210,7 +213,7 @@ static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem, int le } -static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, int cacheaddr, int level) { +static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, int cacheaddr, int nlOnErr) { int pgno = cacheaddr/cp->page_size; if(!cp->iscached[pgno]) { @@ -218,9 +221,9 @@ static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, int cachebase = cacheaddr & ~(cp->page_size-1); if(avr_read_page_default(pgm, p, mem, addr & ~(cp->page_size-1), cp->cont + cachebase) < 0) { report_progress(1, -1, NULL); - if(level != MSG_INFO || !quell_progress) - avrdude_message(level, "%s: ", progname); - avrdude_message(level, "loadCachePage() %s read failed at addr 0x%04x\n", mem->desc, addr); + if(nlOnErr && quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: loadCachePage() %s read error at addr 0x%04x\n", progname, mem->desc, addr); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -233,21 +236,21 @@ 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 level) { +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(avr_write_page_default(pgm, p, mem, base, cp->cont + base) < 0) { report_progress(1, -1, NULL); - if(level != MSG_INFO || !quell_progress) - avrdude_message(level, "%s: ", progname); - avrdude_message(level, "writeCachePage() %s write error at addr 0x%04x\n", mem->desc, base); + if(nlOnErr && quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: writeCachePage() %s write error at addr 0x%04x\n", progname, 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) { report_progress(1, -1, NULL); - if(level != MSG_INFO || !quell_progress) - avrdude_message(level, "%s: ", progname); - avrdude_message(level, "writeCachePage() %s read error at addr 0x%04x\n", mem->desc, base); + if(nlOnErr && quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: writeCachePage() %s read error at addr 0x%04x\n", progname, mem->desc, base); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -326,15 +329,17 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { AVR_Cache *cp = mems[i].cp; if(!cp->cont) // Ensure cache is initialised from now on - if(initCache(cp, pgm, p) < 0) + if(initCache(cp, pgm, p) < 0) { + avrdude_message(MSG_INFO, "%s: initialising the cache failed\n", progname); return LIBAVRDUDE_GENERAL_FAILURE; + } if(chiperase || !mem || mems[i].zopaddr < 0) continue; int n=mems[i].zopaddr; - if(writeCachePage(cp, pgm, p, mem, n, MSG_INFO) < 0) + if(writeCachePage(cp, pgm, p, mem, n, 1) < 0) return LIBAVRDUDE_GENERAL_FAILURE; // Same? OK, can set cleared bit to one, "normal" memory if(!memcmp(cp->copy + n, cp->cont + n, cp->page_size)) { @@ -344,7 +349,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { // Probably NOR memory, check out page erase if(pgm->page_erase && pgm->page_erase(pgm, p, mem, n) >= 0) { - if(writeCachePage(cp, pgm, p, mem, n, MSG_INFO) < 0) + if(writeCachePage(cp, pgm, p, mem, n, 1) < 0) return LIBAVRDUDE_GENERAL_FAILURE; // Worked OK? Can use page erase on this memory if(!memcmp(cp->copy + n, cp->cont + n, cp->page_size)) { @@ -357,8 +362,10 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { chiperase = 1; } - if(!chpages) + if(!chpages) { + avrdude_message(MSG_INFO, "done\n"); return LIBAVRDUDE_SUCCESS; + } if(chiperase) { if(quell_progress) { @@ -379,8 +386,8 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { nrd++; } + report_progress(0, 1, "Reading"); if(nrd) { - report_progress(0, 1, "Reading"); // Read full flash and EEPROM for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { AVRMEM *mem = mems[i].mem; @@ -391,20 +398,20 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { for(int ird = 0, pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) { if(!cp->iscached[pgno]) { report_progress(ird++, nrd, NULL); - if(loadCachePage(cp, pgm, p, mem, n, n, MSG_INFO) < 0) + if(loadCachePage(cp, pgm, p, mem, n, n, 1) < 0) return LIBAVRDUDE_GENERAL_FAILURE; } } } - report_progress(1, 0, NULL); } + report_progress(1, 0, NULL); report_progress(0, 1, "Erasing"); if(avr_chip_erase(pgm, p) < 0) { report_progress(1, -1, NULL); - if(!quell_progress) - avrdude_message(MSG_INFO, "%s: ", progname); - avrdude_message(MSG_INFO, "avr_flush_cache() chip erase failed\n"); + if(quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: avr_flush_cache() chip erase failed\n", progname); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -426,9 +433,9 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { report_progress(1+ibo++, nbo+2, NULL); if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0) { report_progress(1, -1, NULL); - if(!quell_progress) - avrdude_message(MSG_INFO, "%s: ", progname); - avrdude_message(MSG_INFO, "flash read failed at addr 0x%04x\n", n); + if(quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: flash read failed at addr 0x%04x\n", progname, n); return LIBAVRDUDE_GENERAL_FAILURE; } } @@ -439,9 +446,9 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { if(!_is_all_0xff(cp->copy + n, cp->page_size)) { // First page that had EEPROM data if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0) { report_progress(1, -1, NULL); - if(!quell_progress) - avrdude_message(MSG_INFO, "%s: ", progname); - avrdude_message(MSG_INFO, "EEPROM read failed at addr 0x%04x\n", n); + if(quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: EEPROM read failed at addr 0x%04x\n", progname, n); return LIBAVRDUDE_GENERAL_FAILURE; } // EEPROM zapped by chip erase? Set all copy to 0xff @@ -468,8 +475,8 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { nwr++; } + report_progress(0, 1, "Writing"); if(nwr) { - report_progress(0, 1, "Writing"); // Write all modified pages to the device for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { AVRMEM *mem = mems[i].mem; @@ -481,24 +488,23 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { if(cp->iscached[pgno] && memcmp(cp->copy + n, cp->cont + n, cp->page_size)) { if(!chiperase && mems[i].pgerase) pgm->page_erase(pgm, p, mem, n); - if(writeCachePage(cp, pgm, p, mem, n, MSG_INFO) < 0) + if(writeCachePage(cp, pgm, p, mem, n, 1) < 0) return LIBAVRDUDE_GENERAL_FAILURE; if(memcmp(cp->copy + n, cp->cont + n, cp->page_size)) { report_progress(1, -1, NULL); - if(!quell_progress) - avrdude_message(MSG_INFO, "%s: ", progname); - avrdude_message(MSG_INFO, "%s verification error at addr 0x%04x\n", mem->desc, n); + if(quell_progress) + avrdude_message(MSG_INFO, "\n"); + avrdude_message(MSG_INFO, "%s: %s verification error at addr 0x%04x\n", progname, mem->desc, n); return LIBAVRDUDE_GENERAL_FAILURE; } report_progress(iwr++, nwr, NULL); } } } - report_progress(1, 0, NULL); } + report_progress(1, 0, NULL); avrdude_message(MSG_INFO, quell_progress? "done\n": "\n"); - return LIBAVRDUDE_SUCCESS; } @@ -531,12 +537,12 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * if(initCache(cp, pgm, p) < 0) return LIBAVRDUDE_GENERAL_FAILURE; - int cacheaddr = cacheAddress((int) addr, cp, mem, MSG_NOTICE); + int cacheaddr = cacheAddress((int) addr, cp, mem); if(cacheaddr < 0) return LIBAVRDUDE_GENERAL_FAILURE; // Ensure cache page is there - if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, MSG_NOTICE) < 0) + if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, 0) < 0) return LIBAVRDUDE_GENERAL_FAILURE; *value = cp->cont[cacheaddr]; @@ -569,12 +575,12 @@ int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(initCache(cp, pgm, p) < 0) return LIBAVRDUDE_GENERAL_FAILURE; - int cacheaddr = cacheAddress((int) addr, cp, mem, MSG_NOTICE); + int cacheaddr = cacheAddress((int) addr, cp, mem); if(cacheaddr < 0) return LIBAVRDUDE_GENERAL_FAILURE; // Ensure cache page is there - if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, MSG_NOTICE) < 0) + if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, 0) < 0) return LIBAVRDUDE_GENERAL_FAILURE; cp->cont[cacheaddr] = data; @@ -640,6 +646,42 @@ int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) { } +// Erase a page and synchronise it with the cache +int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned int uaddr) { + + int addr = uaddr; + + if(!pgm->page_erase || !avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size) + return LIBAVRDUDE_GENERAL_FAILURE; + + if(pgm->page_erase(pgm, p, mem, uaddr) < 0) + return LIBAVRDUDE_GENERAL_FAILURE; + + AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash; + + if(!cp->cont) // Init cache if needed + if(initCache(cp, pgm, p) < 0) + return LIBAVRDUDE_GENERAL_FAILURE; + + int cacheaddr = cacheAddress(addr, cp, mem); + if(cacheaddr < 0) + return LIBAVRDUDE_GENERAL_FAILURE; + + // Invalidate this cache page and read back, ie, we don't trust the page_erase() routine + cp->iscached[cacheaddr/cp->page_size] = 0; + + // Reload cache page + if(loadCachePage(cp, pgm, p, mem, (int) addr, cacheaddr, 0) < 0) + return LIBAVRDUDE_GENERAL_FAILURE; + + if(!_is_all_0xff(cp->cont + (cacheaddr & ~(cp->page_size-1)), cp->page_size)) + return LIBAVRDUDE_GENERAL_FAILURE; + + return LIBAVRDUDE_SUCCESS; +} + + // Free cache(s) discarding any pending writes int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p) { AVR_Cache *mems[2] = { pgm->cp_flash, pgm->cp_eeprom, }; diff --git a/src/avrdude.1 b/src/avrdude.1 index f0100350..ba5292ee 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -639,7 +639,7 @@ Note: The ability to handle IPv6 hostnames and addresses is limited to Posix systems (by now). .It Fl q Disable (or quell) output of the progress bar while reading or writing -to the device. Specify it a second time for even quieter operation. +to the device. Specify it more often for even quieter operations. .It Fl s, u These options used to control the obsolete "safemode" feature which is no longer present. They are silently ignored for backwards compatibility. @@ -812,7 +812,7 @@ abbreviated to the shortest unambiguous form. Terminal mode provides a command history using .Xr readline 3 , so previously entered command lines can be recalled and edited. The -following commands are currently implemented: +following commands are currently implemented for all programmers: .Bl -tag -offset indent -width indent .It Ar dump memory addr len Read @@ -827,12 +827,14 @@ and display them. Read 256 bytes from the specified memory area, and display them. .It Ar dump memory ... Read all bytes from the specified memory, and display them. -.It Ar dump +.It Ar dump memory Continue dumping the memory contents for another .Ar 256 bytes where the previous .Ar dump command left off. +.It Ar read +can be used as an alias for dump .It Ar write memory addr data[,] {data[,]} Manually program the respective memory cells, starting at address .Ar addr , @@ -895,6 +897,39 @@ or after EOF on input is encountered. The abort command resets the cache discarding all previous writes to the flash and EEPROM cache. .It Ar erase Perform a chip erase and discard all pending writes to EEPROM and flash. +.It Ar sig +Display the device signature bytes. +.It Ar part +Display the current part settings and parameters. Includes chip +specific information including all memory types supported by the +device, read/write timing, etc. +.It Ar verbose Op Ar level +Change (when +.Ar level +is provided), or display the verbosity level. +The initial verbosity level is controlled by the number of +.Fl v +options given on the commandline. +.It Ar quell Op Ar level +Change (when +.Ar level +is provided), or display the quell level. 1 is used to suppress progress reports. +2 or higher yields in progressively quieter operations. +The initial quell level is controlled by the number of +.Fl q +options given on the commandline. +.It Ar \&? +.It Ar help +Give a short on-line summary of the available commands. +.It Ar quit +Leave terminal mode and thus +.Nm avrdude . +.El +.Pp +The terminal commands below may only be implemented on some specific programmers, and may therefore not be available in the help menu. +.Bl -tag -offset indent -width indent +.It pgerase memory addr +Erase one page of the memory specified. .It Ar send b1 b2 b3 b4 Send raw instruction codes to the AVR device. If you need access to a feature of an AVR part that is not directly supported by @@ -903,24 +938,18 @@ this command allows you to use it, even though .Nm does not implement the command. When using direct SPI mode, up to 3 bytes can be omitted. -.It Ar sig -Display the device signature bytes. .It Ar spi Enter direct SPI mode. The .Em pgmled pin acts as slave select. -.Em Only supported on parallel bitbang programmers, and partially by USBtiny. -.It Ar part -Display the current part settings and parameters. Includes chip -specific information including all memory types supported by the -device, read/write timing, etc. +.Em Supported on parallel bitbang programmers, and partially by USBtiny. .It Ar pgm Return to programming mode (from direct SPI mode). .It Ar vtarg voltage Set the target's supply voltage to .Ar voltage Volts. -.Em Only supported on the STK500 and STK600 programmer. +.Em Supported on the STK500 and STK600 programmer. .It Ar varef Oo Ar channel Oc Ar voltage Set the adjustable voltage source to .Ar voltage @@ -932,7 +961,7 @@ On the Atmel STK600, two reference voltages are available, which can be selected by the optional .Ar channel argument (either 0 or 1). -.Em Only supported on the STK500 and STK600 programmer. +.Em Supported on the STK500 and STK600 programmer. .It Ar fosc freq Ns Op M Ns \&| Ns k Set the master oscillator to .Ar freq @@ -942,17 +971,16 @@ An optional trailing letter multiplies by 1E6, a trailing letter .Ar \&k by 1E3. -.Em Only supported on the STK500 and STK600 programmer. +.Em Supported on the STK500 and STK600 programmer. .It Ar fosc off Turn the master oscillator off. -.Em Only supported on the STK500 and STK600 programmer. +.Em Supported on the STK500 and STK600 programmer. .It Ar sck period -.Em STK500 and STK600 programmer only: +.Em STK500 and STK600 programmer: Set the SCK clock period to .Ar period microseconds. -.Pp -.Em JTAG ICE only: +.Em JTAG ICE: Set the JTAG ICE bit clock period to .Ar period microseconds. @@ -962,24 +990,12 @@ software signs off from the JTAG ICE. This parameter can also be used on the JTAG ICE mkII, JTAGICE3, and Atmel-ICE to specify the ISP clock period when operating the ICE in ISP mode. .It Ar parms -.Em STK500 and STK600 programmer only: +.Em STK500 and STK600 programmer: Display the current voltage and master oscillator parameters. -.Pp -.Em JTAG ICE only: +.Em JTAG ICE: Display the current target supply voltage and JTAG bit clock rate/period. -.It Ar verbose Op Ar level -Change (when -.Ar level -is provided), or display the verbosity level. -The initial verbosity level is controlled by the number of -.Fl v -options given on the commandline. -.It Ar \&? -.It Ar help -Give a short on-line summary of the available commands. -.It Ar quit -Leave terminal mode and thus -.Nm avrdude . +.Em Other programmers: +Display the programmer specific parameters. .El .Ss Default Parallel port pin connections (these can be changed, see the diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index ec05d3ba..10b44dc0 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -1329,7 +1329,7 @@ commands can be recalled and edited. @section Terminal Mode Commands @noindent -The following commands are implemented: +The following commands are implemented for all programmers: @table @code @@ -1350,6 +1350,9 @@ Read all bytes from the specified memory, and display them. Continue dumping the memory contents for another @var{nbytes} where the previous dump command left off. +@item read +Can be used as an alias for dump. + @item write @var{memtype} @var{addr} @var{data[,]} @{@var{data[,]}@} Manually program the respective memory cells, starting at address @var{addr}, using the data items provided. The terminal implements @@ -1461,36 +1464,26 @@ cache discarding all previous writes to the flash and EEPROM cache. @item erase Perform a chip erase and discard all pending writes to EEPROM and flash. -@item send @var{b1} @var{b2} @var{b3} @var{b4} -Send raw instruction codes to the AVR device. If you need access to a -feature of an AVR part that is not directly supported by AVRDUDE, this -command allows you to use it, even though AVRDUDE does not implement the -command. When using direct SPI mode, up to 3 bytes -can be omitted. - @item sig Display the device signature bytes. -@item spi -Enter direct SPI mode. The @emph{pgmled} pin acts as slave select. -@emph{Only supported on parallel bitbang programmers, and partially by USBtiny.} -Slave Select must be externally held low for direct SPI when -using USBtinyISP, and send must be a multiple of four bytes. - @item part Display the current part settings and parameters. Includes chip specific information including all memory types supported by the device, read/write timing, etc. -@item pgm -Return to programming mode (from direct SPI mode). - @item verbose [@var{level}] Change (when @var{level} is provided), or display the verbosity level. The initial verbosity level is controlled by the number of @code{-v} options given on the command line. +@item quell [@var{level}] +Change (when @var{level} is provided), or display the quell +level. 1 is used to suppress progress reports. 2 or higher yields +progressively quieter operations. The initial quell level is controlled +by the number of @code{-q} options given on the command line. + @item ? @itemx help Give a short on-line summary of the available commands. @@ -1501,11 +1494,29 @@ Leave terminal mode and thus AVRDUDE. @end table @noindent -In addition, the following commands are supported on the STK500 -and STK600 programmer: +In addition, the following commands are supported on some programmers: @table @code +@item pgerase @var{memory} @var{addr} +Erase one page of the memory specified. + +@item send @var{b1} @var{b2} @var{b3} @var{b4} +Send raw instruction codes to the AVR device. If you need access to a +feature of an AVR part that is not directly supported by AVRDUDE, this +command allows you to use it, even though AVRDUDE does not implement the +command. When using direct SPI mode, up to 3 bytes +can be omitted. + +@item spi +Enter direct SPI mode. The @emph{pgmled} pin acts as slave select. +@emph{Only supported on parallel bitbang programmers, and partially by USBtiny.} +Slave Select must be externally held low for direct SPI when +using USBtinyISP, and send must be a multiple of four bytes. + +@item pgm +Return to programming mode (from direct SPI mode). + @item vtarg @var{voltage} Set the target's supply voltage to @var{voltage} Volts. @@ -1528,7 +1539,6 @@ Turn the master oscillator off. @item sck @var{period} @emph{STK500 and STK600 only:} Set the SCK clock period to @var{period} microseconds. - @emph{JTAG ICE only:} Set the JTAG ICE bit clock period to @var{period} microseconds. Note that unlike STK500 settings, this setting will be reverted to @@ -1540,7 +1550,6 @@ ISP clock period when operating the ICE in ISP mode. @item parms @emph{STK500 and STK600 only:} Display the current voltage and master oscillator parameters. - @emph{JTAG ICE only:} Display the current target supply voltage and JTAG bit clock rate/period. diff --git a/src/libavrdude.h b/src/libavrdude.h index 1c825fc1..01f80a72 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -802,6 +802,8 @@ typedef struct programmer_t { int (*read_byte_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); int (*chip_erase_cached)(const struct programmer_t *pgm, const AVRPART *p); + int (*page_erase_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int baseaddr); int (*flush_cache) (const struct programmer_t *pgm, const AVRPART *p); int (*reset_cache) (const struct programmer_t *pgm, const AVRPART *p); AVR_Cache *cp_flash, *cp_eeprom; @@ -918,6 +920,7 @@ int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); +int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int baseaddr); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); diff --git a/src/pgm.c b/src/pgm.c index e932f05d..7a297582 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -122,6 +122,7 @@ PROGRAMMER *pgm_new(void) { pgm->read_byte_cached = avr_read_byte_cached; pgm->write_byte_cached = avr_write_byte_cached; pgm->chip_erase_cached = avr_chip_erase_cached; + pgm->page_erase_cached = avr_page_erase_cached; pgm->flush_cache = avr_flush_cache; pgm->reset_cache = avr_reset_cache; diff --git a/src/term.c b/src/term.c index 6aaab87f..c0fe33db 100644 --- a/src/term.c +++ b/src/term.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -40,91 +41,60 @@ #include "term.h" struct command { - char * name; - int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]); - char * desc; + char *name; + int (*func)(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); + size_t fnoff; + char *desc; }; -static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); +static int cmd_dump (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_write (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_flush (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_abort (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_erase (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_sig (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_part (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_help (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_quit (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_send (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_parms (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_vtarg (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_varef (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_fosc (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_sck (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_spi (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_pgm (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_verbose(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); +static int cmd_quell (PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]); -static int cmd_write (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_flush (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_abort (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_part (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_help (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_send (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_spi (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_pgm (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_verbose (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); - -static int cmd_quell (PROGRAMMER * pgm, struct avrpart * p, - int argc, char *argv[]); +#define _fo(x) offsetof(PROGRAMMER, x) struct command cmd[] = { - { "dump", cmd_dump, "%s [ | ... | | ...]" }, - { "read", cmd_dump, "alias for dump" }, - { "write", cmd_write, "%s [[,] {[,]} | [,] {[,]} ...]" }, - { "flush", cmd_flush, "synchronise flash & EEPROM writes with the device" }, - { "abort", cmd_abort, "abort flash & EEPROM writes (reset the r/w cache)" }, - { "erase", cmd_erase, "perform a chip erase" }, - { "sig", cmd_sig, "display device signature bytes" }, - { "part", cmd_part, "display the current part information" }, - { "send", cmd_send, "send a raw command: %s " }, - { "parms", cmd_parms, "display adjustable parameters (STK500 and Curiosity Nano only)" }, - { "vtarg", cmd_vtarg, "set (STK500 and Curiosity Nano only)" }, - { "varef", cmd_varef, "set (STK500 only)" }, - { "fosc", cmd_fosc, "set (STK500 only)" }, - { "sck", cmd_sck, "set (STK500 only)" }, - { "spi", cmd_spi, "enter direct SPI mode" }, - { "pgm", cmd_pgm, "return to programming mode" }, - { "verbose", cmd_verbose, "change verbosity" }, - { "quell", cmd_quell, "set quell level for progress bars" }, - { "help", cmd_help, "help" }, - { "?", cmd_help, "help" }, - { "quit", cmd_quit, "quit after writing out cache for flash & EEPROM" } + { "dump", cmd_dump, _fo(read_byte_cached), "%s [ | ... | | ...]" }, + { "read", cmd_dump, _fo(read_byte_cached), "alias for dump" }, + { "write", cmd_write, _fo(write_byte_cached), "write [,] {[,]}" }, + { "", cmd_write, _fo(write_byte_cached), "write [,] {[,]} ..." }, + { "flush", cmd_flush, _fo(flush_cache), "synchronise flash & EEPROM writes with the device" }, + { "abort", cmd_abort, _fo(reset_cache), "abort flash & EEPROM writes (reset the r/w cache)" }, + { "erase", cmd_erase, _fo(chip_erase_cached), "perform a chip erase" }, + { "pgerase", cmd_pgerase, _fo(page_erase), "pgerase " }, + { "sig", cmd_sig, _fo(open), "display device signature bytes" }, + { "part", cmd_part, _fo(open), "display the current part information" }, + { "send", cmd_send, _fo(cmd), "send a raw command: %s " }, + { "parms", cmd_parms, _fo(print_parms), "display adjustable parameters" }, + { "vtarg", cmd_vtarg, _fo(set_vtarget), "set " }, + { "varef", cmd_varef, _fo(set_varef), "set " }, + { "fosc", cmd_fosc, _fo(set_fosc), "set " }, + { "sck", cmd_sck, _fo(set_sck_period), "set " }, + { "spi", cmd_spi, _fo(setpin), "enter direct SPI mode" }, + { "pgm", cmd_pgm, _fo(setpin), "return to programming mode" }, + { "verbose", cmd_verbose, _fo(open), "change verbosity" }, + { "quell", cmd_quell, _fo(open), "set quell level for progress bars" }, + { "help", cmd_help, _fo(open), "show help message" }, + { "?", cmd_help, _fo(open), "same as help" }, + { "quit", cmd_quit, _fo(open), "quit after writing out cache for flash & EEPROM" } }; #define NCMDS ((int)(sizeof(cmd)/sizeof(struct command))) @@ -133,8 +103,7 @@ struct command cmd[] = { static int spi_mode = 0; -static int nexttok(char * buf, char ** tok, char ** next) -{ +static int nexttok(char *buf, char **tok, char **next) { unsigned char *q, *n; q = (unsigned char *) buf; @@ -171,10 +140,9 @@ static int nexttok(char * buf, char ** tok, char ** next) } -static int hexdump_line(char * buffer, unsigned char * p, int n, int pad) -{ - char * hexdata = "0123456789abcdef"; - char * b = buffer; +static int hexdump_line(char *buffer, unsigned char *p, int n, int pad) { + char *hexdata = "0123456789abcdef"; + char *b = buffer; int i = 0; int j = 0; @@ -201,8 +169,7 @@ static int hexdump_line(char * buffer, unsigned char * p, int n, int pad) } -static 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; unsigned char b[128]; @@ -223,13 +190,12 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad) } -static 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) { char dst1[80]; char dst2[80]; int addr = startaddr; - unsigned char * p = (unsigned char *)buf; + unsigned char *p = (unsigned char *)buf; while (len) { int n = 16; if (n > len) @@ -246,9 +212,7 @@ static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len) } -static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (argc < 2 || argc > 4) { terminal_message(MSG_INFO, "Usage: %s \n" @@ -262,8 +226,8 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, enum { read_size = 256 }; static const char *prevmem = ""; - char * memtype = argv[1]; - AVRMEM * mem = avr_locate_mem(p, memtype); + 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); @@ -272,7 +236,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int maxsize = mem->size; // Get start address if present - char * end_ptr; + char *end_ptr; static int addr = 0; if (argc >= 3 && strcmp(argv[2], "...") != 0) { @@ -281,9 +245,9 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, terminal_message(MSG_INFO, "%s (dump): can't parse address %s\n", progname, argv[2]); return -1; - } else if (addr >= maxsize) { - terminal_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n", - progname, (long) addr, mem->desc); + } 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); return -1; } } @@ -322,7 +286,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, if ((addr + len) > maxsize) len = maxsize - addr; - uint8_t * buf = malloc(len); + uint8_t *buf = malloc(len); if (buf == NULL) { terminal_message(MSG_INFO, "%s (dump): out of memory\n", progname); return -1; @@ -399,12 +363,10 @@ static int is_mantissa_only(char *p) { } -static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { if (argc < 4) { terminal_message(MSG_INFO, - "Usage: write [,] {[,]} \n" + "Usage: write [,] {[,]}\n" " write [,] {[,]} ...\n" "\n" "Ellipsis ... writes bytes padded by repeating the last item.\n" @@ -440,8 +402,8 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, 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); + 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); @@ -449,7 +411,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, } int maxsize = mem->size; - char * end_ptr; + 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", @@ -457,14 +419,14 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, return -1; } - if (addr > maxsize) { - terminal_message(MSG_INFO, "%s (write): address 0x%05lx is out of range for %s memory\n", - progname, (long) addr, memtype); + 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); 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)); + 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); return -1; @@ -732,32 +694,24 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_flush(PROGRAMMER *pgm, struct avrpart *p, int ac, char *av[]) { +static int cmd_flush(PROGRAMMER *pgm, AVRPART *p, int ac, char *av[]) { pgm->flush_cache(pgm, p); return 0; } -static int cmd_abort(PROGRAMMER *pgm, struct avrpart *p, int ac, char *av[]) { +static int cmd_abort(PROGRAMMER *pgm, AVRPART *p, int ac, char *av[]) { pgm->reset_cache(pgm, p); return 0; } -static int cmd_send(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { unsigned char cmd[4], res[4]; - char * e; + char *e; int i; int len; - if (pgm->cmd == NULL) { - terminal_message(MSG_INFO, "%s (send): the %s programmer does not support direct ISP commands\n", - progname, pgm->type); - return -1; - } - 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); @@ -806,9 +760,7 @@ static int cmd_send(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_erase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { terminal_message(MSG_INFO, "%s: erasing chip\n", progname); // Erase chip and clear cache pgm->chip_erase_cached(pgm, p); @@ -817,9 +769,53 @@ static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_part(PROGRAMMER * pgm, struct 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"); + 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); + 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))); + return -1; + } + + int maxsize = mem->size; + + 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]); + 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); + 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): %s page at 0x%05x could not be erased\n", + progname, mem->desc, addr); + return -1; + } + + return 0; +} + + +static int cmd_part(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { fprintf(stdout, "\n"); avr_display(stdout, p, "", 0); fprintf(stdout, "\n"); @@ -828,12 +824,10 @@ static int cmd_part(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_sig(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int i; int rc; - AVRMEM * m; + AVRMEM *m; rc = avr_signature(pgm, p); if (rc != 0) { @@ -857,9 +851,7 @@ static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_quit(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { /* FUSE bit verify will fail if left in SPI mode */ if (spi_mode) { cmd_pgm(pgm, p, 0, NULL); @@ -868,23 +860,14 @@ static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ - if (pgm->print_parms == NULL) { - terminal_message(MSG_INFO, "%s (parms): the %s programmer does not support " - "adjustable parameters\n", progname, pgm->type); - return -1; - } +static int cmd_parms(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { pgm->print_parms(pgm); terminal_message(MSG_INFO, "\n"); return 0; } -static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_vtarg(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int rc; double v; char *endp; @@ -899,11 +882,6 @@ static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, progname, argv[1]); return -1; } - if (pgm->set_vtarget == NULL) { - terminal_message(MSG_INFO, "%s (vtarg): the %s programmer cannot set V[target]\n", - progname, pgm->type); - return -2; - } if ((rc = pgm->set_vtarget(pgm, v)) != 0) { terminal_message(MSG_INFO, "%s (vtarg): failed to set V[target] (rc = %d)\n", progname, rc); @@ -913,9 +891,7 @@ static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int rc; double v; char *endp; @@ -938,11 +914,6 @@ static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, v *= 1e6; else if (*endp == 'k' || *endp == 'K') v *= 1e3; - if (pgm->set_fosc == NULL) { - terminal_message(MSG_INFO, "%s (fosc): the %s programmer cannot set oscillator frequency\n", - progname, pgm->type); - return -2; - } if ((rc = pgm->set_fosc(pgm, v)) != 0) { terminal_message(MSG_INFO, "%s (fosc): failed to set oscillator frequency (rc = %d)\n", progname, rc); @@ -952,9 +923,7 @@ static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_sck(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int rc; double v; char *endp; @@ -970,11 +939,6 @@ static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, return -1; } v *= 1e-6; /* Convert from microseconds to seconds. */ - if (pgm->set_sck_period == NULL) { - terminal_message(MSG_INFO, "%s (sck): the %s programmer cannot set SCK period\n", - progname, pgm->type); - return -2; - } if ((rc = pgm->set_sck_period(pgm, v)) != 0) { terminal_message(MSG_INFO, "%s (sck): failed to set SCK period (rc = %d)\n", progname, rc); @@ -984,9 +948,7 @@ static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_varef(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int rc; unsigned int chan; double v; @@ -1018,11 +980,6 @@ static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, return -1; } } - if (pgm->set_varef == NULL) { - terminal_message(MSG_INFO, "%s (varef): the %s programmer cannot set V[aref]\n", - progname, pgm->type); - return -2; - } if ((rc = pgm->set_varef(pgm, chan, v)) != 0) { terminal_message(MSG_INFO, "%s (varef): failed to set V[aref] (rc = %d)\n", progname, rc); @@ -1032,56 +989,39 @@ static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, } -static int cmd_help(PROGRAMMER * pgm, struct 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"); for (i=0; isetpin != NULL) { - pgm->setpin(pgm, PIN_AVR_RESET, 1); - spi_mode = 1; - return 0; - } - terminal_message(MSG_INFO, "%s: spi command unavailable for this programmer type\n", - progname); - return -1; +static int cmd_spi(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { + pgm->setpin(pgm, PIN_AVR_RESET, 1); + spi_mode = 1; + return 0; } -static int cmd_pgm(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ - if (pgm->setpin != NULL) { - pgm->setpin(pgm, PIN_AVR_RESET, 0); - spi_mode = 0; - pgm->initialize(pgm, p); - return 0; - } - terminal_message(MSG_INFO, "%s: pgm command unavailable for this programmer type\n", - progname); - return -1; +static int cmd_pgm(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { + pgm->setpin(pgm, PIN_AVR_RESET, 0); + spi_mode = 0; + pgm->initialize(pgm, p); + return 0; } -static int cmd_verbose(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_verbose(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int nverb; char *endp; @@ -1110,9 +1050,7 @@ static int cmd_verbose(PROGRAMMER * pgm, struct avrpart * p, return 0; } -static int cmd_quell(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int cmd_quell(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int nquell; char *endp; @@ -1146,17 +1084,16 @@ static int cmd_quell(PROGRAMMER * pgm, struct avrpart * p, return 0; } -static int tokenize(char * s, char *** argv) -{ +static int tokenize(char * s, char ***argv) { int i, n, l, nargs; int len, slen; - char * buf; + char *buf; int bufsize; - char ** bufv; - char * bufp; - char * q, * r; - char * nbuf; - char ** av; + char **bufv; + char *bufp; + char *q, *r; + char *nbuf; + char **av; slen = strlen(s); @@ -1244,9 +1181,7 @@ static int tokenize(char * s, char *** argv) } -static int do_cmd(PROGRAMMER * pgm, struct avrpart * p, - int argc, char * argv[]) -{ +static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { int i; int hold; int len; @@ -1254,10 +1189,11 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p, len = strlen(argv[0]); hold = -1; for (i=0; i ")) != NULL) {