mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-15 10:11:07 +00:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1c7bc8c83 | ||
|
|
d05271766a | ||
|
|
92059f41a3 | ||
|
|
ed14409bf9 | ||
|
|
ea652e7b78 | ||
|
|
3bd2da1766 | ||
|
|
d1eb58dbde | ||
|
|
ede8a48d52 | ||
|
|
6acb859507 | ||
|
|
698769dcca | ||
|
|
1188a0313b | ||
|
|
ae39cd7c57 | ||
|
|
77bc532fd2 | ||
|
|
ce6e943739 | ||
|
|
9560dfe881 | ||
|
|
61c60d3b5b | ||
|
|
f2a77c44f0 | ||
|
|
3c507aee9e | ||
|
|
964a170f39 | ||
|
|
d2e0c4eab3 | ||
|
|
c19d7efe7a | ||
|
|
e603e71c45 | ||
|
|
e8d5bce16f | ||
|
|
b8af1211d8 | ||
|
|
96b8604351 | ||
|
|
0d61a7e3f7 | ||
|
|
b4a23dddc0 | ||
|
|
ca01d072ab | ||
|
|
f6a14f4c25 | ||
|
|
f3a6fc6ab0 | ||
|
|
4facd0e3d9 | ||
|
|
17422985b6 | ||
|
|
6ff0c4a47e | ||
|
|
ede6981133 | ||
|
|
3e70d4566f | ||
|
|
4446ed3a7d | ||
|
|
e0026ff0fd | ||
|
|
1fa0b23de1 | ||
|
|
229481f5ac | ||
|
|
0b1f5b8a0d | ||
|
|
25d2b42f87 | ||
|
|
4e10f943ff | ||
|
|
16d49775d0 | ||
|
|
29658b756a | ||
|
|
39dbaf4903 | ||
|
|
9baed74e69 | ||
|
|
8c70fa36ec | ||
|
|
83cb042b9e | ||
|
|
2528839c95 | ||
|
|
57c7412a3c | ||
|
|
b54f273812 | ||
|
|
56823c7aa5 | ||
|
|
d6e5083b97 | ||
|
|
7d5184da75 | ||
|
|
62f2e06711 | ||
|
|
bd11e34965 | ||
|
|
e358fd203a | ||
|
|
5fa160a365 | ||
|
|
8513530063 | ||
|
|
6c3cb9fbb2 | ||
|
|
d2317147db | ||
|
|
20bf291163 | ||
|
|
a58f2c8d66 | ||
|
|
4996510f4c | ||
|
|
c3412f1f57 | ||
|
|
dc21830241 | ||
|
|
191a5a4430 | ||
|
|
ee87b080c3 | ||
|
|
5bd3b081eb | ||
|
|
6fba5faaf5 | ||
|
|
5d6dace3c3 | ||
|
|
200283a902 | ||
|
|
ea977f6062 | ||
|
|
a13d87de00 | ||
|
|
5a74a905b4 | ||
|
|
eb551b1d0d | ||
|
|
f0c2dcf820 | ||
|
|
8da3ff76e4 | ||
|
|
8f15af9679 |
@@ -5,5 +5,6 @@ AVRDUDE was written by:
|
||||
Contributors:
|
||||
|
||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Eric Weddington <eric@umginc.net>
|
||||
Eric Weddington <eric@ecentral.com>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
|
||||
@@ -1,3 +1,388 @@
|
||||
2003-09-06 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* AVRDUDE 4.2.0 has been released (cvs release tag is "release_4_2_0").
|
||||
|
||||
2003-09-06 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* NEWS: Update for 4.2.0 release. Add note about read/write of fuses
|
||||
support for avr910.
|
||||
* configure.ac (AC_INIT): Set version to 4.2.0.
|
||||
|
||||
2003-09-05 Theodore A. Roth <troth@openavr.org>
|
||||
[Contributed by Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>]
|
||||
|
||||
* avr.c (avr_read_byte): If pgm->read_byte method fails, retry with
|
||||
avr_read_byte_default.
|
||||
* avr.c (avr_write_byte): If pgm->write_byte method fails, retry with
|
||||
avr_write_byte_default.
|
||||
* avr910.c (avr910_cmd): Implement using universal command.
|
||||
|
||||
2003-09-04 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile.am: Change AM_CPPFLAGS to avrdude_CPPFLAGS.
|
||||
Define avrdude_CFLAGS.
|
||||
* configure.ac: Set ENABLE_WARNINGS to "-Wall" if using gcc.
|
||||
|
||||
2003-09-02 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* doc/avrdude.texi: Add note about privileges needed to load
|
||||
the giveio driver for Windows.
|
||||
|
||||
2003-08-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1:
|
||||
* main.c:
|
||||
Perform an auto erase before programming if the flash memory is
|
||||
anywhere specified to be written by any of the -U requests.
|
||||
|
||||
To remain backward compatible with previous versions, disable this
|
||||
feature if any of the old-style memory specification operations are
|
||||
specified (-i, -o).
|
||||
|
||||
Implement the -D option to explicitly disable the auto erase default.
|
||||
|
||||
Deprecate the old-style memory specification options (-f, -i, -I, -m,
|
||||
and -o) in favor of the new -U option which allows one to operate on
|
||||
multiple memories on a single command line.
|
||||
|
||||
2003-08-28 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* avr910.c:
|
||||
* fileio.c:
|
||||
* main.c:
|
||||
* stk500.c:
|
||||
More code cleanup to remove warnings.
|
||||
|
||||
2003-08-27 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* main.c (update_progress_no_tty): Properly terminate progress. Also
|
||||
fixes stk500 problem where number of bytes written is less than a page.
|
||||
|
||||
2003-08-27 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.spec.in: Fix broken rpmbuild on RedHat-9.
|
||||
|
||||
2003-08-25 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* fileio.c:
|
||||
* main.c:
|
||||
* ppiwin.c:
|
||||
* ser_posix.c:
|
||||
* stk500.c:
|
||||
Minor code cleanup to remove warnings.
|
||||
|
||||
2003-08-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1:
|
||||
* main.c:
|
||||
|
||||
Introduce a new option, -U, for performing memory operions.
|
||||
Its argument is a 4 field string (fields seperated by colons)
|
||||
which indicate what memory type to operate on, what operation
|
||||
to perform is (read, write, or verify), the filename to read
|
||||
from, write to, or verify against, and an optional file format
|
||||
field. Multple -U options can be specified to operate on more
|
||||
than one memory at a time with a single invocation. For
|
||||
example, to update both the flash and the eeprom at the same
|
||||
time one can now specify the following:
|
||||
|
||||
avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
|
||||
|
||||
2003-08-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* ppiwin.c:
|
||||
Timing related fixes for the Windows platform. Several folks have
|
||||
reported that this patch fixes verify errors on the Windows platform
|
||||
that are apparently timing related. Submitted by: Alex Shepherd
|
||||
<ashepherd@wave.co.nz>, who indicates that this patch was based on
|
||||
code from the UISP project.
|
||||
|
||||
2003-08-01 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.1: Document the -q option.
|
||||
* doc/avrdude.texi: Document the -q option.
|
||||
Fix some typos left over from pasting in man output.
|
||||
|
||||
2003-07-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Add elapsed time information to the new progress bar.
|
||||
|
||||
2003-07-29 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr.c:
|
||||
* avr.h:
|
||||
* avr910.c:
|
||||
* main.c:
|
||||
* stk500.c:
|
||||
New progress reporting implementation.
|
||||
|
||||
2003-07-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1:
|
||||
* doc/avrdude.texi:
|
||||
* pgm.c:
|
||||
* pgm.h:
|
||||
* stk500.c:
|
||||
* stk500_private.h:
|
||||
* term.c: Add support for displaying and setting the various
|
||||
operational parameters of the STK500 (Vtarget, Varef, clock).
|
||||
|
||||
2003/07/22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.in:
|
||||
Add 'picoweb' programming cable programmer.
|
||||
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
|
||||
|
||||
2003-06-18 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.in:
|
||||
Add the 'sp12' (Steve Bolt's) programmer.
|
||||
Submitted by Larry Barello <larryba@barello.net>.
|
||||
|
||||
2003-06-17 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.in:
|
||||
Properly identify the "ALF" programmer.
|
||||
|
||||
Extend ATmega8 calibration memory to support all 4 calibration bytes.
|
||||
Savannah bug #3835. Submitted by Francisco T. A. Silva
|
||||
<ftas@geodigitus.com.br>.
|
||||
|
||||
Add a few AVR910 programmer device codes. Savannah bug #3569 - sorry
|
||||
I can't tell who submitted this to give proper credit.
|
||||
|
||||
Add support for the ATtiny12. Submitted by Pontifex <pontifex@isys.ca>
|
||||
|
||||
2003-05-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c:
|
||||
* avr.h:
|
||||
* fileio.c:
|
||||
Optimize flash memory handling a little bit by ignoring 0xff data that
|
||||
resides above the last non-0xff data value in the address space. Only
|
||||
do this for flash memory since writing a 0xff to flash is a no-op.
|
||||
This has the affect of creating smaller output files when dumping
|
||||
memory contents from flash if the program in flash does not consume
|
||||
the whole memory space. It also results in shorter programming times
|
||||
when avrdude is asked to load a file into flash that has lots of 0xff
|
||||
filled data past the last non-0xff data value.
|
||||
|
||||
2003-05-13 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr910.c (avr910_paged_write_flash): Add code to send the 'm'
|
||||
command ("issue page write" cmd) for each page.
|
||||
|
||||
2003-05-13 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.conf.in: Add pagel and bs2 entries for at90s1200 device.
|
||||
|
||||
2003-05-13 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* doc/TODO: Add note about avr910 device codes.
|
||||
|
||||
2003-05-04 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* configure.ac: Check for ncurses library (since it can be a
|
||||
replacement for termcap).
|
||||
|
||||
2003-05-02 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.conf.in: Add avr decodes for devices known in avr910
|
||||
firmware version 2.3.
|
||||
Add missing stk500 devocde for 2343.
|
||||
|
||||
2003-04-23 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* fileio.c: Fix for bug #3293. Set correct open mode for raw format
|
||||
for Windows.
|
||||
|
||||
2003-04-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1:
|
||||
* fileio.c:
|
||||
* fileio.h:
|
||||
* main.c:
|
||||
Implement and "immediate mode" for file input - this allows
|
||||
one to specify byte values on the command line instead of via
|
||||
a file. This can be good for specifying fuse bytes and
|
||||
eliminates the need to create single-byte files or using
|
||||
interactive terminal mode for these single-byte memories.
|
||||
Requested by several folks on the mailing list.
|
||||
|
||||
2003-04-18 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* configure.ac: Add cvs suffix back to version.
|
||||
* doc/TODO: Add a few items.
|
||||
|
||||
2003-04-18 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* AVRDUDE 4.1.0 has been released (cvs release tag is "release_4_1_0").
|
||||
|
||||
2003-04-17 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* configure.ac: Set version to 4.1.0.
|
||||
* doc/avrdude.texi: Add note about avr910 programmer type.
|
||||
|
||||
2003-04-17 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* NEWS: Replace TBD with new release version.
|
||||
|
||||
2003-04-17 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* avrdude.conf.in: Change name of pony programmer to pony-stk200
|
||||
to better describe the hardware (PonyProg is software that works
|
||||
with various hardware).
|
||||
|
||||
2003-04-16 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* avrdude.conf.in: Add support for ATtiny26
|
||||
Submitted by Artur Lipowski <LAL@pro.onet.pl>
|
||||
* NEWS: List new devices supported: ATtiny26
|
||||
|
||||
2003-04-16 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* avrdude.conf.in: Add support for ATmega8535
|
||||
Submitted by Alexander Peter <apeter@gmx.de>
|
||||
* NEWS: List new devices supported: ATmega8535
|
||||
|
||||
2003-04-09 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr910.c: Reading a 16 bit word in paged load needs to swap the
|
||||
bytes since the 'R' command returns MSB first and the internal buffer
|
||||
stores LSB first.
|
||||
|
||||
2003-04-07 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* stk500.c: Don't print out read/write byte progress unless the verbose
|
||||
option is given.
|
||||
|
||||
2003-04-05 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr910.c: Re-add the avr910 byte read/write methods which were
|
||||
removed in my previous patch. Terminal mode read/writes are broken
|
||||
without those methods. D'oh!
|
||||
|
||||
2003-04-05 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr910.c: Refactor to allow probing for auto addr increment. If auto
|
||||
incr supported by programmer hw, don't send addr for every byte.
|
||||
|
||||
2003-04-03 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* confwin.c: Fix bug that allows garbage for non-existent user
|
||||
config filename on Windows.
|
||||
|
||||
2003-03-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.in:
|
||||
Add the ATmega32 part. This part definition was contributed by:
|
||||
Daniel Williamson <dannyw@maconmgt.co.uk> and
|
||||
Ruwan Jayanetti <rjayanetti@sri.crossvue.com>
|
||||
The resulting part definition used was actually somewhat of a merge of
|
||||
the two submitted definitions.
|
||||
|
||||
2003-03-24 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* NEWS: Add note about avr910 support.
|
||||
|
||||
2003-03-23 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr.c (avr_write): Add call to pgm->write_setup() before the write
|
||||
loop.
|
||||
* avr910.c: Change all show_func_info() calls to no_show_func_info().
|
||||
Add read/write to/from flash/eeprom memory functionality.
|
||||
* pgm.c: Initialize pgm->write_setup.
|
||||
* pgm.h: Add write_setup field to PROGRAMMER structure.
|
||||
* ser_posix.c: Remove unneeded cast in verbosity code.
|
||||
|
||||
2003-03-23 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* ser_posix.c: Limit verbose output to 2 chars.
|
||||
|
||||
2003-03-23 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* ser_posix.c: Add verbose level > 3 output for send and recv functions.
|
||||
|
||||
2003-03-23 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr.c: Add avr_read_byte_default().
|
||||
Have avr_read_byte() call pgm->read_byte() or avr_read_byte_default().
|
||||
Add avr_write_byte_default().
|
||||
Have avr_write_byte() call pgm->write_byte or avr_write_byte_default().
|
||||
* pgm.c: Initialize pgm->write_byte and pgm->read_byte.
|
||||
* pgm.h: Add write_byte and read_byte fields to struct programmer_t.
|
||||
|
||||
2003-03-17 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.conf.in: Fix typo for devicecode deprecation comment.
|
||||
|
||||
2003-03-17 Eric B. Weddington <eric@ecentral.com>
|
||||
|
||||
* avrdude.conf.in: Add Bascom SAMPLE programmer.
|
||||
Submitted by Larry Barello <larryba@barrello.net>
|
||||
|
||||
2003-03-16 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr.c (avr_read): Use pgm->read_sig_bytes to read signature bytes if
|
||||
available.
|
||||
* avr910.c (avr910_vfy_cmd_sent): New function.
|
||||
(avr910_chip_erase): Add support for chip erase.
|
||||
(avr910_enter_prog_mode): New function.
|
||||
(avr910_leave_prog_mode): New function.
|
||||
(avr910_initialize): Add code to select device type and enter prog mode.
|
||||
(avr910_close): Leave programming mode before closing serial port.
|
||||
(avr910_read_sig_bytes): New function.
|
||||
(avr910_initpgm): Add avr910_read_sig_bytes method to pgm initializer.
|
||||
* avrdude.conf.in: Add note about deprecating devicecode.
|
||||
Change all occurences of devicecode to stk500_devcode.
|
||||
Add avr910_devcode to a few parts for testing.
|
||||
* avrpart.h (struct avrpart): Change devicecode field to stk500_devcode.
|
||||
(struct avrpart): Add avr910_devcode field.
|
||||
* config_gram.y: Add K_STK500_DEVCODE and K_AVR910_DEVCODE tokens.
|
||||
Generate an error if devicecode is found in the config file.
|
||||
Handle parsing of avr910_devcode and stk500_devcode.
|
||||
* lexer.l: Handle parsing of avr910_devcode and stk500_devcode.
|
||||
* pgm.c: Initialize pgm->read_sig_bytes field.
|
||||
* pgm.h: Add pgm->read_sig_bytes field.
|
||||
* stk500.c: Use stk500_devcode instead of devicecode.
|
||||
|
||||
2003-03-16 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.conf.in: Add avr910 and pavr programmers.
|
||||
* config_gram.y: Add parsing of avr910 programmer.
|
||||
* lexer.l: Add avr910 token.
|
||||
* avr910.c: [this is still work in progress]
|
||||
Add some debug output.
|
||||
Add probe for programmer presense.
|
||||
* main.c: Set port to default_serial if programmer type is avr910.
|
||||
|
||||
2003-03-13 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* ser_posix.c, ser_win32.c, serial.h:
|
||||
Change baud from int to long to avoid a 16-bit int overflow.
|
||||
|
||||
2003-03-12 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile.am (avrdude_SOURCES): Add avr910.[ch], serial.h and
|
||||
ser_posix.c files.
|
||||
* avr910.c: New file (stubs for avr910 serial programmer).
|
||||
* avr910.h: New file.
|
||||
* ser_posix.c: New file.
|
||||
* ser_win32.c: New file (just stubs for now).
|
||||
* serial.h: New file.
|
||||
* stk500.c: Move all the code for accessing the posix serial ports
|
||||
into ser_posix. This will make a native win32 port easier and allows
|
||||
the avr910 programmer to share the serial code.
|
||||
|
||||
2003-03-12 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* configure.ac (AC_INIT): Set version to 4.0.0cvs since we're done
|
||||
with 4.0.0 release.
|
||||
|
||||
2003-03-12
|
||||
|
||||
* AVRDUDE 4.0.0 has been released (cvs release tag is "release_4_0_0").
|
||||
|
||||
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile.am: Add CLEANFILES to remove all files from a make.
|
||||
@@ -19,7 +404,7 @@
|
||||
* NEWS: Moved contents of CHANGELOG file here.
|
||||
* README: Add note pointing to savannah site.
|
||||
|
||||
2003-03-11 Eric Weddington <eric@umginc.net>
|
||||
2003-03-11 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* doc/avrdude.texi:
|
||||
Add Install and Documentation sections for Windows. Fix typo.
|
||||
@@ -55,7 +440,7 @@
|
||||
Export ${AUTOCONF} so automake will find it by whatever name it will be
|
||||
called today.
|
||||
|
||||
2003-03-06 Eric Weddington <eric@umginc.net>
|
||||
2003-03-06 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* doc/avrdude.texi:
|
||||
Add notes about ability to list parts and list programmers in the
|
||||
@@ -140,7 +525,7 @@
|
||||
Print out a list of valid parts for '-p ?' and a list of valid
|
||||
programmers for '-c ?'.
|
||||
|
||||
2003-03-04 Eric Weddington <eric@umginc.net>
|
||||
2003-03-04 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* doc/avrdude.texi: Minor Windows doc corrections.
|
||||
|
||||
@@ -227,7 +612,7 @@
|
||||
* avrdude.conf.in, avrdude.conf.sample:
|
||||
Renamed avrdude.conf.sample to avrdude.conf.in.
|
||||
|
||||
2003-02-25 Eric Weddington <eric@umginc.net>
|
||||
2003-02-25 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* ppiwin.c: CRs again.
|
||||
|
||||
@@ -240,7 +625,7 @@
|
||||
* avrdude.1: Atmel has rearranged their web site, so now the AVR
|
||||
docs have been moved to a more logically sounding URL.
|
||||
|
||||
2003-02-24 Eric Weddington <eric@umginc.net>
|
||||
2003-02-24 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* Makefile.am, main.c: Integrate Windows search of config files.
|
||||
|
||||
@@ -303,7 +688,7 @@
|
||||
config file, thus, avrdude is not very useful without the config file,
|
||||
and thus, having a programmer compiled-in offers little or no benefit.
|
||||
|
||||
2003-02-21 Eric Weddington <eric@umginc.net>
|
||||
2003-02-21 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* main.c: Change usage text to be verbose.
|
||||
|
||||
@@ -331,7 +716,7 @@
|
||||
indicate that /RESET should be pulsed, while older parts say to pulse
|
||||
SCK.
|
||||
|
||||
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||
2003-02-20 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* main.c, par.c:
|
||||
Make verbose global. Make debug code in par_cmd() based on verbose=2.
|
||||
@@ -356,7 +741,7 @@
|
||||
Defaults for 'serial' and 'parallel' are 'yes' unless specified
|
||||
otherwise.
|
||||
|
||||
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||
2003-02-20 Eric Weddington <eric@ecentral.com>
|
||||
|
||||
* Makefile.am, ppiwin.c: Get rid of CRs.
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@ DIST_SUBDIRS = doc windows
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
@@ -48,6 +50,8 @@ avrdude_SOURCES = \
|
||||
lexer.l \
|
||||
avr.c \
|
||||
avr.h \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrpart.h \
|
||||
config.c \
|
||||
config.h \
|
||||
@@ -67,6 +71,9 @@ avrdude_SOURCES = \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
serial.h \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
stk500.c \
|
||||
stk500.h \
|
||||
stk500_private.h \
|
||||
|
||||
57
avrdude/NEWS
57
avrdude/NEWS
@@ -6,18 +6,65 @@ Approximate change log for AVRDUDE by version.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Version 4.2.0:
|
||||
|
||||
* Add basic support for reading and writing fuses via SPI with avr910
|
||||
programmers. Submitted by
|
||||
Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>.
|
||||
|
||||
* Perform an auto erase before programming if the flash memory is
|
||||
anywhere specified to be written by any of the -U requests. Old
|
||||
style memory specification options (-f, -i, -I, -m, and -o) are
|
||||
deprecated in favor of the new -U options. Auto erase is disabled
|
||||
if any of the old-style options (specifically -i and -o) are
|
||||
specified.
|
||||
|
||||
* Add new -U option for specifying programming operations - allows
|
||||
multiple memory operations on a single command line.
|
||||
|
||||
* New progress reporting, looks nicer and is nicer to wrapper
|
||||
environments such as emacs.
|
||||
|
||||
* Fix long-standing timing (verify) problems on Windows platform.
|
||||
Submitted by Alex Shepherd <ashepherd@wave.co.nz>.
|
||||
|
||||
* Add new file format option - 'm' for "immediate mode." In this
|
||||
case, the filename argument of the -o, -i, or -U options is
|
||||
treated as the data for uploading - useful for specifying fuse
|
||||
bits without having to create a single-byte file for uploading.
|
||||
|
||||
* Add support for displaying and setting the various STK500 operational
|
||||
parameters (Vtarget, Varef, Master clock).
|
||||
|
||||
* Add 'picoweb' programming cable programmer.
|
||||
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
|
||||
|
||||
* Add support for the sp12 programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
|
||||
Version 4.1.0
|
||||
|
||||
* Add support for the Bascom SAMPLE programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
* Add support for avr910 type programmers (mcu00100, pavr avr910, etc).
|
||||
|
||||
* Support new devices: ATmega8535, ATtiny26
|
||||
|
||||
|
||||
Version 4.0.0
|
||||
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>.
|
||||
|
||||
* Now support Windows - added by "E. Weddington" <eric@umginc.net>
|
||||
* Now support Windows - added by "Eric B. Weddington" <eric@ecentral.com>.
|
||||
|
||||
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
||||
<troth@openavr.org>
|
||||
<troth@openavr.org>.
|
||||
|
||||
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||
<tsar@kemford.com>
|
||||
<tsar@kemford.com>.
|
||||
|
||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||
'bs2' keywords to the config file for this purpose.
|
||||
@@ -233,4 +280,4 @@ Version 1.3.0 :
|
||||
|
||||
Version 1.2.2 :
|
||||
|
||||
* Initial public release
|
||||
* Initial public release.
|
||||
|
||||
140
avrdude/avr.c
140
avrdude/avr.c
@@ -287,11 +287,8 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read a byte of data from the indicated memory region
|
||||
*/
|
||||
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
@@ -340,6 +337,53 @@ int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read a byte of data from the indicated memory region
|
||||
*/
|
||||
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (pgm->read_byte) {
|
||||
rc = pgm->read_byte(pgm, p, mem, addr, value);
|
||||
if (rc == 0) {
|
||||
return rc;
|
||||
}
|
||||
/* read_byte() method failed, try again with default. */
|
||||
}
|
||||
|
||||
return avr_read_byte_default(pgm, p, mem, addr, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of "interesting" bytes in a memory buffer,
|
||||
* "interesting" being defined as up to the last non-0xff data
|
||||
* value. This is useful for determining where to stop when dealing
|
||||
* with "flash" memory, since writing 0xff to flash is typically a
|
||||
* no-op. Always return an even number since flash is word addressed.
|
||||
*/
|
||||
int avr_mem_hiaddr(AVRMEM * mem)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
/* return the highest non-0xff address regardless of how much
|
||||
memory was read */
|
||||
for (i=mem->size-1; i>0; i--) {
|
||||
if (mem->buf[i] != 0xff) {
|
||||
n = i+1;
|
||||
if (n & 0x01)
|
||||
return n+1;
|
||||
else
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the entirety of the specified memory type into the
|
||||
* corresponding buffer of the avrpart pointed to by 'p'. If size =
|
||||
@@ -355,7 +399,6 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
unsigned char * buf;
|
||||
AVRMEM * mem;
|
||||
int rc;
|
||||
int printed;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
@@ -369,6 +412,11 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
size = mem->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with all 0xff
|
||||
*/
|
||||
memset(buf, 0xff, size);
|
||||
|
||||
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
|
||||
if (pgm->paged_load != NULL) {
|
||||
/*
|
||||
@@ -377,16 +425,27 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
* instead
|
||||
*/
|
||||
if (mem->paged) {
|
||||
return pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
else {
|
||||
return pgm->paged_load(pgm, p, mem, pgm->page_size, size);
|
||||
rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
if (strcasecmp(mem->desc, "flash") == 0)
|
||||
return avr_mem_hiaddr(mem);
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printed = 0;
|
||||
if (strcmp(mem->desc, "signature") == 0) {
|
||||
if (pgm->read_sig_bytes) {
|
||||
return pgm->read_sig_bytes(pgm, p, mem);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
|
||||
@@ -399,19 +458,13 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
return -2;
|
||||
}
|
||||
buf[i] = rbyte;
|
||||
if (verbose) {
|
||||
if ((i % 16 == 0)||(i == (size-1))) {
|
||||
printed = 1;
|
||||
fprintf(stderr, "\r \r%6lu", i);
|
||||
}
|
||||
}
|
||||
report_progress(i, size, NULL);
|
||||
}
|
||||
|
||||
if (printed) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
return i;
|
||||
if (strcasecmp(mem->desc, "flash") == 0)
|
||||
return avr_mem_hiaddr(mem);
|
||||
else
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -460,10 +513,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write a byte of data at the specified address
|
||||
*/
|
||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
@@ -648,6 +698,26 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write a byte of data at the specified address
|
||||
*/
|
||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (pgm->write_byte) {
|
||||
rc = pgm->write_byte(pgm, p, mem, addr, data);
|
||||
if (rc == 0) {
|
||||
return rc;
|
||||
}
|
||||
/* write_byte() method failed, try again with default. */
|
||||
}
|
||||
|
||||
return avr_write_byte_default(pgm, p, mem, addr, data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write the whole memory region of the specified memory from the
|
||||
* corresponding buffer of the avrpart pointed to by 'p'. Write up to
|
||||
@@ -666,7 +736,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
unsigned char data;
|
||||
int werror;
|
||||
AVRMEM * m;
|
||||
int printed;
|
||||
|
||||
m = avr_locate_mem(p, memtype);
|
||||
if (m == NULL) {
|
||||
@@ -677,7 +746,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
|
||||
printed = 0;
|
||||
werror = 0;
|
||||
|
||||
wsize = m->size;
|
||||
@@ -704,14 +772,14 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
}
|
||||
}
|
||||
|
||||
if (pgm->write_setup) {
|
||||
pgm->write_setup(pgm, p, m);
|
||||
}
|
||||
|
||||
for (i=0; i<wsize; i++) {
|
||||
data = m->buf[i];
|
||||
if (verbose) {
|
||||
if ((i % 16 == 0)||(i == (wsize-1))) {
|
||||
fprintf(stderr, "\r \r%6lu", i);
|
||||
printed = 1;
|
||||
}
|
||||
}
|
||||
report_progress(i, wsize, NULL);
|
||||
|
||||
rc = avr_write_byte(pgm, p, m, i, data);
|
||||
if (rc) {
|
||||
fprintf(stderr, " ***failed; ");
|
||||
@@ -749,10 +817,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
pgm->err_led(pgm, ON);
|
||||
}
|
||||
}
|
||||
|
||||
if (printed)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -765,6 +829,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc;
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, p, "signature", 0, 0);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr,
|
||||
@@ -772,6 +837,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||
progname, p->desc, rc);
|
||||
return -1;
|
||||
}
|
||||
report_progress (1,1,NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -84,4 +84,8 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
|
||||
|
||||
int avr_mem_hiaddr(AVRMEM * mem);
|
||||
|
||||
extern void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#endif
|
||||
|
||||
718
avrdude/avr910.c
Normal file
718
avrdude/avr910.c
Normal file
@@ -0,0 +1,718 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Atmel Low Cost Serial programmers which adher to the
|
||||
* protocol described in application note avr910.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "avr910.h"
|
||||
#include "serial.h"
|
||||
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
static char has_auto_incr_addr;
|
||||
|
||||
/* These two defines are only for debugging. Will remove them once it starts
|
||||
working. */
|
||||
|
||||
#define show_func_info() \
|
||||
fprintf(stderr, "%s: line %d: called %s()\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define no_show_func_info()
|
||||
|
||||
|
||||
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return serial_send(pgm->fd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return serial_recv(pgm->fd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
static int avr910_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return serial_drain(pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
static void avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
||||
{
|
||||
char c;
|
||||
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (c != '\r') {
|
||||
fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
|
||||
progname, errmsg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int avr910_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_err_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_pgm_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_vfy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
*/
|
||||
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
avr910_send(pgm, "e", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "chip erase");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_enter_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_send(pgm, "P", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "enter prog mode");
|
||||
}
|
||||
|
||||
|
||||
static void avr910_leave_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_send(pgm, "L", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "leave prog mode");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
static void avr910_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove power from the AVR processor
|
||||
*/
|
||||
static void avr910_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
char id[8];
|
||||
char sw[2];
|
||||
char hw[2];
|
||||
char buf[10];
|
||||
char type;
|
||||
unsigned char c;
|
||||
int dev_supported = 0;
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
/* Get the programmer identifier. Programmer returns exactly 7 chars
|
||||
_without_ the null.*/
|
||||
|
||||
avr910_send(pgm, "S", 1);
|
||||
memset (id, 0, sizeof(id));
|
||||
avr910_recv(pgm, id, sizeof(id)-1);
|
||||
|
||||
/* Get the HW and SW versions to see if the programmer is present. */
|
||||
|
||||
avr910_send(pgm, "V", 1);
|
||||
avr910_recv(pgm, sw, sizeof(sw));
|
||||
|
||||
avr910_send(pgm, "v", 1);
|
||||
avr910_recv(pgm, hw, sizeof(hw));
|
||||
|
||||
/* Get the programmer type (serial or parallel). Expect serial. */
|
||||
|
||||
avr910_send(pgm, "p", 1);
|
||||
avr910_recv(pgm, &type, 1);
|
||||
|
||||
fprintf(stderr, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
|
||||
fprintf(stderr, " Software Version = %c.%c; ", sw[0], sw[1]);
|
||||
fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);
|
||||
|
||||
/* See if programmer supports autoincrement of address. */
|
||||
|
||||
avr910_send(pgm, "a", 1);
|
||||
avr910_recv(pgm, &has_auto_incr_addr, 1);
|
||||
if (has_auto_incr_addr == 'Y')
|
||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||
|
||||
/* Get list of devices that the programmer supports. */
|
||||
|
||||
avr910_send(pgm, "t", 1);
|
||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||
while (1) {
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (c == 0)
|
||||
break;
|
||||
fprintf(stderr, " Device code: 0x%02x\n", c);
|
||||
|
||||
/* FIXME: Need to lookup devcode and report the device. */
|
||||
|
||||
if (p->avr910_devcode == c)
|
||||
dev_supported = 1;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
if (!dev_supported) {
|
||||
fprintf(stderr,
|
||||
"%s: error: selected device is not supported by programmer: %s\n",
|
||||
progname, p->id);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Tell the programmer which part we selected. */
|
||||
|
||||
buf[0] = 'T';
|
||||
buf[1] = p->avr910_devcode;
|
||||
|
||||
avr910_send(pgm, buf, 2);
|
||||
avr910_vfy_cmd_sent(pgm, "select device");
|
||||
|
||||
avr910_enter_prog_mode(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_save(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_restore(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
unsigned char buf[5];
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
/* FIXME: Insert version check here */
|
||||
|
||||
buf[0] = '.'; /* New Universal Command */
|
||||
buf[1] = cmd[0];
|
||||
buf[2] = cmd[1];
|
||||
buf[3] = cmd[2];
|
||||
buf[4] = cmd[3];
|
||||
|
||||
avr910_send (pgm, buf, 5);
|
||||
avr910_recv (pgm, buf, 2);
|
||||
|
||||
res[0] = 0x00; /* Dummy value */
|
||||
res[1] = cmd[0];
|
||||
res[2] = cmd[1];
|
||||
res[3] = buf[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
pgm->fd = serial_open(port, 19200);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
avr910_drain (pgm, 0);
|
||||
}
|
||||
|
||||
static void avr910_close(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
avr910_leave_prog_mode(pgm);
|
||||
|
||||
serial_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
||||
{
|
||||
unsigned char cmd[3];
|
||||
|
||||
cmd[0] = 'A';
|
||||
cmd[1] = (addr >> 8) & 0xff;
|
||||
cmd[2] = addr & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "set addr");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For some reason, if we don't do this when writing to flash, the first byte
|
||||
* of flash is not programmed. I susect that the board got out of sync after
|
||||
* the erase and sending another command gets us back in sync. -TRoth
|
||||
*/
|
||||
static void avr910_write_setup(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
avr910_send(pgm, "y", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "clear LED");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
if (addr & 0x01) {
|
||||
cmd[0] = 'C'; /* Write Program Mem high byte */
|
||||
}
|
||||
else {
|
||||
cmd[0] = 'c';
|
||||
}
|
||||
|
||||
addr >>= 1;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[0] = 'D';
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[1] = value;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
static int cached = 0;
|
||||
static unsigned char cvalue;
|
||||
static unsigned long caddr;
|
||||
|
||||
if (cached && ((caddr + 1) == addr)) {
|
||||
*value = cvalue;
|
||||
cached = 0;
|
||||
}
|
||||
else {
|
||||
unsigned char buf[2];
|
||||
|
||||
avr910_set_addr(pgm, addr >> 1);
|
||||
|
||||
avr910_send(pgm, "R", 1);
|
||||
|
||||
/* Read back the program mem word (MSB first) */
|
||||
avr910_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[1];
|
||||
cached = 1;
|
||||
cvalue = buf[0];
|
||||
caddr = addr;
|
||||
}
|
||||
else {
|
||||
*value = buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
avr910_set_addr(pgm, addr);
|
||||
avr910_send(pgm, "d", 1);
|
||||
avr910_recv(pgm, value, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return avr910_read_byte_flash(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char cmd[] = {'c', 'C'};
|
||||
unsigned char buf[2];
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
unsigned int page_addr;
|
||||
int page_bytes = page_size;
|
||||
int page_wr_cmd_pending = 0;
|
||||
|
||||
avr910_write_setup(pgm, p, m);
|
||||
|
||||
page_addr = addr;
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
|
||||
while (addr < max_addr) {
|
||||
page_wr_cmd_pending = 1;
|
||||
buf[0] = cmd[addr & 0x01];
|
||||
buf[1] = m->buf[addr];
|
||||
avr910_send(pgm, buf, sizeof(buf));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
addr++;
|
||||
page_bytes--;
|
||||
|
||||
if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
}
|
||||
else if (m->paged && (page_bytes == 0)) {
|
||||
/* Send the "Issue Page Write" if we have sent a whole page. */
|
||||
|
||||
avr910_set_addr(pgm, page_addr>>1);
|
||||
avr910_send(pgm, "m", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "flush page");
|
||||
|
||||
/* Set page address for next page. */
|
||||
|
||||
page_addr = addr;
|
||||
page_bytes = page_size;
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
/* If we didn't send the page wr cmd after the last byte written in the
|
||||
loop, send it now. */
|
||||
|
||||
if (page_wr_cmd_pending) {
|
||||
avr910_set_addr(pgm, page_addr>>1);
|
||||
avr910_send(pgm, "m", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "flush final page");
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
||||
AVRMEM * m, int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
cmd[0] = 'D';
|
||||
|
||||
while (addr < max_addr) {
|
||||
cmd[1] = m->buf[addr];
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
addr++;
|
||||
|
||||
if (has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char cmd;
|
||||
int rd_size;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr;
|
||||
unsigned char buf[2];
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
cmd = 'R';
|
||||
rd_size = 2; /* read two bytes per addr */
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd = 'd';
|
||||
rd_size = 1;
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
}
|
||||
|
||||
max_addr = n_bytes/rd_size;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
while (addr < max_addr) {
|
||||
avr910_send(pgm, &cmd, 1);
|
||||
if (cmd == 'R') {
|
||||
/* The 'R' command returns two bytes, MSB first, we need to put the data
|
||||
into the memory buffer LSB first. */
|
||||
avr910_recv(pgm, buf, 2);
|
||||
m->buf[addr*2] = buf[1]; /* LSB */
|
||||
m->buf[addr*2+1] = buf[0]; /* MSB */
|
||||
}
|
||||
else {
|
||||
avr910_recv(pgm, &m->buf[addr], 1);
|
||||
}
|
||||
|
||||
addr++;
|
||||
|
||||
if (has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
return addr * rd_size;
|
||||
}
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
avr910_send(pgm, "s", 1);
|
||||
avr910_recv(pgm, m->buf, 3);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
void avr910_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
strcpy(pgm->type, "avr910");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->rdy_led = avr910_rdy_led;
|
||||
pgm->err_led = avr910_err_led;
|
||||
pgm->pgm_led = avr910_pgm_led;
|
||||
pgm->vfy_led = avr910_vfy_led;
|
||||
pgm->initialize = avr910_initialize;
|
||||
pgm->display = avr910_display;
|
||||
pgm->save = avr910_save;
|
||||
pgm->restore = avr910_restore;
|
||||
pgm->enable = avr910_enable;
|
||||
pgm->disable = avr910_disable;
|
||||
pgm->powerup = avr910_powerup;
|
||||
pgm->powerdown = avr910_powerdown;
|
||||
pgm->program_enable = avr910_program_enable;
|
||||
pgm->chip_erase = avr910_chip_erase;
|
||||
pgm->cmd = avr910_cmd;
|
||||
pgm->open = avr910_open;
|
||||
pgm->close = avr910_close;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
|
||||
pgm->write_setup = avr910_write_setup;
|
||||
pgm->write_byte = avr910_write_byte;
|
||||
pgm->read_byte = avr910_read_byte;
|
||||
|
||||
pgm->paged_write = avr910_paged_write;
|
||||
pgm->paged_load = avr910_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = avr910_read_sig_bytes;
|
||||
}
|
||||
29
avrdude/avr910.h
Normal file
29
avrdude/avr910.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __avr910_h__
|
||||
#define __avr910_h__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void avr910_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif /* __avr910_h__ */
|
||||
@@ -19,7 +19,7 @@
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE January 11, 2002
|
||||
.Dd DATE July 24, 2003
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -30,6 +30,7 @@
|
||||
.Fl p Ar partno
|
||||
.Op Fl c Ar programmer-id
|
||||
.Op Fl C Ar config-file
|
||||
.Op Fl D
|
||||
.Op Fl e
|
||||
.Oo Fl E Ar exitspec Ns
|
||||
.Op \&, Ns Ar exitspec
|
||||
@@ -41,7 +42,9 @@
|
||||
.Op Fl o Ar filename
|
||||
.Op Fl n
|
||||
.Op Fl P Ar port
|
||||
.Op Fl q
|
||||
.Op Fl t
|
||||
.Op Fl U Ar memtype:op:filename:filefmt
|
||||
.Op Fl v
|
||||
.Op Fl V
|
||||
.Op Fl y
|
||||
@@ -112,6 +115,9 @@ been code-protected previously, of course) and store the data in a
|
||||
file. Finally, a ``terminal'' mode is available that allows one to
|
||||
interactively communicate with the MCU, and to display or program
|
||||
individual memory cells.
|
||||
On the STK500 programmer, several operational parameters (target supply
|
||||
voltage, target Aref voltage, master clock) can be examined and changed
|
||||
from within terminal mode as well.
|
||||
.Ss Options
|
||||
In order to control all the different operation modi, a number of options
|
||||
need to be specified to
|
||||
@@ -175,6 +181,19 @@ submit a patch back to the author so that it can be incorporated for
|
||||
the next version). See the config file, located at
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.It Fl D
|
||||
Disable auto erase for flash. When the
|
||||
.Fl U
|
||||
option with flash memory is specified,
|
||||
.Nm
|
||||
will perform a chip erase before starting any of the programming
|
||||
operations, since it generally is a mistake to program the flash
|
||||
without performing an erase first. This option disables that.
|
||||
However, to remain backward compatible, the
|
||||
.Fl i ,
|
||||
and
|
||||
.Fl m
|
||||
options automatically disable the auto erase feature.
|
||||
.It Fl e
|
||||
Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value
|
||||
@@ -239,8 +258,10 @@ Multiple
|
||||
.Ar exitspec
|
||||
arguments can be separated with commas.
|
||||
.It Fl f Ar format
|
||||
This option specifies the file format for the input or output files
|
||||
to be processed.
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) This option specifies the file format for the input or
|
||||
output files to be processed.
|
||||
.Ar Format
|
||||
can be one of:
|
||||
.Bl -tag -width sss
|
||||
@@ -250,6 +271,10 @@ Intel Hex
|
||||
Motorola S-record
|
||||
.It Ar r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
.It Ar m
|
||||
immediate; actual byte values specified on the command line, seperated
|
||||
by commas or spaces. This is good for programming fuse bytes without
|
||||
having to create a single-byte file or enter terminal mode.
|
||||
.It Ar a
|
||||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
@@ -267,15 +292,31 @@ that a device has a broken (erased or overwritten) device signature
|
||||
but is otherwise operating normally, this options is provided to
|
||||
override the check.
|
||||
.It Fl i Ar filename
|
||||
Specifies the input file to be programmed into the MCU. Can be specified
|
||||
as
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies the input file to be programmed into the MCU.
|
||||
Can be specified as
|
||||
.Ql \&-
|
||||
to use
|
||||
.Em stdin
|
||||
as the input.
|
||||
.It Fl I Ar data
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Same as specifying
|
||||
.Fl i
|
||||
and
|
||||
.Fl f Ar m
|
||||
together, i.e., this is a shortcut for using immediate file input mode
|
||||
where the filename field is used as the data itself. Useful for
|
||||
programming single byte memories such as fuse bytes without having to
|
||||
use single byte files or enter interactive terminal mode.
|
||||
.It Fl m Ar memtype
|
||||
Specifies which program area of the MCU to read or write; allowable
|
||||
values depend on the MCU being programmed, but most support at least
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies which program area of the MCU to read or write;
|
||||
allowable values depend on the MCU being programmed, but most support
|
||||
at least
|
||||
.Em eeprom
|
||||
for the EEPROM, and
|
||||
.Em flash
|
||||
@@ -291,8 +332,11 @@ No-write - disables actually writing data to the MCU (useful for debugging
|
||||
.Nm avrdude
|
||||
).
|
||||
.It Fl o Ar filename
|
||||
Specifies the name of the output file to write, and causes the respective
|
||||
memory area to be read from the MCU. Can be specified as
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies the name of the output file to write, and causes
|
||||
the respective memory area to be read from the MCU. Can be specified
|
||||
as
|
||||
.Ql \&-
|
||||
to write to
|
||||
.Em stdout .
|
||||
@@ -307,11 +351,42 @@ serial port, the
|
||||
.Pa /dev/cuaa0
|
||||
port is the default. If you need to use a different parallel or
|
||||
serial port, use this option to specify the alternate port name.
|
||||
.It Fl q
|
||||
Disable (or quell) output of the progress bar while reading or writing
|
||||
to the device.
|
||||
.It Fl t
|
||||
Tells
|
||||
.Nm
|
||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||
files. See below for a detailed description of the terminal mode.
|
||||
.It Xo Fl U Ar memtype Ns
|
||||
.Ar \&: Ns Ar op Ns
|
||||
.Ar \&: Ns Ar filename Ns
|
||||
.Op \&: Ns Ar format
|
||||
.Xc
|
||||
Perform a memory operation as indicated. The
|
||||
.Ar memtype
|
||||
field specifies the memory type to operate on. The
|
||||
.Ar op
|
||||
field specifies what operation to perform:
|
||||
.Bl -tag -width noreset
|
||||
.It Ar r
|
||||
read device memory and write to the specified file
|
||||
.It Ar w
|
||||
read data from the specified file and write to the device memory
|
||||
.It Ar v
|
||||
read data from both the device and the specified file and perform a verify
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar filename
|
||||
field indicates the name of the file to read or write.
|
||||
The
|
||||
.Ar format
|
||||
field is optional and contains the format of the file to read or
|
||||
write. See the
|
||||
.Fl f
|
||||
option for possible values.
|
||||
.It Fl v
|
||||
Enable verbose output.
|
||||
.It Fl V
|
||||
@@ -385,6 +460,35 @@ does not implement the command.
|
||||
Display the device signature bytes.
|
||||
.It Ar part
|
||||
Display the current part settings.
|
||||
.It Ar vtarg voltage
|
||||
Set the target's supply voltage to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar varef voltage
|
||||
Set the adjustable voltage source to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
.Em Aref
|
||||
input on the STK500.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc freq Ns Op M Ns \&| Ns k
|
||||
Set the master oscillator to
|
||||
.Ar freq
|
||||
Hz.
|
||||
An optional trailing letter
|
||||
.Ar \&M
|
||||
multiplies by 1E6, a trailing letter
|
||||
.Ar \&k
|
||||
by 1E3.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar \&?
|
||||
.It Ar help
|
||||
Give a short on-line summary of the available commands.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# programmer
|
||||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||
# desc = <description> ; # quoted string
|
||||
# type = par | stk500 ; # programmer type
|
||||
# type = par | stk500 | avr910; # programmer type
|
||||
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||
# reset = <num> ; # pin number
|
||||
# sck = <num> ; # pin number
|
||||
@@ -30,7 +30,9 @@
|
||||
# part
|
||||
# id = <id> ; # quoted string
|
||||
# desc = <description> ; # quoted string
|
||||
# devicecode = <num> ; # numeric
|
||||
# devicecode = <num> ; # deprecated, use stk500_devcode
|
||||
# stk500_devcode = <num> ; # numeric
|
||||
# avr910_devcode = <num> ; # numeric
|
||||
# chip_erase_delay = <num> ; # micro-seconds
|
||||
# pagel = <num> ; # pin name in hex, i.e., 0xD7
|
||||
# bs2 = <num> ; # pin name in hex, i.e., 0xA0
|
||||
@@ -182,7 +184,7 @@ default_serial = "@DEFAULT_SER_PORT@";
|
||||
|
||||
programmer
|
||||
id = "bsd";
|
||||
desc = "Brian Dean's Programmer";
|
||||
desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/";
|
||||
type = par;
|
||||
vcc = 2, 3, 4, 5;
|
||||
reset = 7;
|
||||
@@ -203,6 +205,18 @@ programmer
|
||||
type = stk500;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "avr910";
|
||||
desc = "Atmel Low Cost Serial Programmer";
|
||||
type = avr910;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "pavr";
|
||||
desc = "Jason Kyle's pAVR Serial Programmer";
|
||||
type = avr910;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "stk200";
|
||||
desc = "STK200";
|
||||
@@ -220,8 +234,8 @@ programmer
|
||||
# programming is currently in progress.
|
||||
|
||||
programmer
|
||||
id = "pony";
|
||||
desc = "Pony Prog";
|
||||
id = "pony-stk200";
|
||||
desc = "Pony Prog STK200";
|
||||
type = par;
|
||||
buff = 4, 5;
|
||||
sck = 6;
|
||||
@@ -241,9 +255,19 @@ programmer
|
||||
miso = 11;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "bascom";
|
||||
desc = "Bascom SAMPLE programming cable";
|
||||
type = par;
|
||||
reset = 4;
|
||||
sck = 5;
|
||||
mosi = 2;
|
||||
miso = 11;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "alf";
|
||||
desc = "Tony Friebel's Programmer";
|
||||
desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/";
|
||||
type = par;
|
||||
vcc = 2, 3, 4, 5;
|
||||
buff = 6;
|
||||
@@ -257,6 +281,26 @@ programmer
|
||||
vfyled = 17;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "sp12";
|
||||
desc = "Steve Bolt's Programmer";
|
||||
type = par;
|
||||
vcc = 4,5,6,7,8;
|
||||
reset = 3;
|
||||
sck = 2;
|
||||
mosi = 9;
|
||||
miso = 11;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "picoweb";
|
||||
desc = "Picoweb Programming Cable, http://www.picoweb.net/";
|
||||
type = par;
|
||||
reset = 2;
|
||||
sck = 3;
|
||||
mosi = 4;
|
||||
miso = 13;
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -265,6 +309,93 @@ programmer
|
||||
# PART DEFINITIONS
|
||||
#
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny12
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t12";
|
||||
desc = "ATtiny12";
|
||||
stk500_devcode = 0x12;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
memory "eeprom"
|
||||
size = 64;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 20000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
|
||||
"x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
|
||||
write = "1 1 0 0 0 0 0 0 x x x x x x x x",
|
||||
"x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
size = 1024;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 20000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write_lo = " 0 1 0 0 0 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
write_hi = " 0 1 0 0 1 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
|
||||
"0 0 0 0 0 0 a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
read = "0 1 0 1 1 0 0 0 x x x x x x x x",
|
||||
"x x x x x x x x x x x x x o o x";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
read = "0 0 1 1 1 0 0 0 x x x x x x x x",
|
||||
"0 0 0 0 0 0 0 0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
read = "0 1 0 1 0 0 0 0 x x x x x x x x",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny15
|
||||
#------------------------------------------------------------
|
||||
@@ -272,7 +403,8 @@ programmer
|
||||
part
|
||||
id = "t15";
|
||||
desc = "ATtiny15";
|
||||
devicecode = 0x13;
|
||||
stk500_devcode = 0x13;
|
||||
avr910_devcode = 0x56;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -359,7 +491,10 @@ part
|
||||
part
|
||||
id = "1200";
|
||||
desc = "AT90S1200";
|
||||
devicecode = 0x33;
|
||||
stk500_devcode = 0x33;
|
||||
avr910_devcode = 0x13;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xa0;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -439,7 +574,8 @@ part
|
||||
part
|
||||
id = "4414";
|
||||
desc = "AT90S4414";
|
||||
devicecode = 0x50;
|
||||
stk500_devcode = 0x50;
|
||||
avr910_devcode = 0x28;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -499,7 +635,8 @@ part
|
||||
part
|
||||
id = "2313";
|
||||
desc = "AT90S2313";
|
||||
devicecode = 0x40;
|
||||
stk500_devcode = 0x40;
|
||||
avr910_devcode = 0x20;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -564,7 +701,8 @@ part
|
||||
part
|
||||
id = "2333";
|
||||
desc = "AT90S2333";
|
||||
devicecode = 0x42;
|
||||
stk500_devcode = 0x42;
|
||||
avr910_devcode = 0x34;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -646,6 +784,8 @@ part
|
||||
part
|
||||
id = "2343";
|
||||
desc = "AT90S2343";
|
||||
stk500_devcode = 0x43;
|
||||
avr910_devcode = 0x4c;
|
||||
chip_erase_delay = 18000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -726,7 +866,8 @@ part
|
||||
part
|
||||
id = "4433";
|
||||
desc = "AT90S4433";
|
||||
devicecode = 0x51;
|
||||
stk500_devcode = 0x51;
|
||||
avr910_devcode = 0x30;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -807,7 +948,8 @@ part
|
||||
part
|
||||
id = "4434";
|
||||
desc = "AT90S4434";
|
||||
devicecode = 0x52;
|
||||
stk500_devcode = 0x52;
|
||||
avr910_devcode = 0x6c;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -887,7 +1029,8 @@ part
|
||||
part
|
||||
id = "8515";
|
||||
desc = "AT90S8515";
|
||||
devicecode = 0x60;
|
||||
stk500_devcode = 0x60;
|
||||
avr910_devcode = 0x38;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -961,7 +1104,8 @@ part
|
||||
part
|
||||
id = "8535";
|
||||
desc = "AT90S8535";
|
||||
devicecode = 0x61;
|
||||
stk500_devcode = 0x61;
|
||||
avr910_devcode = 0x68;
|
||||
chip_erase_delay = 20000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -1021,7 +1165,8 @@ part
|
||||
part
|
||||
id = "m103";
|
||||
desc = "ATMEGA103";
|
||||
devicecode = 0xB1;
|
||||
stk500_devcode = 0xB1;
|
||||
avr910_devcode = 0x41;
|
||||
chip_erase_delay = 112000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -1114,7 +1259,7 @@ part
|
||||
part
|
||||
id = "m128";
|
||||
desc = "ATMEGA128";
|
||||
devicecode = 0xB2;
|
||||
stk500_devcode = 0xB2;
|
||||
chip_erase_delay = 9000;
|
||||
pagel = 0xD7;
|
||||
bs2 = 0xA0;
|
||||
@@ -1235,7 +1380,7 @@ part
|
||||
part
|
||||
id = "m16";
|
||||
desc = "ATMEGA16";
|
||||
devicecode = 0x82;
|
||||
stk500_devcode = 0x82;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xa0;
|
||||
chip_erase_delay = 9000;
|
||||
@@ -1339,7 +1484,8 @@ part
|
||||
part
|
||||
id = "m163";
|
||||
desc = "ATMEGA163";
|
||||
devicecode = 0x81;
|
||||
stk500_devcode = 0x81;
|
||||
avr910_devcode = 0x64;
|
||||
chip_erase_delay = 32000;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xa0;
|
||||
@@ -1453,7 +1599,7 @@ part
|
||||
part
|
||||
id = "m169";
|
||||
desc = "ATMEGA169";
|
||||
devicecode = 0x85;
|
||||
stk500_devcode = 0x85;
|
||||
chip_erase_delay = 32000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
@@ -1567,6 +1713,125 @@ part
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega32
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "m32";
|
||||
desc = "ATMEGA32";
|
||||
stk500_devcode = 0x91;
|
||||
avr910_devcode = 0x72;
|
||||
chip_erase_delay = 32000;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xa0;
|
||||
reset = dedicated;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
memory "eeprom"
|
||||
paged = no; /* leave this "no" */
|
||||
page_size = 4; /* for parallel programming */
|
||||
size = 1024;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = " 1 0 1 0 0 0 0 0",
|
||||
" 0 0 x x x x a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write = " 1 1 0 0 0 0 0 0",
|
||||
" 0 0 x x x x a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 32768;
|
||||
page_size = 128;
|
||||
num_pages = 256;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 x x x x x x",
|
||||
" x x x x x x x x";
|
||||
;
|
||||
|
||||
memory "lfuse"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "hfuse"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x x x o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
|
||||
"x x x x x x x x 1 1 i i i i i i";
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
|
||||
"x x x x x x a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
|
||||
"0 0 0 0 0 0 0 0 o o o o o o o o";
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega8
|
||||
#------------------------------------------------------------
|
||||
@@ -1574,7 +1839,7 @@ part
|
||||
part
|
||||
id = "m8";
|
||||
desc = "ATMEGA8";
|
||||
devicecode = 0x70;
|
||||
stk500_devcode = 0x70;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xc2;
|
||||
chip_erase_delay = 9000;
|
||||
@@ -1668,6 +1933,121 @@ part
|
||||
"x x x x x x x x 1 1 i i i i i i";
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 4;
|
||||
read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
|
||||
"0 0 0 0 0 0 a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
|
||||
"x x x x x x a1 a0 o o o o o o o o";
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega8535
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "m8535";
|
||||
desc = "ATMEGA8535";
|
||||
stk500_devcode = 0x64;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xa0;
|
||||
chip_erase_delay = 9000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
memory "eeprom"
|
||||
size = 512;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = " 1 0 1 0 0 0 0 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write = " 1 1 0 0 0 0 0 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
;
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 8192;
|
||||
page_size = 64;
|
||||
num_pages = 128;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" 0 0 0 0 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" 0 0 0 0 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" 0 0 0 0 x x x x",
|
||||
" x x x a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" 0 0 0 0 x x x x",
|
||||
" x x x a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" 0 0 0 0 a11 a10 a9 a8",
|
||||
" a7 a6 a5 x x x x x",
|
||||
" x x x x x x x x";
|
||||
;
|
||||
|
||||
memory "lfuse"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "hfuse"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
min_write_delay = 2000;
|
||||
max_write_delay = 2000;
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x x x o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
|
||||
"x x x x x x x x 1 1 i i i i i i";
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
|
||||
@@ -1681,3 +2061,110 @@ part
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny26
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t26";
|
||||
desc = "ATTINY26";
|
||||
stk500_devcode = 0x21;
|
||||
pagel = 0xb3;
|
||||
bs2 = 0xb2;
|
||||
chip_erase_delay = 9000;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
memory "eeprom"
|
||||
size = 128;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 20000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
|
||||
"x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
|
||||
write = "1 1 0 0 0 0 0 0 x x x x x x x x",
|
||||
"x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 2048;
|
||||
page_size = 32;
|
||||
num_pages = 64;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 20000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" x x x x x x a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" x x x x x x a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" x x x x x x x x",
|
||||
" x x x x a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" x x x x x x x x",
|
||||
" x x x x a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" x x x x x x a9 a8",
|
||||
" a7 a6 a5 a4 x x x x",
|
||||
" x x x x x x x x";
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
|
||||
"0 0 0 0 0 0 a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
read = "0 1 0 1 1 0 0 0 x x x x x x x x",
|
||||
"x x x x x x x x x x x x x x o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
;
|
||||
|
||||
memory "lfuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "hfuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
|
||||
"x x x x x x x x x x x i i i i i";
|
||||
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x x x x o o o o o";
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 4;
|
||||
read = "0 0 1 1 1 0 0 0 x x x x x x x x",
|
||||
"0 0 0 0 0 0 a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
## @configure_input@
|
||||
##
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||
Name: avrdude
|
||||
Version: @VERSION@
|
||||
@@ -43,6 +45,9 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
|
||||
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
||||
install
|
||||
|
||||
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
|
||||
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
@@ -68,11 +73,17 @@ fi
|
||||
%attr(0644,root,root) %config /etc/avrdude.conf
|
||||
|
||||
%files docs
|
||||
%doc doc/avrdude-html
|
||||
%doc doc/avrdude-html/*.html
|
||||
%doc doc/TODO
|
||||
%doc doc/avrdude.ps
|
||||
%doc doc/avrdude.pdf
|
||||
|
||||
%changelog
|
||||
* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
|
||||
[Thanks to Artur Lipowski <LAL@pro.onet.pl>]
|
||||
- Do not build debug package.
|
||||
- Remove files not packaged to quell RH9 rpmbuild complaints.
|
||||
|
||||
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
|
||||
- Add docs sub-package.
|
||||
- Add %post and %preun scriptlets for handling info files.
|
||||
|
||||
@@ -81,7 +81,8 @@ typedef struct opcode {
|
||||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
int devicecode; /* Atmel STK500 device code */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
int avr910_devcode; /* avr910 device code */
|
||||
int chip_erase_delay; /* microseconds */
|
||||
unsigned char pagel; /* for parallel programming */
|
||||
unsigned char bs2; /* for parallel programming */
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "ppi.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500.h"
|
||||
#include "avr910.h"
|
||||
#include "avr.h"
|
||||
|
||||
extern char * progname;
|
||||
@@ -72,6 +73,8 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_DEFAULT_SERIAL
|
||||
%token K_DESC
|
||||
%token K_DEVICECODE
|
||||
%token K_STK500_DEVCODE
|
||||
%token K_AVR910_DEVCODE
|
||||
%token K_EEPROM
|
||||
%token K_ERRLED
|
||||
%token K_FLASH
|
||||
@@ -101,6 +104,7 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_SCK
|
||||
%token K_SIZE
|
||||
%token K_STK500
|
||||
%token K_AVR910
|
||||
%token K_TYPE
|
||||
%token K_VCC
|
||||
%token K_VFYLED
|
||||
@@ -284,6 +288,12 @@ prog_parm :
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_AVR910 {
|
||||
{
|
||||
avr910_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_DESC TKN_EQUAL TKN_STRING {
|
||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||
current_prog->desc[PGM_DESCLEN-1] = 0;
|
||||
@@ -403,7 +413,24 @@ part_parm :
|
||||
|
||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->devicecode = $3->value.number;
|
||||
fprintf(stderr,
|
||||
"%s: error at %s:%d: devicecode is deprecated, use "
|
||||
"stk500_devcode instead\n",
|
||||
progname, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
} |
|
||||
|
||||
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->stk500_devcode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->avr910_devcode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(avrdude, 4.0.0, avrdude-dev@nongnu.org)
|
||||
AC_INIT(avrdude, 4.2.0, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
@@ -42,6 +42,7 @@ AM_PROG_LEX
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([termcap], [tputs])
|
||||
AC_CHECK_LIB([ncurses], [tputs])
|
||||
AC_CHECK_LIB([readline], [readline])
|
||||
|
||||
# Checks for header files.
|
||||
@@ -124,6 +125,12 @@ case $target in
|
||||
esac
|
||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
fi
|
||||
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
doc/Makefile
|
||||
windows/Makefile
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -30,6 +30,8 @@ static char *filename;
|
||||
|
||||
void win_sys_config_set(char sys_config[PATH_MAX])
|
||||
{
|
||||
sys_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default system config file.*/
|
||||
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
||||
return;
|
||||
@@ -38,6 +40,8 @@ void win_sys_config_set(char sys_config[PATH_MAX])
|
||||
|
||||
void win_usr_config_set(char usr_config[PATH_MAX])
|
||||
{
|
||||
usr_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default user config file. */
|
||||
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
|
||||
General:
|
||||
|
||||
- Man page needs updated for avr910 info.
|
||||
|
||||
- avr910 needs a little bit of work to support setting fuse byte (note that it
|
||||
can only deal with a _single_ fuse byte.
|
||||
|
||||
- Website needs to link to docs:
|
||||
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
|
||||
|
||||
- Add avr910 device codes for more devices. Some where posted here:
|
||||
http://www.avrfreaks.com/phorum/read.php?f=3&i=40925&t=40717#40925
|
||||
but uisp seems to have a more comprehensive list.
|
||||
|
||||
Windows:
|
||||
|
||||
- Use Windows API for stk500 serial port communications on Windows port.
|
||||
This might remove dependency on Cygwin.
|
||||
|
||||
- Add ability to find all parallel port names available and base addresses
|
||||
of available ports.
|
||||
of available ports.
|
||||
|
||||
@@ -127,17 +127,24 @@ from the contents of a file, while interactive mode is useful for
|
||||
exploring memory contents, modifing individual bytes of eeprom,
|
||||
programming fuse/lock bits, etc.
|
||||
|
||||
AVRDUDE supports two basic programmer types: Atmel's STK500 and the PPI
|
||||
(parallel port interface). PPI represents a class of simple programmers
|
||||
where the programming lines are directly connected to the PC parallel
|
||||
port, while the STK500 uses the serial port to communicate with the PC
|
||||
AVRDUDE supports three basic programmer types: Atmel's STK500, appnote
|
||||
avr910 and the PPI (parallel port interface). PPI represents a class
|
||||
of simple programmers where the programming lines are directly
|
||||
connected to the PC parallel port. Several pin configurations exist
|
||||
for several variations of the PPI programmers, and AVRDUDE can be be
|
||||
configured to work with them by either specifying the appropriate
|
||||
programmer on the command line or by creating a new entry in its
|
||||
configuration file. All that's usually required for a new entry is to
|
||||
tell AVRDUDE which pins to use for each programming function.
|
||||
|
||||
The STK500 and avr910 use the serial port to communicate with the PC
|
||||
and contains on-board logic to control the programming of the target
|
||||
device. Several pin configurations exist for several variations of the
|
||||
PPI programmers, and AVRDUDE can be be configured to work with them by
|
||||
either specifying the appropriate programmer on the command line or by
|
||||
creating a new entry in its configuration file. All that's usually
|
||||
required for a new entry is to tell AVRDUDE which pins to use for each
|
||||
programming function.
|
||||
device. The fundamental difference between the two types lies in the
|
||||
protocol used to control the programmer. The av910 protocol is very
|
||||
simplistic and can easily be used as the basis for a simple, home made
|
||||
programer since the firmware is available online. On the other hand,
|
||||
the STK500 protocol is more robust and complicated and the firmware is
|
||||
not openly available.
|
||||
|
||||
@menu
|
||||
* History::
|
||||
@@ -147,7 +154,7 @@ programming function.
|
||||
@c Node
|
||||
@c
|
||||
@node History, , Introduction, Introduction
|
||||
@section History
|
||||
@section History and Credits
|
||||
|
||||
AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
|
||||
the FreeBSD Operating System. Brian renamed the software to be called
|
||||
@@ -212,9 +219,6 @@ datasheet so that you can enter the programming specifications.
|
||||
Currently, the following MCU types are understood:
|
||||
|
||||
@table @code
|
||||
@itemx t15
|
||||
ATtiny15
|
||||
|
||||
@itemx 1200
|
||||
AT90S1200
|
||||
|
||||
@@ -242,24 +246,39 @@ AT90S8515
|
||||
@itemx 8535
|
||||
AT90S8535
|
||||
|
||||
@itemx m103
|
||||
ATMEGA103
|
||||
|
||||
@itemx m128
|
||||
ATMEGA128
|
||||
|
||||
@itemx m16
|
||||
ATMEGA16
|
||||
|
||||
@itemx m163
|
||||
ATMEGA163
|
||||
|
||||
@itemx m169
|
||||
ATMEGA169
|
||||
|
||||
@itemx m128
|
||||
ATMEGA128
|
||||
|
||||
@itemx m103
|
||||
ATMEGA103
|
||||
|
||||
@itemx m16
|
||||
ATMEGA16
|
||||
@itemx m32
|
||||
ATMEGA32
|
||||
|
||||
@itemx m8
|
||||
ATMEGA8
|
||||
|
||||
@itemx m8535
|
||||
ATMEGA8535
|
||||
|
||||
@itemx t12
|
||||
ATtiny12
|
||||
|
||||
@itemx t15
|
||||
ATtiny15
|
||||
|
||||
@itemx t26
|
||||
ATTINY26
|
||||
|
||||
@end table
|
||||
|
||||
(*) The AT90S2323 uses the same algorithm.
|
||||
@@ -268,12 +287,55 @@ ATMEGA8
|
||||
Specify the programmer to be used. AVRDUDE knows about several common
|
||||
programmers. Use this option to specify which one to use. The
|
||||
@var{programmer-id} parameter is the programmer's id listed in the
|
||||
configuration file. Specify -c ? to list all programmers in the
|
||||
configuration file. Specify -c ? to list all programmers in the
|
||||
configuration file. If you have a programmer that is unknown to
|
||||
AVRDUDE, and the programmer is controlled via the PC parallel port,
|
||||
there's a good chance that it can be easily added to the configuration
|
||||
file without any code changes to AVRDUDE. Simply copy an existing entry
|
||||
and change the pin definitions to match that of the unknown programmer.
|
||||
Currently, the following programmer ids are understood and supported:
|
||||
|
||||
@table @code
|
||||
|
||||
@itemx alf
|
||||
Nightshade ALF-PgmAVR, http://nightshade.homeip.net/
|
||||
|
||||
@itemx avr910
|
||||
Atmel Low Cost Serial Programmer
|
||||
|
||||
@itemx avrisp
|
||||
Atmel AVR ISP
|
||||
|
||||
@itemx bascom
|
||||
Bascom SAMPLE programming cable
|
||||
|
||||
@itemx bsd
|
||||
Brian Dean's Programmer, http://www.bsdhome.com/avrdude/
|
||||
|
||||
@itemx dt006
|
||||
Dontronics DT006
|
||||
|
||||
@itemx pavr
|
||||
Jason Kyle's pAVR Serial Programmer
|
||||
|
||||
@itemx picoweb
|
||||
Picoweb Programming Cable, http://www.picoweb.net/
|
||||
|
||||
@itemx pony
|
||||
stk200 = Pony Prog STK200
|
||||
|
||||
@itemx sp12
|
||||
Steve Bolt's Programmer
|
||||
|
||||
@itemx stk200
|
||||
STK200
|
||||
|
||||
@itemx stk500
|
||||
Atmel STK500
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
|
||||
@item -C @var{config-file}
|
||||
Use the specified config file for configuration data. This file
|
||||
@@ -290,7 +352,7 @@ Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value `0xff', and is basically a
|
||||
prerequisite command before the flash ROM can be reprogrammed again.
|
||||
The only exception would be if the new contents would exclusively cause
|
||||
bits to be pro- grammed from the value `1' to `0'. Note that in order
|
||||
bits to be programmed from the value `1' to `0'. Note that in order
|
||||
to reprogram EERPOM cells, no explicit prior chip erase is required
|
||||
since the MCU provides an auto-erase cycle in that case before
|
||||
programming the cell.
|
||||
@@ -299,12 +361,12 @@ programming the cell.
|
||||
@item -E @var{exitspec}[,@dots{}]
|
||||
By default, AVRDUDE leaves the parallel port in the same state at exit
|
||||
as it has been found at startup. This option modifies the state of the
|
||||
`/RESET' and `Vcc' lines the par- allel port is left at, according to
|
||||
`/RESET' and `Vcc' lines the parallel port is left at, according to
|
||||
the exitspec arguments provided, as follows:
|
||||
|
||||
@table @code
|
||||
@itemx reset
|
||||
The `/RESET' signal will be left activated at pro- gram exit, that is it
|
||||
The `/RESET' signal will be left activated at program exit, that is it
|
||||
will be held low, in order to keep the MCU in reset state afterwards.
|
||||
Note in particular that the programming algorithm for the AT90S1200
|
||||
device mandates that the `/RESET' signal is active before powering up
|
||||
@@ -322,7 +384,7 @@ This option will leave those parallel port pins active (i. e. high) that
|
||||
can be used to supply `Vcc' power to the MCU.
|
||||
|
||||
@itemx novcc
|
||||
This option will pull the `Vcc' pins of the paral- lel port down at
|
||||
This option will pull the `Vcc' pins of the parallel port down at
|
||||
program exit.
|
||||
|
||||
@end table
|
||||
@@ -332,7 +394,7 @@ Multiple @var{exitspec} arguments can be separated with commas.
|
||||
|
||||
|
||||
@item -f @var{format}
|
||||
This option specifies the file format for the input or out- put files to
|
||||
This option specifies the file format for the input or output files to
|
||||
be processed. Format can be one of:
|
||||
|
||||
@table @code
|
||||
@@ -345,6 +407,16 @@ Motorola S-record
|
||||
@itemx r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
|
||||
@itemx m
|
||||
immediate mode; actual byte values specified on the command line,
|
||||
seperated by commas or spaces in place of the @var{filename} field of
|
||||
the @option{-i}, @option{-o}, or @option{-U} options. This is useful
|
||||
for programming fuse bytes without having to create a single-byte file
|
||||
or enter terminal mode. If the number specified begins with @code{0x},
|
||||
it is treated as a hex value. If the number otherwise begins with a
|
||||
leading zero (@code{0}) it is treated as octal. Otherwise, the value is
|
||||
treated as decimal.
|
||||
|
||||
@itemx a
|
||||
auto detect; valid for input only, and only if the input is not provided
|
||||
at stdin.
|
||||
@@ -387,13 +459,42 @@ Use port to identify the device to which the programmer is attached. By
|
||||
default the @code{/dev/ppi0} port is used, but if the programmer type
|
||||
normally connects to the serial port, the @code{/dev/cuaa0} port is the
|
||||
default. If you need to use a different parallel or serial port, use
|
||||
this option to spec- ify the alternate port name.
|
||||
this option to specify the alternate port name.
|
||||
|
||||
@item -q
|
||||
Disable (or quell) output of the progress bar while reading or writing
|
||||
to the device.
|
||||
|
||||
@item -t
|
||||
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
||||
or downloading files. See below for a detailed description of the
|
||||
terminal mode.
|
||||
|
||||
@item -U @var{memtype}:@var{op}:@var{filename}[:@var{format}]
|
||||
Perform a memory operation, equivalent to specifing the @option{-m},
|
||||
@option{-i} or @option{-o}, and @option{-f} options, except that
|
||||
multiple @option{-U} optins can be specified in order to operate on
|
||||
mulitple memories on the same command-line invocation. The
|
||||
@var{memtype} field specifies the memory type to operate on. The
|
||||
@var{op} field specifies what operation to perform:
|
||||
|
||||
@table @code
|
||||
@itemx r
|
||||
read the specified device memory and write to the specified file
|
||||
|
||||
@itemx w
|
||||
read the specified file and write it to the specified device memory
|
||||
|
||||
@itemx v
|
||||
read the specified device memory and the specified file and perform a verify operation
|
||||
|
||||
@end table
|
||||
|
||||
The @var{filename} field indicates the name of the file to read or
|
||||
write. The @var{format} field is optional and contains the format of
|
||||
the file to read or write. See the @option{-f} option for possible
|
||||
values.
|
||||
|
||||
@item -v
|
||||
Enable verbose output.
|
||||
|
||||
@@ -405,14 +506,14 @@ Tells AVRDUDE to use the last four bytes of the connected parts' EEPROM
|
||||
memory to track the number of times the device has been erased. When
|
||||
this option is used and the @option{-e} flag is specified to generate a
|
||||
chip erase, the previous counter will be saved before the chip erase, it
|
||||
is then incremented, and written back after the erase cycle com- pletes.
|
||||
is then incremented, and written back after the erase cycle completes.
|
||||
Presumably, the device would only be erased just before being
|
||||
programmed, and thus, this can be utilized to give an indication of how
|
||||
many erase-rewrite cycles the part has undergone. Since the FLASH
|
||||
memory can only endure a finite number of erase-rewrite cycles, one can
|
||||
use this option to track when a part is nearing the limit. The typ-
|
||||
ical limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
||||
application needs the last four bytes of EEPROM mem- ory, this option
|
||||
use this option to track when a part is nearing the limit. The typical
|
||||
limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
||||
application needs the last four bytes of EEPROM memory, this option
|
||||
should not be used.
|
||||
|
||||
@item -Y @var{cycles}
|
||||
@@ -430,28 +531,64 @@ should not be used.
|
||||
@section Example Command Line Invocations
|
||||
|
||||
@noindent
|
||||
Download the file @code{m128diag.hex} to the ATmega128 chip using the
|
||||
Download the file @code{diag.hex} to the ATmega128 chip using the
|
||||
STK500 programmer connected to the default serial port:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% avrdude -p m128 -c stk500 -y -e -i m128diag.hex
|
||||
% avrdude -p m128 -c stk500 -e -U flash:w:diag.hex
|
||||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
|
||||
Reading | ################################################## | 100% 0.03s
|
||||
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: erasing chip
|
||||
avrdude: erase-rewrite cycle count is now 52
|
||||
avrdude: done.
|
||||
avrdude: reading input file "m128diag.hex"
|
||||
avrdude: input file m128diag.hex auto detected as Intel Hex
|
||||
avrdude: writing flash (18130 bytes):
|
||||
18175
|
||||
avrdude: 18176 bytes of flash written
|
||||
avrdude: verifying flash memory against m128diag.hex:
|
||||
avrdude: performing op: 1, flash, 0, diag.hex
|
||||
avrdude: reading input file "diag.hex"
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: writing flash (19278 bytes):
|
||||
|
||||
Writing | ################################################## | 100% 7.60s
|
||||
|
||||
avrdude: 19456 bytes of flash written
|
||||
avrdude: verifying flash memory against diag.hex:
|
||||
avrdude: load data flash data from input file diag.hex:
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: input file diag.hex contains 19278 bytes
|
||||
avrdude: reading on-chip flash data:
|
||||
18175
|
||||
|
||||
Reading | ################################################## | 100% 6.83s
|
||||
|
||||
avrdude: verifying ...
|
||||
avrdude: 18176 bytes of flash verified
|
||||
avrdude: 19278 bytes of flash verified
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
%
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Upload the flash memory from the ATmega128 connected to the STK500
|
||||
programmer and save it in raw binary format in the file named
|
||||
@code{diag.flash}:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% avrdude -p m128 -c stk500 -U flash:r:diag.flash:r
|
||||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
|
||||
Reading | ################################################## | 100% 0.03s
|
||||
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: reading flash memory:
|
||||
|
||||
Reading | ################################################## | 100% 46.10s
|
||||
|
||||
avrdude: writing output file "diag.flash"
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
@@ -460,20 +597,46 @@ avrdude done. Thank you.
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Upload the flash memory from the ATmega128 connected to the STK500
|
||||
programmer and save it in raw binary format in the file named
|
||||
@code{m128diag.flash}:
|
||||
Using the default programmer, download the file @code{diag.hex} to
|
||||
flash, @code{eeprom.hex} to EEPROM, and set the Extended, High, and Low
|
||||
fuse bytes to 0xff, 0x89, and 0x2e respectively:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% avrdude -p m128 -c stk500 -f r -o m128diag.flash
|
||||
|
||||
% avrdude -p m128 -U flash:w:diag.hex \
|
||||
> -U eeprom:w:eeprom.hex \
|
||||
> -U efuse:w:0xff:m \
|
||||
> -U hfuse:w:0x89:m \
|
||||
> -U lfuse:w:0x2e:m
|
||||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
|
||||
Reading | ################################################## | 100% 0.03s
|
||||
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
|
||||
avrdude: reading flash memory:
|
||||
131071
|
||||
avrdude: writing output file "m128diag.flash"
|
||||
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
|
||||
To disable this feature, specify the -D option.
|
||||
avrdude: erasing chip
|
||||
avrdude: reading input file "diag.hex"
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: writing flash (19278 bytes):
|
||||
|
||||
Writing | ################################################## | 100% 7.60s
|
||||
|
||||
avrdude: 19456 bytes of flash written
|
||||
avrdude: verifying flash memory against diag.hex:
|
||||
avrdude: load data flash data from input file diag.hex:
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: input file diag.hex contains 19278 bytes
|
||||
avrdude: reading on-chip flash data:
|
||||
|
||||
Reading | ################################################## | 100% 6.84s
|
||||
|
||||
avrdude: verifying ...
|
||||
avrdude: 19278 bytes of flash verified
|
||||
|
||||
[ ... other memory status output skipped for brevity ... ]
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
@@ -482,6 +645,7 @@ avrdude done. Thank you.
|
||||
@end example
|
||||
|
||||
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@@ -548,6 +712,33 @@ Leave terminal mode and thus AVRDUDE.
|
||||
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
In addition, the following commands are supported on the STK500
|
||||
programmer:
|
||||
|
||||
@table @code
|
||||
|
||||
@item vtarg @var{voltage}
|
||||
Set the target's supply voltage to @var{voltage} Volts.
|
||||
|
||||
@item varef @var{voltage}
|
||||
Set the adjustable voltage source to @var{voltage} Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
@emph{Aref} input on the STK500.
|
||||
|
||||
@item fosc @var{freq}[@var{M}|@var{k}]
|
||||
Set the master oscillator to @var{freq} Hz.
|
||||
An optional trailing letter @var{M}
|
||||
multiplies by 1E6, a trailing letter @var{k} by 1E3.
|
||||
|
||||
@item fosc off
|
||||
Turn the master oscillator off.
|
||||
|
||||
@item parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
|
||||
@end table
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@@ -614,8 +805,8 @@ avrdude>
|
||||
|
||||
@noindent
|
||||
Program the fuse bits of an ATmega128 (disable M103 compatibility,
|
||||
enable high speed external crystal, enable brown-out detection). First
|
||||
display the factory defaults, then reprogram:
|
||||
enable high speed external crystal, enable brown-out detection, slowly
|
||||
rising power). First display the factory defaults, then reprogram:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
@@ -642,8 +833,8 @@ avrdude> w efuse 0 0xff
|
||||
avrdude> w hfuse 0 0x89
|
||||
>>> w hfuse 0 0x89
|
||||
|
||||
avrdude> w lfuse 0 0x2e
|
||||
>>> w lfuse 0 0x2e
|
||||
avrdude> w lfuse 0 0x2f
|
||||
>>> w lfuse 0 0x2f
|
||||
|
||||
avrdude>
|
||||
@end cartouche
|
||||
@@ -1269,6 +1460,8 @@ means that after the first time install_giveio is executed, you should
|
||||
be able to subsequently execute the batch file from any directory and have
|
||||
it successfully start the driver.
|
||||
|
||||
Note that you must have administrator privilege to load the giveio driver.
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
|
||||
197
avrdude/fileio.c
197
avrdude/fileio.c
@@ -360,11 +360,10 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
char * outfile, FILE * outf)
|
||||
{
|
||||
unsigned char * buf;
|
||||
unsigned int nextaddr, stopaddr;
|
||||
unsigned int nextaddr;
|
||||
int n, nbytes, addr_width;
|
||||
int i;
|
||||
unsigned char cksum;
|
||||
unsigned char startf, stopf ,emptyf;
|
||||
|
||||
char * tmpl=0;
|
||||
|
||||
@@ -373,39 +372,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
progname, recsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nextaddr = startaddr;
|
||||
buf = inbuf;
|
||||
nextaddr = 0;
|
||||
stopaddr = 0;
|
||||
startf = 0;
|
||||
stopf = 0;
|
||||
nbytes = 0;
|
||||
|
||||
/* search for ranges of 'real' data */
|
||||
for (i=startaddr; i<bufsize; i++) {
|
||||
if (buf[i] == 0xff) {
|
||||
if (startf == 0)
|
||||
continue;
|
||||
else if (stopf == 0) {
|
||||
stopf = 1;
|
||||
stopaddr = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (startf == 0) {
|
||||
startf = 1;
|
||||
nextaddr = i;
|
||||
while (nextaddr % recsize != 0)
|
||||
nextaddr --;
|
||||
}
|
||||
else if (stopf == 1) {
|
||||
stopf = 0;
|
||||
stopaddr = bufsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbytes = i;
|
||||
|
||||
bufsize = stopaddr - nextaddr;
|
||||
addr_width = 0;
|
||||
|
||||
while (bufsize) {
|
||||
@@ -435,34 +406,23 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* skip the lines filled with 0xff */
|
||||
emptyf = 1;
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
if (buf[i] != 0xff) {
|
||||
emptyf=0;
|
||||
break;
|
||||
}
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
||||
if (emptyf != 1) {
|
||||
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
}
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
|
||||
nextaddr += n;
|
||||
nbytes +=n;
|
||||
}
|
||||
|
||||
/* advance to next 'recsize' bytes */
|
||||
@@ -728,6 +688,49 @@ int fileio_rbin(struct fioparms * fio,
|
||||
}
|
||||
|
||||
|
||||
int fileio_imm(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
int rc = 0;
|
||||
char * e, * p;
|
||||
unsigned long b;
|
||||
int loc;
|
||||
|
||||
switch (fio->op) {
|
||||
case FIO_READ:
|
||||
loc = 0;
|
||||
p = strtok(filename, " ,");
|
||||
while (p != NULL && loc < size) {
|
||||
b = strtoul(p, &e, 0);
|
||||
if (*e != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid byte value (%s) specified for immediate mode\n",
|
||||
progname, p);
|
||||
return -1;
|
||||
}
|
||||
buf[loc++] = b;
|
||||
p = strtok(NULL, " ,");
|
||||
rc = loc;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
|
||||
progname, fio->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
|
||||
fprintf(stderr,
|
||||
"%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
|
||||
progname, fio->iodesc, fio->dir, filename, strerror(errno),
|
||||
fio->rw, rc, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int fileio_ihex(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
@@ -892,8 +895,8 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
char * fname;
|
||||
unsigned char * buf;
|
||||
struct fioparms fio;
|
||||
int i;
|
||||
AVRMEM * mem;
|
||||
int using_stdio;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
@@ -907,6 +910,33 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
/* Open Raw Binary format in binary mode on Windows.*/
|
||||
if(format == FMT_RBIN)
|
||||
{
|
||||
if(fio.op == FIO_READ)
|
||||
{
|
||||
fio.mode = "rb";
|
||||
}
|
||||
if(fio.op == FIO_WRITE)
|
||||
{
|
||||
fio.mode = "wb";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* point at the requested memory buffer */
|
||||
buf = mem->buf;
|
||||
if (fio.op == FIO_READ)
|
||||
size = mem->size;
|
||||
|
||||
if (fio.op == FIO_READ) {
|
||||
/* 0xff fill unspecified memory */
|
||||
memset(buf, 0xff, size);
|
||||
}
|
||||
|
||||
using_stdio = 0;
|
||||
|
||||
if (strcmp(filename, "-")==0) {
|
||||
if (fio.op == FIO_READ) {
|
||||
fname = "<stdin>";
|
||||
@@ -916,30 +946,22 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
fname = "<stdout>";
|
||||
f = stdout;
|
||||
}
|
||||
using_stdio = 1;
|
||||
}
|
||||
else {
|
||||
fname = filename;
|
||||
f = fopen(fname, fio.mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* point at the requested memory buffer */
|
||||
buf = mem->buf;
|
||||
if (fio.op == FIO_READ)
|
||||
size = mem->size;
|
||||
|
||||
if (fio.op == FIO_READ) {
|
||||
/* 0xff fill unspecified memory */
|
||||
for (i=0; i<size; i++) {
|
||||
buf[i] = 0xff;
|
||||
}
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
if (format == FMT_AUTO) {
|
||||
if (using_stdio) {
|
||||
fprintf(stderr,
|
||||
"%s: can't auto detect file format when using stdin/out.\n"
|
||||
" Please specify a file format using the -f option and try again.\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
format = fmt_autodetect(fname);
|
||||
if (format < 0) {
|
||||
fprintf(stderr,
|
||||
@@ -952,6 +974,17 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
progname, fio.iodesc, fname, fmtstr(format));
|
||||
}
|
||||
|
||||
if (format != FMT_IMM) {
|
||||
if (!using_stdio) {
|
||||
f = fopen(fname, fio.mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case FMT_IHEX:
|
||||
rc = fileio_ihex(&fio, fname, f, buf, size);
|
||||
@@ -965,12 +998,26 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
rc = fileio_rbin(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
case FMT_IMM:
|
||||
rc = fileio_imm(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||
progname, fio.iodesc, format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc > 0) {
|
||||
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) {
|
||||
/*
|
||||
* if we are reading flash, just mark the size as being the
|
||||
* highest non-0xff byte
|
||||
*/
|
||||
rc = avr_mem_hiaddr(mem);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ typedef enum {
|
||||
FMT_AUTO,
|
||||
FMT_SREC,
|
||||
FMT_IHEX,
|
||||
FMT_RBIN
|
||||
FMT_RBIN,
|
||||
FMT_IMM
|
||||
} FILEFMT;
|
||||
|
||||
struct fioparms {
|
||||
|
||||
@@ -125,6 +125,8 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
errled { yylval=NULL; return K_ERRLED; }
|
||||
flash { yylval=NULL; return K_FLASH; }
|
||||
@@ -152,6 +154,7 @@ retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||
serial { yylval=NULL; return K_SERIAL; }
|
||||
size { yylval=NULL; return K_SIZE; }
|
||||
stk500 { yylval=NULL; return K_STK500; }
|
||||
avr910 { yylval=NULL; return K_AVR910; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
vfyled { yylval=NULL; return K_VFYLED; }
|
||||
|
||||
786
avrdude/main.c
786
avrdude/main.c
@@ -41,17 +41,35 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "confwin.h"
|
||||
#include "fileio.h"
|
||||
#include "lists.h"
|
||||
#include "par.h"
|
||||
#include "pindefs.h"
|
||||
#include "ppi.h"
|
||||
#include "term.h"
|
||||
|
||||
|
||||
enum {
|
||||
DEVICE_READ,
|
||||
DEVICE_WRITE,
|
||||
DEVICE_VERIFY
|
||||
};
|
||||
|
||||
|
||||
typedef struct update_t {
|
||||
char * memtype;
|
||||
int op;
|
||||
char * filename;
|
||||
int format;
|
||||
} UPDATE;
|
||||
|
||||
|
||||
|
||||
/* Get VERSION from ac_cfg.h */
|
||||
char * version = VERSION;
|
||||
|
||||
@@ -63,6 +81,8 @@ char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
|
||||
|
||||
PROGRAMMER * pgm = NULL;
|
||||
|
||||
LISTID updates;
|
||||
|
||||
/*
|
||||
* global options
|
||||
*/
|
||||
@@ -80,18 +100,24 @@ void usage(void)
|
||||
" -p <partno> Required. Specify AVR device.\n"
|
||||
" -C <config-file> Specify location of configuration file.\n"
|
||||
" -c <programmer> Specify programmer type.\n"
|
||||
" -D Disable auto erase for flash memory\n"
|
||||
" -P <port> Specify connection port.\n"
|
||||
" -F Override invalid signature check.\n"
|
||||
" -e Perform a chip erase.\n"
|
||||
" -m <memtype> Memory type to operate on.\n"
|
||||
" -i <filename> Write device. Specify an input file.\n"
|
||||
" -o <filename> Read device. Specify an output file.\n"
|
||||
" -f <format> Specify the file format.\n"
|
||||
" -m <memtype> (deprecated) Memory type to operate on.\n"
|
||||
" -i <filename> (deprecated) Write device. Specify an input file.\n"
|
||||
" -o <filename> (deprecated) Read device. Specify an output file.\n"
|
||||
" -f <format> (deprecated) Specify the file format.\n"
|
||||
" -U <memtype>:r|w|v:<filename>[:format]\n"
|
||||
" Alternate memory operation specification.\n"
|
||||
" Multiple -U options are allowed, each request\n"
|
||||
" is performed in the order specified.\n"
|
||||
" -n Do not write anything to the device.\n"
|
||||
" -V Do not verify.\n"
|
||||
" -t Enter terminal mode.\n"
|
||||
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
|
||||
" -v Verbose output. -v -v for more.\n"
|
||||
" -q Quell progress output.\n"
|
||||
" -? Display this usage.\n"
|
||||
"\navrdude project: <URL:http://savannah.nongnu.org/projects/avrdude>\n"
|
||||
,progname);
|
||||
@@ -253,7 +279,431 @@ void list_programmers(FILE * f, char * prefix, LISTID programmers)
|
||||
return;
|
||||
}
|
||||
|
||||
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
|
||||
|
||||
static FP_UpdateProgress update_progress;
|
||||
|
||||
/* Report the progress of a read or write operation from/to the device.
|
||||
|
||||
The first call of report_progress() should look like this (for a write op):
|
||||
|
||||
report_progress (0, 1, "Writing");
|
||||
|
||||
Then hdr should be passed NULL on subsequent calls while the operation is
|
||||
progressing. Once the operation is complete, a final call should be made as
|
||||
such to ensure proper termination of the progress report:
|
||||
|
||||
report_progress (1, 1, NULL);
|
||||
|
||||
It would be nice if we could reduce the usage to one and only one call for
|
||||
each of start, during and end cases. As things stand now, that is not
|
||||
possible and makes maintenance a bit more work. */
|
||||
|
||||
void report_progress (int completed, int total, char *hdr)
|
||||
{
|
||||
static int last = 0;
|
||||
static double start_time;
|
||||
int percent = (completed * 100) / total;
|
||||
struct timeval tv;
|
||||
double t;
|
||||
|
||||
if (update_progress == NULL)
|
||||
return;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
|
||||
|
||||
if (hdr) {
|
||||
last = 0;
|
||||
start_time = t;
|
||||
update_progress (percent, t - start_time, hdr);
|
||||
}
|
||||
|
||||
if (percent > 100)
|
||||
percent = 100;
|
||||
|
||||
if (percent > last) {
|
||||
last = percent;
|
||||
update_progress (percent, t - start_time, hdr);
|
||||
}
|
||||
|
||||
if (percent == 100)
|
||||
last = 0; /* Get ready for next time. */
|
||||
}
|
||||
|
||||
static void update_progress_tty (int percent, double etime, char *hdr)
|
||||
{
|
||||
static char hashes[51];
|
||||
static char *header;
|
||||
static int last = 0;
|
||||
int i;
|
||||
|
||||
hashes[50] = 0;
|
||||
|
||||
memset (hashes, ' ', 50);
|
||||
for (i=0; i<percent; i+=2) {
|
||||
hashes[i/2] = '#';
|
||||
}
|
||||
|
||||
if (hdr) {
|
||||
fprintf (stderr, "\n");
|
||||
last = 0;
|
||||
header = hdr;
|
||||
}
|
||||
|
||||
if (last == 0) {
|
||||
fprintf(stderr, "\r%s | %s | %d%% %0.2fs",
|
||||
header, hashes, percent, etime);
|
||||
}
|
||||
|
||||
if (percent == 100) {
|
||||
last = 1;
|
||||
fprintf (stderr, "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void update_progress_no_tty (int percent, double etime, char *hdr)
|
||||
{
|
||||
static int done = 0;
|
||||
static int last = 0;
|
||||
int cnt = (percent>>1)*2;
|
||||
|
||||
if (hdr) {
|
||||
fprintf (stderr, "\n%s | ", hdr);
|
||||
last = 0;
|
||||
done = 0;
|
||||
}
|
||||
else {
|
||||
while ((cnt > last) && (done == 0)) {
|
||||
fprintf (stderr, "#");
|
||||
cnt -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((percent == 100) && (done == 0)) {
|
||||
fprintf (stderr, " | 100%% %0.2fs\n\n", etime);
|
||||
last = 0;
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
last = (percent>>1)*2; /* Make last a multiple of 2. */
|
||||
}
|
||||
|
||||
|
||||
UPDATE * parse_op(char * s)
|
||||
{
|
||||
char buf[1024];
|
||||
char * p;
|
||||
UPDATE * upd;
|
||||
int i;
|
||||
|
||||
upd = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (upd == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
p = s;
|
||||
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
|
||||
buf[i++] = *p++;
|
||||
|
||||
if (*p != ':') {
|
||||
fprintf(stderr, "%s: invalid update specification\n", progname);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[i] = 0;
|
||||
|
||||
upd->memtype = (char *)malloc(strlen(buf)+1);
|
||||
if (upd->memtype == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(upd->memtype, buf);
|
||||
|
||||
p++;
|
||||
if (*p == 'r') {
|
||||
upd->op = DEVICE_READ;
|
||||
}
|
||||
else if (*p == 'w') {
|
||||
upd->op = DEVICE_WRITE;
|
||||
}
|
||||
else if (*p == 'v') {
|
||||
upd->op = DEVICE_VERIFY;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n",
|
||||
progname, *p);
|
||||
fprintf(stderr,
|
||||
" allowed values are:\n"
|
||||
" r = read device\n"
|
||||
" w = write device\n"
|
||||
" v = verify device\n");
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
if (*p != ':') {
|
||||
fprintf(stderr, "%s: invalid update specification\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
i = 0;
|
||||
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
|
||||
buf[i++] = *p++;
|
||||
|
||||
if (!((*p == ':')||(*p == 0))) {
|
||||
fprintf(stderr, "%s: invalid update specification\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[i] = 0;
|
||||
|
||||
upd->filename = (char *)malloc(strlen(buf)+1);
|
||||
if (upd->filename == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(upd->filename, buf);
|
||||
|
||||
upd->format = FMT_AUTO;
|
||||
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
switch (*p) {
|
||||
case 'a': upd->format = FMT_AUTO; break;
|
||||
case 's': upd->format = FMT_SREC; break;
|
||||
case 'i': upd->format = FMT_IHEX; break;
|
||||
case 'r': upd->format = FMT_RBIN; break;
|
||||
case 'm': upd->format = FMT_IMM; break;
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid file format '%c' in update specifier\n",
|
||||
progname, *p);
|
||||
free(upd->memtype);
|
||||
free(upd->filename);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: WARNING, extraneous data (%s) in update specifier ignored\n",
|
||||
progname, p);
|
||||
}
|
||||
|
||||
return upd;
|
||||
}
|
||||
|
||||
|
||||
UPDATE * dup_update(UPDATE * upd)
|
||||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(u, upd, sizeof(UPDATE));
|
||||
|
||||
u->memtype = strdup(upd->memtype);
|
||||
u->filename = strdup(upd->filename);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
||||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u->memtype = strdup(memtype);
|
||||
u->filename = strdup(filename);
|
||||
u->op = op;
|
||||
u->format = filefmt;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
|
||||
int verify)
|
||||
{
|
||||
struct avrpart * v;
|
||||
AVRMEM * mem;
|
||||
int size, vsize;
|
||||
int rc;
|
||||
|
||||
mem = avr_locate_mem(p, upd->memtype);
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
|
||||
upd->memtype, p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (upd->op == DEVICE_READ) {
|
||||
/*
|
||||
* read out the specified device memory and write it to a file
|
||||
*/
|
||||
fprintf(stderr, "%s: reading %s memory:\n",
|
||||
progname, upd->memtype);
|
||||
report_progress(0,1,"Reading");
|
||||
rc = avr_read(pgm, p, upd->memtype, 0, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, upd->memtype, rc);
|
||||
return -1;
|
||||
}
|
||||
report_progress(1,1,NULL);
|
||||
size = rc;
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: writing output file \"%s\"\n",
|
||||
progname,
|
||||
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
|
||||
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: write to file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (upd->op == DEVICE_WRITE) {
|
||||
/*
|
||||
* write the selected device memory using data from a file; first
|
||||
* read the data from the specified file
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s: reading input file \"%s\"\n",
|
||||
progname,
|
||||
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: write to file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
size = rc;
|
||||
|
||||
/*
|
||||
* write the buffer contents to the selected memory type
|
||||
*/
|
||||
fprintf(stderr, "%s: writing %s (%d bytes):\n",
|
||||
progname, upd->memtype, size);
|
||||
|
||||
if (!nowrite) {
|
||||
report_progress(0,1,"Writing");
|
||||
rc = avr_write(pgm, p, upd->memtype, size, 1);
|
||||
report_progress(1,1,NULL);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* test mode, don't actually write to the chip, output the buffer
|
||||
* to stdout in intel hex instead
|
||||
*/
|
||||
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
|
||||
progname, upd->memtype, rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
vsize = rc;
|
||||
|
||||
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
|
||||
vsize, upd->memtype);
|
||||
|
||||
}
|
||||
else if (upd->op == DEVICE_VERIFY) {
|
||||
/*
|
||||
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
|
||||
* is the same as what is on the chip
|
||||
*/
|
||||
pgm->vfy_led(pgm, ON);
|
||||
|
||||
v = avr_dup_part(p);
|
||||
|
||||
fprintf(stderr, "%s: verifying %s memory against %s:\n",
|
||||
progname, upd->memtype, upd->filename);
|
||||
|
||||
fprintf(stderr, "%s: load data %s data from input file %s:\n",
|
||||
progname, upd->memtype, upd->filename);
|
||||
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: read from file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
size = rc;
|
||||
fprintf(stderr, "%s: input file %s contains %d bytes\n",
|
||||
progname, upd->filename, size);
|
||||
|
||||
|
||||
|
||||
fprintf(stderr, "%s: reading on-chip %s data:\n",
|
||||
progname, upd->memtype);
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, v, upd->memtype, size, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, upd->memtype, rc);
|
||||
pgm->err_led(pgm, ON);
|
||||
return -1;
|
||||
}
|
||||
report_progress (1,1,NULL);
|
||||
|
||||
|
||||
|
||||
fprintf(stderr, "%s: verifying ...\n", progname);
|
||||
rc = avr_verify(p, v, upd->memtype, size);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: verification error; content mismatch\n",
|
||||
progname);
|
||||
pgm->err_led(pgm, ON);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: %d bytes of %s verified\n",
|
||||
progname, rc, upd->memtype);
|
||||
|
||||
pgm->vfy_led(pgm, OFF);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: invalid update operation (%d) requested\n",
|
||||
progname, upd->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* main routine
|
||||
@@ -264,20 +714,24 @@ int main(int argc, char * argv [])
|
||||
int exitrc; /* exit code for main() */
|
||||
int i; /* general loop counter */
|
||||
int ch; /* options flag */
|
||||
int size; /* size of memory region */
|
||||
int len; /* length for various strings */
|
||||
struct avrpart * p; /* which avr part we are programming */
|
||||
struct avrpart * v; /* used for verify */
|
||||
int readorwrite; /* true if a chip read/write op was selected */
|
||||
int ppidata; /* cached value of the ppi data register */
|
||||
int vsize=-1; /* number of bytes to verify */
|
||||
AVRMEM * sig; /* signature data */
|
||||
struct stat sb;
|
||||
UPDATE * upd;
|
||||
LNODEID * ln;
|
||||
int deprecated = 0;
|
||||
|
||||
/* options / operating mode variables */
|
||||
char * memtype; /* "flash", "eeprom", etc */
|
||||
int doread; /* 1=reading AVR, 0=writing AVR */
|
||||
int doread; /* 1=reading AVR */
|
||||
int dowrite; /* 1=writing AVR */
|
||||
int erase; /* 1=erase chip, 0=don't */
|
||||
int auto_erase; /* 0=never erase unless explicity told to do
|
||||
so, 1=erase if we are going to program flash */
|
||||
char * outputf; /* output file name */
|
||||
char * inputf; /* input file name */
|
||||
int ovsigck; /* 1=override sig check, 0=don't */
|
||||
@@ -296,7 +750,10 @@ int main(int argc, char * argv [])
|
||||
int cycles; /* erase-rewrite cycles */
|
||||
int set_cycles; /* value to set the erase-rewrite cycles to */
|
||||
char * e; /* for strtol() error checking */
|
||||
int quell_progress;
|
||||
#if !defined(__CYGWIN__)
|
||||
char * homedir;
|
||||
#endif
|
||||
|
||||
progname = rindex(argv[0],'/');
|
||||
if (progname)
|
||||
@@ -309,20 +766,29 @@ int main(int argc, char * argv [])
|
||||
|
||||
init_config();
|
||||
|
||||
updates = lcreat(NULL, 0);
|
||||
if (updates == NULL) {
|
||||
fprintf(stderr, "%s: cannot initialize updater list\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
partdesc = NULL;
|
||||
readorwrite = 0;
|
||||
port = default_parallel;
|
||||
outputf = NULL;
|
||||
inputf = NULL;
|
||||
doread = 1;
|
||||
doread = 0;
|
||||
dowrite = 0;
|
||||
memtype = "flash";
|
||||
erase = 0;
|
||||
auto_erase = 1;
|
||||
p = NULL;
|
||||
ovsigck = 0;
|
||||
terminal = 0;
|
||||
filefmt = FMT_AUTO;
|
||||
nowrite = 0;
|
||||
verify = 1; /* on by default */
|
||||
quell_progress = 0;
|
||||
ppisetbits = 0;
|
||||
ppiclrbits = 0;
|
||||
exitspecs = NULL;
|
||||
@@ -375,7 +841,7 @@ int main(int argc, char * argv [])
|
||||
/*
|
||||
* process command line arguments
|
||||
*/
|
||||
while ((ch = getopt(argc,argv,"?c:C:eE:f:Fi:m:no:p:P:tvVyY:")) != -1) {
|
||||
while ((ch = getopt(argc,argv,"?c:C:DeE:f:Fi:I:m:no:p:P:qtU:vVyY:")) != -1) {
|
||||
|
||||
switch (ch) {
|
||||
case 'c': /* programmer id */
|
||||
@@ -387,7 +853,71 @@ int main(int argc, char * argv [])
|
||||
sys_config[PATH_MAX-1] = 0;
|
||||
break;
|
||||
|
||||
case 'D': /* disable auto erase */
|
||||
auto_erase = 0;
|
||||
break;
|
||||
|
||||
case 'e': /* perform a chip erase */
|
||||
erase = 1;
|
||||
auto_erase = 0;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
exitspecs = optarg;
|
||||
break;
|
||||
|
||||
case 'f': /* specify file format */
|
||||
deprecated = 1;
|
||||
if (strlen(optarg) != 1) {
|
||||
fprintf(stderr, "%s: invalid file format \"%s\"\n",
|
||||
progname, optarg);
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
switch (optarg[0]) {
|
||||
case 'a' : filefmt = FMT_AUTO; break;
|
||||
case 'i' : filefmt = FMT_IHEX; break;
|
||||
case 'r' : filefmt = FMT_RBIN; break;
|
||||
case 's' : filefmt = FMT_SREC; break;
|
||||
case 'm' : filefmt = FMT_IMM; break;
|
||||
break;
|
||||
default :
|
||||
fprintf(stderr, "%s: invalid file format \"%s\"\n\n",
|
||||
progname, optarg);
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F': /* override invalid signature check */
|
||||
ovsigck = 1;
|
||||
break;
|
||||
|
||||
case 'i': /* specify input file */
|
||||
deprecated = 1;
|
||||
auto_erase = 0;
|
||||
if (outputf || terminal) {
|
||||
fprintf(stderr,"%s: -o, -i, and -t are incompatible\n\n", progname);
|
||||
return 1;
|
||||
}
|
||||
dowrite = 1;
|
||||
inputf = optarg;
|
||||
break;
|
||||
|
||||
case 'I': /* specify input file and assume 'immediate mode' */
|
||||
deprecated = 1;
|
||||
auto_erase = 0;
|
||||
if (outputf || terminal) {
|
||||
fprintf(stderr,"%s: -o, -I, and -t are incompatible\n\n", progname);
|
||||
return 1;
|
||||
}
|
||||
dowrite = 1;
|
||||
inputf = optarg;
|
||||
filefmt = FMT_IMM;
|
||||
break;
|
||||
|
||||
case 'm': /* select memory type to operate on */
|
||||
deprecated = 1;
|
||||
if ((strcasecmp(optarg,"e")==0)||(strcasecmp(optarg,"eeprom")==0)) {
|
||||
memtype = "eeprom";
|
||||
}
|
||||
@@ -401,15 +931,13 @@ int main(int argc, char * argv [])
|
||||
readorwrite = 1;
|
||||
break;
|
||||
|
||||
case 'F': /* override invalid signature check */
|
||||
ovsigck = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
nowrite = 1;
|
||||
break;
|
||||
|
||||
case 'o': /* specify output file */
|
||||
deprecated = 1;
|
||||
auto_erase = 0;
|
||||
if (inputf || terminal) {
|
||||
fprintf(stderr,"%s: -i, -o, and -t are incompatible\n\n", progname);
|
||||
return 1;
|
||||
@@ -424,42 +952,12 @@ int main(int argc, char * argv [])
|
||||
partdesc = optarg;
|
||||
break;
|
||||
|
||||
case 'e': /* perform a chip erase */
|
||||
erase = 1;
|
||||
case 'P':
|
||||
port = optarg;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
exitspecs = optarg;
|
||||
break;
|
||||
|
||||
case 'i': /* specify input file */
|
||||
if (outputf || terminal) {
|
||||
fprintf(stderr,"%s: -o, -i, and -t are incompatible\n\n", progname);
|
||||
return 1;
|
||||
}
|
||||
doread = 0;
|
||||
inputf = optarg;
|
||||
break;
|
||||
|
||||
case 'f': /* specify file format */
|
||||
if (strlen(optarg) != 1) {
|
||||
fprintf(stderr, "%s: invalid file format \"%s\"\n",
|
||||
progname, optarg);
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
switch (optarg[0]) {
|
||||
case 'a' : filefmt = FMT_AUTO; break;
|
||||
case 'i' : filefmt = FMT_IHEX; break;
|
||||
case 'r' : filefmt = FMT_RBIN; break;
|
||||
case 's' : filefmt = FMT_SREC; break;
|
||||
break;
|
||||
default :
|
||||
fprintf(stderr, "%s: invalid file format \"%s\"\n\n",
|
||||
progname, optarg);
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
case 'q' : /* Quell progress output */
|
||||
quell_progress = 1;
|
||||
break;
|
||||
|
||||
case 't': /* enter terminal mode */
|
||||
@@ -473,8 +971,20 @@ int main(int argc, char * argv [])
|
||||
terminal = 1;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
port = optarg;
|
||||
case 'U':
|
||||
upd = parse_op(optarg);
|
||||
if (upd == NULL) {
|
||||
fprintf(stderr, "%s: error parsing update operation '%s'\n",
|
||||
progname, optarg);
|
||||
exit(1);
|
||||
}
|
||||
ladd(updates, upd);
|
||||
|
||||
if (verify && upd->op == DEVICE_WRITE) {
|
||||
upd = dup_update(upd);
|
||||
upd->op = DEVICE_VERIFY;
|
||||
ladd(updates, upd);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
@@ -513,6 +1023,21 @@ int main(int argc, char * argv [])
|
||||
|
||||
}
|
||||
|
||||
if (deprecated) {
|
||||
fprintf(stderr,
|
||||
"\n%s: WARNING: the -f, -i, -I, -o, and -m options are deprecated.\n"
|
||||
"%sPlease use the -U option instead.\n",
|
||||
progname, progbuf);
|
||||
}
|
||||
|
||||
|
||||
if (quell_progress == 0) {
|
||||
if (isatty (STDERR_FILENO))
|
||||
update_progress = update_progress_tty;
|
||||
else
|
||||
update_progress = update_progress_no_tty;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
/*
|
||||
* Print out an identifying string so folks can tell what version
|
||||
@@ -610,7 +1135,8 @@ int main(int argc, char * argv [])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strcmp(pgm->type, "STK500") == 0) {
|
||||
if ((strcmp(pgm->type, "STK500") == 0)
|
||||
|| (strcmp(pgm->type, "avr910") == 0)){
|
||||
if (port == default_parallel) {
|
||||
port = default_serial;
|
||||
}
|
||||
@@ -732,8 +1258,14 @@ int main(int argc, char * argv [])
|
||||
rc = pgm->initialize(pgm, p);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: initialization failed, rc=%d\n", progname, rc);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
if (!ovsigck) {
|
||||
fprintf(stderr, "%sDouble check connections and try again, "
|
||||
"or use -F to override\n"
|
||||
"%sthis check.\n\n",
|
||||
progbuf, progbuf);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* indicate ready */
|
||||
@@ -809,6 +1341,27 @@ int main(int argc, char * argv [])
|
||||
}
|
||||
}
|
||||
|
||||
if ((erase == 0) && (auto_erase == 1)) {
|
||||
AVRMEM * m;
|
||||
|
||||
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
|
||||
upd = ldata(ln);
|
||||
m = avr_locate_mem(p, upd->memtype);
|
||||
if (m == NULL)
|
||||
continue;
|
||||
if ((strcasecmp(m->desc, "flash") == 0) && (upd->op == DEVICE_WRITE)) {
|
||||
erase = 1;
|
||||
fprintf(stderr,
|
||||
"%s: NOTE: FLASH memory has been specified, an erase cycle will be performed\n"
|
||||
"%sTo disable this feature, specify the -D option.\n",
|
||||
progname, progbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (erase) {
|
||||
/*
|
||||
* erase the chip's flash and eeprom memories, this is required
|
||||
@@ -816,7 +1369,6 @@ int main(int argc, char * argv [])
|
||||
*/
|
||||
fprintf(stderr, "%s: erasing chip\n", progname);
|
||||
pgm->chip_erase(pgm, p);
|
||||
fprintf(stderr, "%s: done.\n", progname);
|
||||
}
|
||||
else if (set_cycles == -1) {
|
||||
/*
|
||||
@@ -838,7 +1390,8 @@ int main(int argc, char * argv [])
|
||||
|
||||
|
||||
|
||||
if (!terminal && ((inputf==NULL) && (outputf==NULL))) {
|
||||
if (!terminal && (lsize(updates) == 0) &&
|
||||
((inputf==NULL) && (outputf==NULL))) {
|
||||
/*
|
||||
* Check here to see if any other operations were selected and
|
||||
* generate an error message because if they were, we need either
|
||||
@@ -853,6 +1406,13 @@ int main(int argc, char * argv [])
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
if (doread && dowrite) {
|
||||
fprintf(stderr, "%s: can't be reading and writing from/to the same file\n",
|
||||
progname);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
if (terminal) {
|
||||
/*
|
||||
* terminal mode
|
||||
@@ -860,113 +1420,27 @@ int main(int argc, char * argv [])
|
||||
exitrc = terminal_mode(pgm, p);
|
||||
}
|
||||
else if (doread) {
|
||||
/*
|
||||
* read out the specified device memory and write it to a file
|
||||
*/
|
||||
fprintf(stderr, "%s: reading %s memory:\n",
|
||||
progname, memtype);
|
||||
rc = avr_read(pgm, p, memtype, 0, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, memtype, rc);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
size = rc;
|
||||
|
||||
fprintf(stderr, "%s: writing output file \"%s\"\n",
|
||||
progname, outputf);
|
||||
rc = fileio(FIO_WRITE, outputf, filefmt, p, memtype, size);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: terminating\n", progname);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
upd = new_update(DEVICE_READ, memtype, filefmt, outputf);
|
||||
ladd(updates, upd);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* write the selected device memory using data from a file; first
|
||||
* read the data from the specified file
|
||||
*/
|
||||
fprintf(stderr, "%s: reading input file \"%s\"\n",
|
||||
progname, inputf);
|
||||
rc = fileio(FIO_READ, inputf, filefmt, p, memtype, -1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: terminating\n", progname);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
size = rc;
|
||||
|
||||
/*
|
||||
* write the buffer contents to the selected memory type
|
||||
*/
|
||||
fprintf(stderr, "%s: writing %s (%d bytes):\n",
|
||||
progname, memtype, size);
|
||||
|
||||
if (!nowrite) {
|
||||
rc = avr_write(pgm, p, memtype, size, 1);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* test mode, don't actually write to the chip, output the buffer
|
||||
* to stdout in intel hex instead
|
||||
*/
|
||||
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype, size);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
|
||||
progname, memtype, rc);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
vsize = rc;
|
||||
|
||||
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
|
||||
vsize, memtype);
|
||||
|
||||
else if (dowrite) {
|
||||
upd = new_update(DEVICE_WRITE, memtype, filefmt, inputf);
|
||||
ladd(updates, upd);
|
||||
}
|
||||
|
||||
if (!doread && verify) {
|
||||
/*
|
||||
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
|
||||
* is the same as what is on the chip
|
||||
*/
|
||||
pgm->vfy_led(pgm, ON);
|
||||
|
||||
fprintf(stderr, "%s: verifying %s memory against %s:\n",
|
||||
progname, memtype, inputf);
|
||||
fprintf(stderr, "%s: reading on-chip %s data:\n",
|
||||
progname, memtype);
|
||||
rc = avr_read(pgm, v, memtype, vsize, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, memtype, rc);
|
||||
pgm->err_led(pgm, ON);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: verifying ...\n", progname);
|
||||
rc = avr_verify(p, v, memtype, vsize);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: verification error; content mismatch\n",
|
||||
progname);
|
||||
pgm->err_led(pgm, ON);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: %d bytes of %s verified\n",
|
||||
progname, rc, memtype);
|
||||
|
||||
pgm->vfy_led(pgm, OFF);
|
||||
if (!doread && verify && inputf) {
|
||||
upd = new_update(DEVICE_VERIFY, memtype, filefmt, inputf);
|
||||
ladd(updates, upd);
|
||||
}
|
||||
|
||||
|
||||
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
|
||||
upd = ldata(ln);
|
||||
rc = do_op(pgm, p, upd, nowrite, verify);
|
||||
if (rc) {
|
||||
exitrc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
main_exit:
|
||||
|
||||
|
||||
@@ -89,6 +89,13 @@ PROGRAMMER * pgm_new(void)
|
||||
*/
|
||||
pgm->paged_write = NULL;
|
||||
pgm->paged_load = NULL;
|
||||
pgm->write_setup = NULL;
|
||||
pgm->write_byte = NULL;
|
||||
pgm->read_byte = NULL;
|
||||
pgm->read_sig_bytes = NULL;
|
||||
pgm->set_vtarget = NULL;
|
||||
pgm->set_varef = NULL;
|
||||
pgm->set_fosc = NULL;
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,16 @@ typedef struct programmer_t {
|
||||
int page_size, int n_bytes);
|
||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes);
|
||||
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value);
|
||||
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value);
|
||||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, double v);
|
||||
int (*set_fosc) (struct programmer_t * pgm, double v);
|
||||
char config_file[PATH_MAX]; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
} PROGRAMMER;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -39,6 +39,8 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <windows.h>
|
||||
#include <sys/time.h>
|
||||
#include <w32api/windows.h>
|
||||
#include "ppi.h"
|
||||
|
||||
|
||||
@@ -315,6 +317,78 @@ static void outb(unsigned char value, unsigned short port)
|
||||
return;
|
||||
}
|
||||
|
||||
/* These two functions usecPerfDelay and usleep are based on code from the
|
||||
* uisp project and are a replacement for the cygwin usleep library
|
||||
* function which seems to not delay for the correct time
|
||||
*/
|
||||
|
||||
BOOL usecPerfDelay(long t)
|
||||
{
|
||||
static BOOL perf_counter_checked = FALSE;
|
||||
static BOOL use_perf_counter = FALSE;
|
||||
static LARGE_INTEGER freq ;
|
||||
|
||||
if (! perf_counter_checked) {
|
||||
if (QueryPerformanceFrequency(&freq)){
|
||||
use_perf_counter = TRUE;
|
||||
}
|
||||
perf_counter_checked = TRUE;
|
||||
}
|
||||
|
||||
if (! use_perf_counter)
|
||||
return FALSE;
|
||||
|
||||
else {
|
||||
LARGE_INTEGER now;
|
||||
LARGE_INTEGER finish;
|
||||
QueryPerformanceCounter(&now);
|
||||
finish.QuadPart = now.QuadPart + (t * freq.QuadPart) / 1000000;
|
||||
do {
|
||||
QueryPerformanceCounter(&now);
|
||||
} while (now.QuadPart < finish.QuadPart);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
WARNING WARNING This function replaces the standard usleep() library function
|
||||
because it doesn't appear to delay for the correct time.
|
||||
*/
|
||||
|
||||
#ifndef MIN_SLEEP_USEC
|
||||
#define MIN_SLEEP_USEC 20000
|
||||
#endif
|
||||
|
||||
unsigned usleep( unsigned int uSeconds )
|
||||
{
|
||||
struct timeval t1, t2;
|
||||
struct timespec nanoDelay ;
|
||||
|
||||
if (usecPerfDelay(uSeconds))
|
||||
return(0);
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
|
||||
if( uSeconds > MIN_SLEEP_USEC )
|
||||
{
|
||||
nanoDelay.tv_sec = uSeconds / 1000000UL;
|
||||
nanoDelay.tv_nsec = (uSeconds / 1000000UL) * 1000 ;
|
||||
nanosleep( &nanoDelay, NULL ) ;
|
||||
}
|
||||
|
||||
/* loop for the remaining time */
|
||||
t2.tv_sec = uSeconds / 1000000UL;
|
||||
t2.tv_usec = uSeconds % 1000000UL;
|
||||
|
||||
timeradd(&t1, &t2, &t1);
|
||||
|
||||
do {
|
||||
gettimeofday(&t2, NULL);
|
||||
} while (timercmp(&t2, &t1, <));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
352
avrdude/ser_posix.c
Normal file
352
avrdude/ser_posix.c
Normal file
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Posix serial interface for avrdude.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern char *progname;
|
||||
extern int verbose;
|
||||
|
||||
struct baud_mapping {
|
||||
long baud;
|
||||
speed_t speed;
|
||||
};
|
||||
|
||||
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, B1200 },
|
||||
{ 2400, B2400 },
|
||||
{ 4800, B4800 },
|
||||
{ 9600, B9600 },
|
||||
{ 19200, B19200 },
|
||||
{ 38400, B38400 },
|
||||
{ 57600, B57600 },
|
||||
{ 115200, B115200 },
|
||||
{ 230400, B230400 },
|
||||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static speed_t serial_baud_lookup(long baud)
|
||||
{
|
||||
struct baud_mapping *map = baud_lookup_table;
|
||||
|
||||
while (map->baud) {
|
||||
if (map->baud == baud)
|
||||
return map->speed;
|
||||
map++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
|
||||
progname, baud);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int serial_setattr(int fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
|
||||
if (!isatty(fd))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* initialize terminal modes
|
||||
*/
|
||||
rc = tcgetattr(fd, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: serial_setattr(): tcgetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
termios.c_iflag = 0;
|
||||
termios.c_oflag = 0;
|
||||
termios.c_cflag = 0;
|
||||
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
|
||||
termios.c_lflag = 0;
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: serial_setattr(): tcsetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serial_open(char * port, int baud)
|
||||
{
|
||||
int rc;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* open the serial port
|
||||
*/
|
||||
fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "%s: serial_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set serial line attributes
|
||||
*/
|
||||
rc = serial_setattr(fd, baud);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"%s: serial_open(): can't set attributes for device \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void serial_close(int fd)
|
||||
{
|
||||
/* FIXME: Should really restore the terminal to original state here. */
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
int serial_send(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set wfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
|
||||
char * p = buf;
|
||||
size_t len = buflen;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Send: ", progname);
|
||||
|
||||
while (buflen) {
|
||||
unsigned char c = *buf;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000;
|
||||
|
||||
while (len) {
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(fd, &wfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd+1, NULL, &wfds, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: serial_send(): programmer is not responding\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: serial_send(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = write(fd, p, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: serial_send(): write error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serial_recv(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
|
||||
char * p = buf;
|
||||
size_t len = 0;
|
||||
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
while (len < buflen) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: serial_recv(): programmer is not responding\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: serial_recv(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd, p, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: serial_recv(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
p++;
|
||||
len++;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (len) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serial_drain(int fd, int display)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
unsigned char buf;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
|
||||
if (display) {
|
||||
fprintf(stderr, "drain>");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
if (display) {
|
||||
fprintf(stderr, "<drain\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: serial_drain(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd, &buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: serial_drain(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (display) {
|
||||
fprintf(stderr, "%02x ", buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
avrdude/ser_win32.c
Normal file
60
avrdude/ser_win32.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Native Win32 serial interface for avrdude.
|
||||
*/
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
extern char *progname;
|
||||
|
||||
#if 0
|
||||
|
||||
int serial_open(char * port, long baud)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void serial_close(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int serial_send(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serial_recv(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serial_drain(int fd, int display)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
42
avrdude/serial.h
Normal file
42
avrdude/serial.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* This is the API for the generic serial interface. The implementations are
|
||||
actually provided by the target dependant files:
|
||||
|
||||
ser_posix.c : posix serial interface.
|
||||
ser_win32.c : native win32 serial interface.
|
||||
|
||||
The target file will be selected at configure time. */
|
||||
|
||||
#ifndef __serial_h__
|
||||
#define __serial_h__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern int serial_open(char * port, long baud);
|
||||
extern void serial_close(int fd);
|
||||
|
||||
extern int serial_send(int fd, char * buf, size_t buflen);
|
||||
extern int serial_recv(int fd, char * buf, size_t buflen);
|
||||
extern int serial_drain(int fd, int display);
|
||||
|
||||
#endif /* __serial_h__ */
|
||||
460
avrdude/stk500.c
460
avrdude/stk500.c
@@ -33,171 +33,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500_private.h"
|
||||
#include "serial.h"
|
||||
|
||||
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
|
||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
||||
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p);
|
||||
|
||||
|
||||
static int stk500_send(PROGRAMMER * pgm, char * buf, int buflen)
|
||||
static int stk500_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set wfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
|
||||
if (!buflen)
|
||||
return 0;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000;
|
||||
|
||||
while (buflen) {
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(pgm->fd, &wfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(pgm->fd+1, NULL, &wfds, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_send(): programmer is not responding on %s\n",
|
||||
progname, pgm->port);
|
||||
exit(1);
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: stk500_send(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = write(pgm->fd, buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: stk500_send(): write error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return serial_send(pgm->fd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int stk500_recv(PROGRAMMER * pgm, char * buf, int n)
|
||||
|
||||
static int stk500_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
while (n) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(pgm->fd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_recv(): programmer is not responding on %s\n",
|
||||
progname, pgm->port);
|
||||
exit(1);
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: stk500_recv(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(pgm->fd, buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: stk500_recv(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
buf++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return serial_recv(pgm->fd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int stk500_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
unsigned char buf;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
|
||||
if (display) {
|
||||
fprintf(stderr, "drain>");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(pgm->fd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
if (display) {
|
||||
fprintf(stderr, "<drain\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: stk500_drain(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(pgm->fd, &buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: stk500_drain(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (display) {
|
||||
fprintf(stderr, "%02x ", buf);
|
||||
}
|
||||
}
|
||||
return serial_drain(pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
@@ -518,7 +386,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
*/
|
||||
buf[0] = Cmnd_STK_SET_DEVICE;
|
||||
|
||||
buf[1] = p->devicecode;
|
||||
buf[1] = p->stk500_devcode;
|
||||
buf[2] = 0; /* device revision */
|
||||
|
||||
if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
|
||||
@@ -739,72 +607,10 @@ static void stk500_enable(PROGRAMMER * pgm)
|
||||
}
|
||||
|
||||
|
||||
static int stk500_setattr(int fd)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
|
||||
if (!isatty(fd))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* initialize terminal modes
|
||||
*/
|
||||
rc = tcgetattr(fd, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: stk500_setattr(): tcgetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
termios.c_iflag = 0;
|
||||
termios.c_oflag = 0;
|
||||
termios.c_cflag = 0;
|
||||
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
|
||||
termios.c_lflag = 0;
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
|
||||
cfsetospeed(&termios, B115200);
|
||||
cfsetispeed(&termios, B115200);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: stk500_setattr(): tcsetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
int rc;
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
|
||||
/*
|
||||
* open the serial port
|
||||
*/
|
||||
pgm->fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
|
||||
if (pgm->fd < 0) {
|
||||
fprintf(stderr, "%s: stk500_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set serial line attributes
|
||||
*/
|
||||
rc = stk500_setattr(pgm->fd);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_open(): can't set attributes for device \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
pgm->fd = serial_open(port, 115200);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
@@ -819,7 +625,7 @@ static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void stk500_close(PROGRAMMER * pgm)
|
||||
{
|
||||
close(pgm->fd);
|
||||
serial_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
@@ -924,7 +730,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
#endif
|
||||
|
||||
for (addr = 0; addr < n; addr += page_size) {
|
||||
fprintf(stderr, "\r \r%6u", addr);
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
@@ -968,8 +774,6 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\r \r%6u", addr-1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -1014,7 +818,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
}
|
||||
|
||||
for (addr = 0; addr < n; addr += page_size) {
|
||||
fprintf(stderr, "\r \r%6u", addr);
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
@@ -1055,13 +859,111 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\r \r%6u", addr-1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned uaref, utarg;
|
||||
|
||||
utarg = (unsigned)((v + 0.049) * 10);
|
||||
|
||||
if (stk500_getparm(pgm, Parm_STK_VADJUST, &uaref) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_vtarget(): cannot obtain V[aref]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uaref > utarg) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
|
||||
progname, uaref / 10.0, v);
|
||||
if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg)
|
||||
!= 0)
|
||||
return -1;
|
||||
}
|
||||
return stk500_setparm(pgm, Parm_STK_VTARGET, utarg);
|
||||
}
|
||||
|
||||
|
||||
static int stk500_set_varef(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned uaref, utarg;
|
||||
|
||||
uaref = (unsigned)((v + 0.049) * 10);
|
||||
|
||||
if (stk500_getparm(pgm, Parm_STK_VTARGET, &utarg) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_varef(): cannot obtain V[target]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uaref > utarg) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_varef(): V[aref] must not be greater than "
|
||||
"V[target] = %.1f\n",
|
||||
progname, utarg / 10.0);
|
||||
return -1;
|
||||
}
|
||||
return stk500_setparm(pgm, Parm_STK_VADJUST, uaref);
|
||||
}
|
||||
|
||||
|
||||
static int stk500_set_fosc(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
#define fbase 7372800U
|
||||
unsigned prescale, cmatch, fosc;
|
||||
static unsigned ps[] = {
|
||||
1, 8, 32, 64, 128, 256, 1024
|
||||
};
|
||||
int idx, rc;
|
||||
|
||||
prescale = cmatch = 0;
|
||||
if (v > 0.0) {
|
||||
if (v > fbase / 2) {
|
||||
const char *unit;
|
||||
if (v > 1e6) {
|
||||
v /= 1e6;
|
||||
unit = "MHz";
|
||||
} else if (v > 1e3) {
|
||||
v /= 1e3;
|
||||
unit = "kHz";
|
||||
} else
|
||||
unit = "Hz";
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
|
||||
progname, v, unit, fbase / 2e6);
|
||||
fosc = fbase / 2;
|
||||
} else
|
||||
fosc = (unsigned)v;
|
||||
|
||||
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
|
||||
if (fosc >= fbase / (256 * ps[idx] * 2)) {
|
||||
/* this prescaler value can handle our frequency */
|
||||
prescale = idx + 1;
|
||||
cmatch = (unsigned)(fbase / (2 * v * ps[idx]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == sizeof(ps) / sizeof(ps[0])) {
|
||||
fprintf(stderr, "%s: stk500_set_fosc(): f = %u Hz too low, %u Hz min\n",
|
||||
progname, fosc, fbase / (256 * 1024 * 2));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0
|
||||
|| (rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
@@ -1118,21 +1020,141 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
}
|
||||
|
||||
|
||||
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
int tries = 0;
|
||||
|
||||
retry:
|
||||
tries++;
|
||||
buf[0] = Cmnd_STK_SET_PARAMETER;
|
||||
buf[1] = parm;
|
||||
buf[2] = value;
|
||||
buf[3] = Sync_CRC_EOP;
|
||||
|
||||
stk500_send(pgm, buf, 4);
|
||||
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
if (tries > 33) {
|
||||
fprintf(stderr, "\n%s: stk500_setparm(): can't get into sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_setparm(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -2;
|
||||
}
|
||||
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK)
|
||||
return 0;
|
||||
|
||||
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_FAILED) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_setparm(): parameter 0x%02x failed\n",
|
||||
progname, parm);
|
||||
return -3;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_setparm(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stk500_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned maj, min, hdw;
|
||||
unsigned maj, min, hdw, topcard;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
|
||||
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
||||
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
||||
stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
|
||||
|
||||
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
|
||||
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
|
||||
if (topcard < 3) {
|
||||
const char *n = "Unknown";
|
||||
|
||||
switch (topcard) {
|
||||
case 1:
|
||||
n = "STK502";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
n = "STK501";
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "%sTopcard : %s\n", p, n);
|
||||
}
|
||||
stk500_print_parms1(pgm, p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned vtarget, vadjust, osc_pscale, osc_cmatch;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
|
||||
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
||||
|
||||
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
||||
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
|
||||
fprintf(stderr, "%sOscillator : ", p);
|
||||
if (osc_pscale == 0)
|
||||
fprintf(stderr, "Off\n");
|
||||
else {
|
||||
int prescale = 1;
|
||||
double f = 3.6864e6;
|
||||
const char *unit;
|
||||
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
case 3: prescale = 32; break;
|
||||
case 4: prescale = 64; break;
|
||||
case 5: prescale = 128; break;
|
||||
case 6: prescale = 256; break;
|
||||
case 7: prescale = 1024; break;
|
||||
}
|
||||
f /= prescale;
|
||||
f /= (osc_cmatch + 1);
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
unit = "kHz";
|
||||
} else
|
||||
unit = "Hz";
|
||||
fprintf(stderr, "%.3f %s\n", f, unit);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void stk500_print_parms(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500_print_parms1(pgm, "");
|
||||
}
|
||||
|
||||
|
||||
void stk500_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK500");
|
||||
@@ -1163,7 +1185,9 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
||||
*/
|
||||
pgm->paged_write = stk500_paged_write;
|
||||
pgm->paged_load = stk500_paged_load;
|
||||
pgm->print_parms = stk500_print_parms;
|
||||
pgm->set_vtarget = stk500_set_vtarget;
|
||||
pgm->set_varef = stk500_set_varef;
|
||||
pgm->set_fosc = stk500_set_fosc;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE
|
||||
|
||||
#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached
|
||||
|
||||
// *****************[ STK status bit definitions ]***************************
|
||||
|
||||
|
||||
126
avrdude/term.c
126
avrdude/term.c
@@ -66,6 +66,14 @@ int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
|
||||
struct command cmd[] = {
|
||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||
@@ -75,6 +83,10 @@ struct command cmd[] = {
|
||||
{ "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 only)" },
|
||||
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
|
||||
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
|
||||
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
|
||||
{ "help", cmd_help, "help" },
|
||||
{ "?", cmd_help, "help" },
|
||||
{ "quit", cmd_quit, "quit" }
|
||||
@@ -497,6 +509,120 @@ int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
if (pgm->print_parms == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (parms): the %s programmer does not support "
|
||||
"adjustable parameters\n",
|
||||
progname, pgm->type);
|
||||
return -1;
|
||||
}
|
||||
pgm->print_parms(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: vtarg <value>\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (vtarg): can't parse voltage \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
if (pgm->set_vtarget == NULL) {
|
||||
fprintf(stderr, "%s (vtarg): the %s programmer cannot set V[target]\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_vtarget(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (vtarg): failed to set V[target] (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: fosc <value>[M|k] | off\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
if (strcmp(argv[1], "off") == 0)
|
||||
v = 0.0;
|
||||
else {
|
||||
fprintf(stderr, "%s (fosc): can't parse frequency \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
v *= 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
v *= 1e3;
|
||||
if (pgm->set_fosc == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (fosc): the %s programmer cannot set oscillator frequency\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_fosc(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (fosc): failed to set oscillator_frequency (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: varef <value>\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
if (pgm->set_varef == NULL) {
|
||||
fprintf(stderr, "%s (varef): the %s programmer cannot set V[aref]\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_varef(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
Reference in New Issue
Block a user