Improve help message in terminal and provide new command pgerase (#1113)

This commit is contained in:
Stefan Rueger 2022-10-11 14:40:37 +01:00 committed by GitHub
parent 44fe5bec2d
commit d3a3257cf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 341 additions and 336 deletions

View File

@ -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++;
}
if(nrd) {
report_progress(0, 1, "Reading");
if(nrd) {
// 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++;
}
if(nwr) {
report_progress(0, 1, "Writing");
if(nwr) {
// 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, };

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
@ -40,90 +41,59 @@
struct command {
char *name;
int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
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 <memory> [<addr> <len> | <addr> ... | <addr> | ...]" },
{ "read", cmd_dump, "alias for dump" },
{ "write", cmd_write, "%s <memory> <addr> [<data>[,] {<data>[,]} | <len> <data>[,] {<data>[,]} ...]" },
{ "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 <b1> <b2> <b3> <b4>" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 and Curiosity Nano only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 and Curiosity Nano only)" },
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "sck", cmd_sck, "set <SCK period> (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 <memory> [<addr> <len> | <addr> ... | <addr> | ...]" },
{ "read", cmd_dump, _fo(read_byte_cached), "alias for dump" },
{ "write", cmd_write, _fo(write_byte_cached), "write <memory> <addr> <data>[,] {<data>[,]}" },
{ "", cmd_write, _fo(write_byte_cached), "write <memory> <addr> <len> <data>[,] {<data>[,]} ..." },
{ "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 <memory> <addr>" },
{ "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 <b1> <b2> <b3> <b4>" },
{ "parms", cmd_parms, _fo(print_parms), "display adjustable parameters" },
{ "vtarg", cmd_vtarg, _fo(set_vtarget), "set <V[target]>" },
{ "varef", cmd_varef, _fo(set_varef), "set <V[aref]>" },
{ "fosc", cmd_fosc, _fo(set_fosc), "set <oscillator frequency>" },
{ "sck", cmd_sck, _fo(set_sck_period), "set <SCK period>" },
{ "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)))
@ -132,8 +102,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;
@ -170,8 +139,7 @@ static int nexttok(char * buf, char ** tok, char ** next)
}
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
{
static int hexdump_line(char *buffer, unsigned char *p, int n, int pad) {
char *hexdata = "0123456789abcdef";
char *b = buffer;
int i = 0;
@ -200,8 +168,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];
@ -222,8 +189,7 @@ 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];
@ -245,9 +211,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 <memory> <addr> <len>\n"
@ -280,9 +244,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;
}
}
@ -398,9 +362,7 @@ 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 <memory> <addr> <data>[,] {<data>[,]}\n"
@ -456,9 +418,9 @@ 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;
}
@ -731,32 +693,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;
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);
@ -805,9 +759,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);
@ -816,9 +768,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 <memory> <addr>\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");
@ -827,9 +823,7 @@ 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;
@ -856,9 +850,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);
@ -867,23 +859,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;
@ -898,11 +881,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);
@ -912,9 +890,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;
@ -937,11 +913,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);
@ -951,9 +922,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;
@ -969,11 +938,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);
@ -983,9 +947,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;
@ -1017,11 +979,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);
@ -1031,56 +988,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; i<NCMDS; i++) {
if(!*(void (**)(void)) ((char *) pgm + cmd[i].fnoff))
continue;
fprintf(stdout, " %-7s : ", cmd[i].name);
fprintf(stdout, cmd[i].desc, cmd[i].name);
fprintf(stdout, "\n");
}
fprintf(stdout, "\n"
"Note that flash and EEPROM type memories are normally read and written\n"
"using a cache and paged r/w access; the cache is synchronised on quit.\n"
"Use the 'part' command to display valid memory types for use with the\n"
"'dump' and 'write' commands.\n\n");
"Note that not all programmer derivatives support all commands. Flash and\n"
"EEPROM type memories are normally read and written using a cache via paged\n"
"read and write access; the cache is synchronised on quit. Use the part\n"
"command to display valid memory types for use with dump and write.\n\n");
return 0;
}
static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
if (pgm->setpin != NULL) {
static int cmd_spi(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
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_pgm(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
if (pgm->setpin != NULL) {
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;
}
terminal_message(MSG_INFO, "%s: pgm command unavailable for this programmer type\n",
progname);
return -1;
}
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;
@ -1109,9 +1049,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;
@ -1145,8 +1083,7 @@ 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, k, nargs, offset;
int len, slen;
char *buf;
@ -1243,9 +1180,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;
@ -1253,10 +1188,11 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
len = strlen(argv[0]);
hold = -1;
for (i=0; i<NCMDS; i++) {
if (strcasecmp(argv[0], cmd[i].name) == 0) {
if(!*(void (**)(void)) ((char *) pgm + cmd[i].fnoff))
continue;
if (len && strcasecmp(argv[0], cmd[i].name) == 0)
return cmd[i].func(pgm, p, argc, argv);
}
else if (strncasecmp(argv[0], cmd[i].name, len)==0) {
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]);
@ -1276,8 +1212,7 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
}
char * terminal_get_input(const char *prompt)
{
char *terminal_get_input(const char *prompt) {
#if defined(HAVE_LIBREADLINE) && !defined(WIN32)
char *input;
input = readline(prompt);
@ -1299,8 +1234,7 @@ char * terminal_get_input(const char *prompt)
}
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
{
int terminal_mode(PROGRAMMER *pgm, AVRPART *p) {
char *cmdbuf;
char *q;
int rc;