mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-18 11:24:42 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
078a334625 |
@@ -5,6 +5,5 @@ AVRDUDE was written by:
|
|||||||
Contributors:
|
Contributors:
|
||||||
|
|
||||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
Eric Weddington <eric@ecentral.com>
|
Eric Weddington <eric@umginc.net>
|
||||||
Theodore A. Roth <troth@openavr.org>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,601 @@
|
|||||||
2004-01-26 Theodore A. Roth <troth@openavr.org>
|
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
* AVRDUDE 4.3.0 has been released (cvs release tag is "release_4_3_0").
|
* Makefile.am: Add CLEANFILES to remove all files from a make.
|
||||||
|
* doc/Makefile.am: Ditto
|
||||||
|
|
||||||
2004-01-26 Theodore A. Roth <troth@openavr.org>
|
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
* configure.ac: Update copyright year.
|
* windows/Makefile.am: Fix uninstall-local rule (forget the $$file
|
||||||
(AC_INIT): Set version to 4.3.0.
|
part of the rm command).
|
||||||
|
|
||||||
2004-01-25 Theodore A. Roth <troth@openavr.org>
|
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
* ChangeLog: Minor formatting cleanups.
|
* AUTHORS: Updated.
|
||||||
Move to all 2003 entries to ChangeLog-2003.
|
* CHANGELOG: Move contents to NEWS and remove file.
|
||||||
* ChangeLog-2003: New file.
|
* ChangeLog: All of the changes for this year.
|
||||||
* Makefile.am: Update copyright year.
|
* ChangeLog-2001: All 2001 changes.
|
||||||
(EXTRA_DIST): Add ChangeLog-2003.
|
* ChangeLog-2002: All 2002 changes.
|
||||||
|
* Makefile.am (EXTRA_DIST): Remove CHANGELOG and and Change-200[12].
|
||||||
|
* NEWS: Moved contents of CHANGELOG file here.
|
||||||
|
* README: Add note pointing to savannah site.
|
||||||
|
|
||||||
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
|
2003-03-11 Eric Weddington <eric@umginc.net>
|
||||||
|
|
||||||
* doc/avrdude.texi: Get rid of those black boxes marking "overfull
|
* doc/avrdude.texi:
|
||||||
hbox".
|
Add Install and Documentation sections for Windows. Fix typo.
|
||||||
|
|
||||||
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
|
2003-03-10 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
* doc/avrdude.texi: New appendix "Troubleshooting".
|
* Makefile.am: * Makefile.am (EXTRA_DIST): Add CHANGELOG.
|
||||||
|
|
||||||
2004-01-12 Jan-Hinnerk Reichert <hinni@despammed.com>
|
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
* avr910.c, avrpart.c, avrpart.h, doc/TODO:
|
* stk500.c: Disable debugging printf.
|
||||||
Look up devicecode and report device.
|
|
||||||
|
|
||||||
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
|
* configure.ac: Update version number in preparation for release.
|
||||||
|
|
||||||
* avr910.c, pgm.c, pgm.h, config_gram.y, lexer.l: Add new configuration
|
2003-03-10 Theodore A. Roth <troth@openavr.org>
|
||||||
parameter baudrate to support avr910-programmers with non-standard
|
|
||||||
baudrates.
|
|
||||||
* avrdude.conf.in, doc/avrdude.texi: Added "baudrate" to documentation.
|
|
||||||
|
|
||||||
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
|
* doc/avrdude.texi:
|
||||||
|
Add comment before each node to make them stand out better.
|
||||||
|
Use @option{} command for options instead of @code{}.
|
||||||
|
Merge FreeBSD and Linux platform dependent information.
|
||||||
|
|
||||||
* avr910.c: Removed debugging stuff that is no longer needed.
|
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
|
* avrdude.1: Minor man page updates to better reflect reality.
|
||||||
|
|
||||||
* doc/TODO: Removed two items.
|
2003-03-10 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
|
* bootstrap:
|
||||||
|
Export all the AUTO* variables. Hopefully, that way the generated
|
||||||
|
Makefile might get them correctly.
|
||||||
|
|
||||||
* main.c, avr.c, avr.h, par.c, stk500.c: Add function
|
* bootstrap:
|
||||||
avr_chip_erase() to unify handling of cycle-count.
|
Export ${AUTOCONF} so automake will find it by whatever name it will be
|
||||||
Makes cycle-count work for avr910-programmers.
|
called today.
|
||||||
|
|
||||||
|
2003-03-06 Eric Weddington <eric@umginc.net>
|
||||||
|
|
||||||
|
* doc/avrdude.texi:
|
||||||
|
Add notes about ability to list parts and list programmers in the
|
||||||
|
config file in -p and -c descriptions. Change info about where to
|
||||||
|
find Windows search method in -C description.
|
||||||
|
|
||||||
|
* main.c:
|
||||||
|
Change software version from hardcoded value to getting it from
|
||||||
|
the configuration.
|
||||||
|
|
||||||
|
2003-03-06 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* avrdude.spec.in: * avrdude.spec.in: Add docs sub-package.
|
||||||
|
Add %post and %preun scriptlets for handling info files.
|
||||||
|
|
||||||
|
* configure.ac, doc/Makefile.am:
|
||||||
|
* configure.ac: Add --enable-versioned-doc option and set DOC_INST_DIR.
|
||||||
|
* doc/Makefile.am: Add rules to install docs in DOC_INST_DIR.
|
||||||
|
|
||||||
|
* doc/Makefile.am:
|
||||||
|
Delete the lines which where commented out in previous commit.
|
||||||
|
|
||||||
|
* configure.ac, doc/Makefile.am:
|
||||||
|
* configure.ac: Remove hack to make work with automake-1.5.
|
||||||
|
* doc/Makefile.am: Remove extra rules that were needed to work with
|
||||||
|
automake-1.5.
|
||||||
|
|
||||||
|
* bootstrap:
|
||||||
|
* bootstrap: Force use of autoconf-2.57 and automake-1.7.x.
|
||||||
|
|
||||||
|
2003-03-05 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* avrdude.conf.in: Add a definition for the popular Ponyprog dongle.
|
||||||
|
|
||||||
|
Submitted by: Daniel Williamson <dannyw@maconmgt.co.uk>
|
||||||
|
|
||||||
|
2003-03-05 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* main.c:
|
||||||
|
Check the programmer type against 'STK500' instead of the programmer
|
||||||
|
name when checking to see if we should default to the default_serial
|
||||||
|
port instead of the default_parallel port. This has us do the right
|
||||||
|
thing for the new 'avrisp' programmer.
|
||||||
|
|
||||||
|
* stk500.c:
|
||||||
|
Make the page size used for non-paged parts for the 'paged_write'
|
||||||
|
command be 128 bytes. This cuts 6 seconds off the programming time
|
||||||
|
for uploading a 6K file into an AT90S8515 vs the time loading the same
|
||||||
|
file using a 16 byte buffer, and the response feedback is still good.
|
||||||
|
|
||||||
|
* avr.c, stk500.c:
|
||||||
|
Fix stk500 page write (Program Page command). This is supported after
|
||||||
|
all on non-paged-memory parts. The problem was that the page size was
|
||||||
|
defaulting to 256 (maximum for the stk500), but the timeout for a
|
||||||
|
response from the stk500 before declaring it dead was only 0.5
|
||||||
|
seconds. But it takes much longer than 0.5 seconds to program 256
|
||||||
|
bytes, so we just weren't waiting long enough.
|
||||||
|
|
||||||
|
Fix this in two ways - increase the timeout to 5 seconds, and decrease
|
||||||
|
the page size to 16 bytes for non-paged parts. The programming time
|
||||||
|
for 16 bytes is short enough to provide the user with some feedback
|
||||||
|
that something is happening.
|
||||||
|
|
||||||
|
* avr.c, stk500.c:
|
||||||
|
Don't call the programmer's 'paged_write' routine unless the memory
|
||||||
|
itself is paged as it doesn't appear to work otherwise.
|
||||||
|
|
||||||
|
* avrdude.conf.in: Fix device codes for at90s8515 and at90s8535.
|
||||||
|
|
||||||
|
* avrdude.conf.in:
|
||||||
|
Add PAGEL and BS2 parms for parts I have datasheets for.
|
||||||
|
|
||||||
|
* config_gram.y:
|
||||||
|
Do that last commit slightly differently - this way results in no
|
||||||
|
shift-reduce conflicts.
|
||||||
|
|
||||||
|
* config_gram.y:
|
||||||
|
It shouldn't be an error to have an empty configuration file. This
|
||||||
|
causes some shift-reduce conflicts, but I think they are OK.
|
||||||
|
|
||||||
|
* main.c:
|
||||||
|
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>
|
||||||
|
|
||||||
|
* doc/avrdude.texi: Minor Windows doc corrections.
|
||||||
|
|
||||||
|
* doc/TODO: Add TODO file.
|
||||||
|
|
||||||
|
* avrdude.conf.in: Add AVR ISP programmer.
|
||||||
|
|
||||||
|
2003-03-04 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* stk500.c:
|
||||||
|
Don't try to set extended device programming parameters if they
|
||||||
|
haven't been specified in the config file for the part.
|
||||||
|
|
||||||
|
* stk500.c: Set extended device parameters for all firmware versions.
|
||||||
|
|
||||||
|
* stk500.c:
|
||||||
|
First attempt at supporting STK500 firmware past 1.10. Thanks to
|
||||||
|
Jason Kyle for the needed protocol information.
|
||||||
|
|
||||||
|
2003-03-03 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* doc/Makefile.am:
|
||||||
|
* doc/Makefile.am: Add ps and pdf rules since they aren't supplied by
|
||||||
|
automake versions prior to 1.7.
|
||||||
|
|
||||||
|
* doc/avrdude.texi:
|
||||||
|
* doc/avrdude.texi: Add node and menu information for the info system.
|
||||||
|
|
||||||
|
* Makefile.am, configure.ac, doc/Makefile.am, doc/avrdude.texi:
|
||||||
|
* Makefile.am (SUBDIRS): Add doc dir.
|
||||||
|
* configure.ac (AC_CONFIG_FILES): Add doc/Makefile.
|
||||||
|
* doc/Makefile.am: New file.
|
||||||
|
* doc/avrdude.texi: Use automatically generated version.texi.
|
||||||
|
|
||||||
|
2003-03-02 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* doc/avrdude.texi: Initial manual.
|
||||||
|
|
||||||
|
2003-02-27 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* term.c: * term.c: Use fgets() if readline() is not available.
|
||||||
|
|
||||||
|
2003-02-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* bootstrap:
|
||||||
|
Oops, accidentally spammed the repository with my private version of
|
||||||
|
"bootstrap". Back out that change.
|
||||||
|
|
||||||
|
* bootstrap, lexer.l:
|
||||||
|
Ignore \r as white space, to make the Windows people happy.
|
||||||
|
|
||||||
|
2003-02-27 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile.am (EXTRA_DIST): Add avrdude.spec and make entries one
|
||||||
|
per line so future patches are obvious as to what changed.
|
||||||
|
* avrdude.spec.in: New file to support creation of binaries in rpm
|
||||||
|
format.
|
||||||
|
* configure.ac (AC_OUTPUT): Add avrdude.spec. Reorder so that
|
||||||
|
Makefile is the last entry.
|
||||||
|
|
||||||
|
2003-02-26 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile.am (SUBDIRS): Add windows dir.
|
||||||
|
* configure.ac: If $target is a windows system, build whats in
|
||||||
|
windows sub dir.
|
||||||
|
* windows/Makefile.am: New file.
|
||||||
|
|
||||||
|
2003-02-25 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* ChangeLog: Point reader to the CHANGELOG file.
|
||||||
|
* Makefile.am (EXTRA_DIST): Rename avrdude.conf.sample to
|
||||||
|
avrdude.conf.in.
|
||||||
|
Remove avrdude.conf and distclean-local rules.
|
||||||
|
Add install-exec-local and backup-avrdude-conf rules.
|
||||||
|
* avrdude.conf.in:
|
||||||
|
Set default_parallel to "@DEFAULT_PAR_PORT@" for autoconf expansion.
|
||||||
|
Set default_serial to "@DEFAULT_SER_PORT@" for autoconf expansion.
|
||||||
|
* configure.ac: Add call to AC_CANONICAL_{BUILD,HOST,TARGET} macros.
|
||||||
|
Set DEFAULT_PAR_PORT and DEFAULT_SER_PORT based on $host.
|
||||||
|
Add copyright header.
|
||||||
|
Define avrdude_version so AC_INIT and AM_INIT_AUTOMAKE are sure
|
||||||
|
to get the same version.
|
||||||
|
|
||||||
|
* avrdude.conf.in, avrdude.conf.sample:
|
||||||
|
Renamed avrdude.conf.sample to avrdude.conf.in.
|
||||||
|
|
||||||
|
2003-02-25 Eric Weddington <eric@umginc.net>
|
||||||
|
|
||||||
|
* ppiwin.c: CRs again.
|
||||||
|
|
||||||
|
* confwin.c, confwin.h: Get rid of CRs.
|
||||||
|
|
||||||
|
* main.c, Makefile.am: Get rid of CRs again.
|
||||||
|
|
||||||
|
2003-02-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
* Makefile.am, main.c: Integrate Windows search of config files.
|
||||||
|
|
||||||
|
* confwin.c, confwin.h: config file search on Windows.
|
||||||
|
|
||||||
|
* ppiwin.c: Change port value from lpt1alt to lpt3. Other
|
||||||
|
formatting changes.
|
||||||
|
|
||||||
|
* windows/giveio.c:
|
||||||
|
Add giveio device driver source. Requires MS DDK to build.
|
||||||
|
|
||||||
|
* windows/giveio.sys: Add giveio device driver binary.
|
||||||
|
|
||||||
|
* giveio.sys, install_giveio.bat, remove_giveio.bat, status_giveio.bat:
|
||||||
|
Move Windows specific files.
|
||||||
|
|
||||||
|
* windows/loaddrv.c, windows/loaddrv.h, windows/remove_giveio.bat:
|
||||||
|
* windows/status_giveio.bat, windows/install_giveio.bat:
|
||||||
|
Add Windows specific files.
|
||||||
|
|
||||||
|
* main.c: Usage back to stderr.
|
||||||
|
|
||||||
|
2003-02-22 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* CHANGELOG: Add note about .avrduderc.
|
||||||
|
|
||||||
|
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, main.c,
|
||||||
|
* par.c, pgm.c, pgm.h:
|
||||||
|
Add the ability to read a per-user config file located at
|
||||||
|
$HOME/.avrduderc. Entries from .avrduderc take precedence over those
|
||||||
|
from the system wide config file in ${PREFIX}/etc/avrdude.conf.
|
||||||
|
|
||||||
|
Track and display the config file name and line number when we print
|
||||||
|
out the available parts and programmers. This is useful in case
|
||||||
|
someone has overridden a definition in their .avrduderc file and is
|
||||||
|
wondering why the definition in the system wide config file is not
|
||||||
|
being used.
|
||||||
|
|
||||||
|
Remove the default programmer 'stk500' from the distributed config
|
||||||
|
file.
|
||||||
|
|
||||||
|
* CHANGELOG: Spelling.
|
||||||
|
|
||||||
|
2003-02-21 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* CHANGELOG:
|
||||||
|
Put some stuff in the CHANGELOG for this upcoming new version before I
|
||||||
|
forget.
|
||||||
|
|
||||||
|
* main.c:
|
||||||
|
Update comment due to removal of the default parallel port pin config.
|
||||||
|
|
||||||
|
* config.c, config.h, config_gram.y, lexer.l, main.c:
|
||||||
|
* avrdude.conf.sample:
|
||||||
|
Introduce 'default_programmer' to the config file instead of requiring
|
||||||
|
one of the programmers to be tagged "default" within its definition.
|
||||||
|
|
||||||
|
Also, axe the notion of a compiled-in default programmer. It is
|
||||||
|
kind've pointless now that nearly all configuration comes from the
|
||||||
|
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>
|
||||||
|
|
||||||
|
* main.c: Change usage text to be verbose.
|
||||||
|
|
||||||
|
* giveio.sys: Add Windows parallel port device driver (binary).
|
||||||
|
|
||||||
|
* install_giveio.bat, remove_giveio.bat, status_giveio.bat:
|
||||||
|
Windows batch files to work with giveio.sys.
|
||||||
|
|
||||||
|
2003-02-21 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* avrdude.conf.sample, config.c, config.h, config_gram.y, lexer.l:
|
||||||
|
* main.c:
|
||||||
|
Add port name defaults to the config file instead of hard-coding.
|
||||||
|
This adds 'default_parallel' and 'default_serial' keywords to the
|
||||||
|
grammar, which take quoted string arguments.
|
||||||
|
|
||||||
|
* avrdude.conf.sample:
|
||||||
|
Document the recent additions to the config file.
|
||||||
|
|
||||||
|
* stk500.c, avr.c, avrpart.h, config_gram.y, lexer.l, par.c:
|
||||||
|
Add the ability to specify which pin to pulse when retrying entry into
|
||||||
|
programming mode. Use 'retry_pulse' in the per-part specification
|
||||||
|
that can currently take values of 'reset' or 'sck', the default being
|
||||||
|
'sck' which preserves the previous behaviour. Some newer parts
|
||||||
|
indicate that /RESET should be pulsed, while older parts say to pulse
|
||||||
|
SCK.
|
||||||
|
|
||||||
|
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||||
|
|
||||||
|
* main.c, par.c:
|
||||||
|
Make verbose global. Make debug code in par_cmd() based on verbose=2.
|
||||||
|
|
||||||
|
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* stk500.c: Fix pseudo/full parallel mode selection logic.
|
||||||
|
|
||||||
|
* avrdude.conf.sample:
|
||||||
|
Woops, didn't really mean to commit those changes that slipped in with
|
||||||
|
the last commit. Those were just there for testing.
|
||||||
|
|
||||||
|
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
|
||||||
|
* stk500.c:
|
||||||
|
Add 'serial' and 'parallel' keywords to the grammar so that one can
|
||||||
|
say whether parts support these programming modes or not. Possible
|
||||||
|
values for 'serial' are 'yes' or 'no'. Possible values for 'parallel'
|
||||||
|
are 'yes', 'no', or 'pseudo'. Add a bit mask of flags to the AVRPART
|
||||||
|
structure to capture these settings. Use these within
|
||||||
|
stk500_initialize() to set the device parameters correctly.
|
||||||
|
|
||||||
|
Defaults for 'serial' and 'parallel' are 'yes' unless specified
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||||
|
|
||||||
|
* Makefile.am, ppiwin.c: Get rid of CRs.
|
||||||
|
|
||||||
|
* Makefile.am: Add ppiwin.c to avrdude_SOURCES.
|
||||||
|
|
||||||
|
* ppiwin.c: Added ppiwin.c: Windows parallel port driver.
|
||||||
|
|
||||||
|
* stk500.c:
|
||||||
|
Add error message for fail to enter programming mode. Fix typos.
|
||||||
|
|
||||||
|
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
|
||||||
|
Add a few parameters needed for parallel programming: assignment of
|
||||||
|
PAGEL and BS2 signals and the disposition of the reset pin
|
||||||
|
('dedicated' or 'io').
|
||||||
|
|
||||||
|
2003-02-20 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* avrdude.1: Fix spacing for m169 entry. (tabs not spaces ;-)
|
||||||
|
|
||||||
|
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* avrdude.1, fileio.c, main.c: Add Motorola S-record support.
|
||||||
|
|
||||||
|
Submitted by: "Alexey V.Levdikov" <tsar@kemford.com>
|
||||||
|
|
||||||
|
2003-02-19 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* avrdude.1: Add m169 to list of supported targets.
|
||||||
|
|
||||||
|
2003-02-19 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* avrdude.conf.sample, avrdude.1:
|
||||||
|
My colleague contributed a part definition for the AT90S2343.
|
||||||
|
|
||||||
|
Submitted by: Mirko Kaffka <mirko@mkaffka.de>
|
||||||
|
|
||||||
|
2003-02-18 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* avrdude.conf.sample:
|
||||||
|
Add support for mega169. (tested with stk500 with 1.7 firmware)
|
||||||
|
|
||||||
|
* avrdude.conf.sample:
|
||||||
|
Add commments to separate parts (makes it easier for the eye to parse).
|
||||||
|
|
||||||
|
2003-02-15 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile.am: Add $srcdir to sample config filename so that
|
||||||
|
building in a separate dir works.
|
||||||
|
|
||||||
|
2003-02-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
Only GNU make sets $< in non-inference rules, so rather explicitly
|
||||||
|
spell the source file(s) to remain compatible.
|
||||||
|
|
||||||
|
2003-02-14 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile.am: Add distclean rule and EXTRA_DIST list to get 'make
|
||||||
|
distcheck' to succeed.
|
||||||
|
|
||||||
|
These changes add basic support for a autoconf/automake based
|
||||||
|
build system.
|
||||||
|
|
||||||
|
* .cvsignore: Ignore autoconf files.
|
||||||
|
* AUTHORS: New file.
|
||||||
|
* ChangeLog: New file.
|
||||||
|
* Makefile: Removed file.
|
||||||
|
* Makefile.am: New file.
|
||||||
|
* NEWS: New file.
|
||||||
|
* README: New file.
|
||||||
|
* bootstrap: New file.
|
||||||
|
* configure.ac: New file.
|
||||||
|
* avr.c: Include ac_cfg.h (generated by autoconf).
|
||||||
|
* config.c: Include ac_cfg.h.
|
||||||
|
Include config_gram.h instead of y.tab.h.
|
||||||
|
* config.h: If HAS_YYSTYPE is not defined, define YYSTYPE.
|
||||||
|
* config_gram.y: Include ac_cfg.h.
|
||||||
|
* fileio.c: Include ac_cfg.h.
|
||||||
|
* lexer.l: Include config_gram.h instead of y.tab.h.
|
||||||
|
* lists.c: Include ac_cfg.h.
|
||||||
|
* main.c: Include ac_cfg.h.
|
||||||
|
* par.c: Include ac_cfg.h.
|
||||||
|
* pgm.c: Include ac_cfg.h.
|
||||||
|
* ppi.c: Include ac_cfg.h.
|
||||||
|
* stk500.c: Include ac_cfg.h.
|
||||||
|
* term.c: Include ac_cfg.h.
|
||||||
|
|
||||||
|
2003-02-14 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* stk500.c: Fix typos. Fix error messages.
|
||||||
|
|
||||||
|
2003-02-13 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* Makefile, avrdude.conf.sample, config_gram.y, lexer.l, main.c:
|
||||||
|
* par.c, par.h, ppi.c, ppi.h, stk500.c:
|
||||||
|
Split higher level parallel port programmer code off from ppi.c into
|
||||||
|
its own file par.c, leaving low level parallel port accessor routines
|
||||||
|
in ppi.c to help with portability. Change the programmer type to
|
||||||
|
'PAR' now instead of 'PPI' - 'PAR' represents the parallel port
|
||||||
|
programmer type.
|
||||||
|
|
||||||
|
Be more liberal with 'static' function declarations within the
|
||||||
|
programmer implimentation files - these functions should never be
|
||||||
|
called directly - always use the programmer function references.
|
||||||
|
|
||||||
|
There are still a few places in 'main.c' that directly reference the
|
||||||
|
parallel programmer explicitly (par_getpinmask). These should be
|
||||||
|
fixed somehow.
|
||||||
|
|
||||||
|
Axe a few unused functions.
|
||||||
|
|
||||||
|
2003-02-12 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* .cvsignore: New file.
|
||||||
|
|
||||||
|
* stk500.c: Remove need for inttypes.h.
|
||||||
|
|
||||||
|
* lexer.l: Define YY_NO_UNPUT to quell a compiler warning.
|
||||||
|
|
||||||
|
* Makefile: Remove YACC assignment.
|
||||||
|
Add '-b y' options to YACC invocation.
|
||||||
|
Remove leading '-' from 'include .depend'.
|
||||||
|
|
||||||
|
2003-02-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* config_gram.y:
|
||||||
|
Declare the internally used static functions on top, to get rid of the
|
||||||
|
compiler warnings.
|
||||||
|
|
||||||
|
Reported by: bison-generated parsers
|
||||||
|
|
||||||
|
2003-02-11 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* linux_ppdev.h: New file.
|
||||||
|
* ppi.c: Include system dependant parallel port interface file.
|
||||||
|
(ppi_open): Add call to ppi_claim().
|
||||||
|
(ppi_close): Add call to ppi_release().
|
||||||
|
* ppi.h: Define ppi_claim() and ppi_release() as NOPs if not previously
|
||||||
|
defined.
|
||||||
|
* stk500.c: Include inttypes header to quell compiler warning.
|
||||||
|
|
||||||
|
2003-02-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
* pgm.c, ppi.c, stk500.c: Fix some implicit declaration warnings.
|
||||||
|
|
||||||
|
* config_gram.y:
|
||||||
|
Move the C declarations to the top of the file. While [b]yacc doesn't
|
||||||
|
care, bison does, and this is normally the way it's meant to be
|
||||||
|
anyway.
|
||||||
|
|
||||||
|
2003-02-11 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile: Generate dependencies specific to the target system.
|
||||||
|
Explicitly use byacc.
|
||||||
|
|
||||||
|
* Makefile:
|
||||||
|
Remove reference to avr-gcc in depend rule (cut & paste error).
|
||||||
|
|
||||||
|
2003-02-09 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h, stk500.c:
|
||||||
|
* stk500.h, stk500_private.h, term.c, term.h, CHANGELOG, COPYING:
|
||||||
|
* Makefile, avr.c, avr.h, avrdude.1, avrdude.conf.sample:
|
||||||
|
* avrdude.pdf, avrpart.h, config.c, config.h, config_gram.y:
|
||||||
|
* fileio.c, fileio.h, lexer.l, lists.c, lists.h:
|
||||||
|
Test commit in new public repository. Before this time this repo
|
||||||
|
existed on a private system. Commits made by 'bsd' on the old system
|
||||||
|
were made by Brian Dean (bdean on the current system).
|
||||||
|
|
||||||
|
2003-02-08 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c,
|
||||||
|
* config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
|
||||||
|
* lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
|
||||||
|
* stk500.c, stk500.h, term.c, term.h:
|
||||||
|
The last part of that last commit message should read:
|
||||||
|
|
||||||
|
All others - modify program description.
|
||||||
|
|
||||||
|
* Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c:
|
||||||
|
* config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
|
||||||
|
* lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
|
||||||
|
* stk500.c, stk500.h, term.c, term.h:
|
||||||
|
Makefile: include a target to automatically generate the dependency
|
||||||
|
list.
|
||||||
|
|
||||||
|
All others
|
||||||
|
|
||||||
|
2003-02-06 Brian S. Dean <bsd@bsdhome.com>
|
||||||
|
|
||||||
|
* avrdude.1: Update license to GPL, permission by Joerg Wunsch.
|
||||||
|
|
||||||
|
* lexer.l: Add GPL.
|
||||||
|
|
||||||
|
* Makefile, config_gram.y: Add GPL to the Makefile and config_gram.y.
|
||||||
|
|
||||||
|
* Makefile, stk500.h:
|
||||||
|
Add stk500.h as a dependency for stk500.c. Remove carraige returns
|
||||||
|
from stk500.h - don't know how those got in there (pointed out by Ted
|
||||||
|
Roth).
|
||||||
|
|
||||||
|
* COPYING, avr.c, avr.h, avrpart.h, config.c, config.h, fileio.c:
|
||||||
|
* fileio.h, lists.c, lists.h, main.c, pgm.c, pgm.h, pindefs.h:
|
||||||
|
* ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
|
||||||
|
Re-license using the GNU GPL. Thanks to Ted Roth for the patch.
|
||||||
|
|
||||||
|
* avr.c, avr.h, config.c, config.h, config_gram.y, fileio.c:
|
||||||
|
* fileio.h, lexer.l, lists.c, lists.h, main.c, pgm.c, pgm.h:
|
||||||
|
* pindefs.h, ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
|
||||||
|
Get rid of the verbose printing of individual file CVS version ids.
|
||||||
|
This was intended to be used for identifying code in the field for
|
||||||
|
incoming bug reports, but I've never really found it all that useful.
|
||||||
|
|
||||||
|
* CHANGELOG, Makefile, Makefile.inc, avr.c, avrdude.1:
|
||||||
|
* avrdude.conf.sample, config_gram.y, lexer.l, main.c, stk500.c:
|
||||||
|
* term.c:
|
||||||
|
Change the name from AVRPROG to AVRDUDE.
|
||||||
|
|
||||||
|
This change represents a name change only. There is currently an
|
||||||
|
effort to port AVRPROG to other platforms including Linux and Windows.
|
||||||
|
Since Atmel's programmer binary that's included within their AVR
|
||||||
|
Studio software is named AVRPROG.EXE on the Windows OS, there is the
|
||||||
|
chance for confusion if we keep calling this program AVRPROG as well.
|
||||||
|
Up until now the name hasn't really been a problem since there was no
|
||||||
|
chance to confuse 'avrprog' on Unix with Atmel's AVRPROG because
|
||||||
|
Atmel's tools only run on Windows. But with the Unix 'avrprog'
|
||||||
|
possibly being ported to Windows, I felt a name change was the best
|
||||||
|
way to avoid problems.
|
||||||
|
|
||||||
|
So - from this point forward, my FreeBSD Unix program formerly
|
||||||
|
known as AVRPROG will subsequently be known as AVRDUDE (AVR
|
||||||
|
Downloader/UploaDEr).
|
||||||
|
|
||||||
|
This change also represents a time when the AVRDUDE sources move from
|
||||||
|
my own private repository to a public repository. This will give
|
||||||
|
other developers a chance to port AVRDUDE to other platforms and
|
||||||
|
extend its functionality to support additional programming hardware,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
So goodbye AVRPROG, welcome AVRDUDE!
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
ChangeLog-2001 \
|
ChangeLog-2001 \
|
||||||
ChangeLog-2002 \
|
ChangeLog-2002 \
|
||||||
ChangeLog-2003 \
|
|
||||||
avrdude.1 \
|
avrdude.1 \
|
||||||
avrdude.pdf \
|
avrdude.pdf \
|
||||||
avrdude.spec \
|
avrdude.spec \
|
||||||
@@ -40,9 +39,7 @@ DIST_SUBDIRS = doc windows
|
|||||||
|
|
||||||
AM_YFLAGS = -d
|
AM_YFLAGS = -d
|
||||||
|
|
||||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||||
|
|
||||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
|
||||||
|
|
||||||
bin_PROGRAMS = avrdude
|
bin_PROGRAMS = avrdude
|
||||||
|
|
||||||
@@ -51,12 +48,7 @@ avrdude_SOURCES = \
|
|||||||
lexer.l \
|
lexer.l \
|
||||||
avr.c \
|
avr.c \
|
||||||
avr.h \
|
avr.h \
|
||||||
avr910.c \
|
|
||||||
avr910.h \
|
|
||||||
avrpart.c \
|
|
||||||
avrpart.h \
|
avrpart.h \
|
||||||
butterfly.c \
|
|
||||||
butterfly.h \
|
|
||||||
config.c \
|
config.c \
|
||||||
config.h \
|
config.h \
|
||||||
confwin.c \
|
confwin.c \
|
||||||
@@ -75,9 +67,6 @@ avrdude_SOURCES = \
|
|||||||
ppi.c \
|
ppi.c \
|
||||||
ppi.h \
|
ppi.h \
|
||||||
ppiwin.c \
|
ppiwin.c \
|
||||||
serial.h \
|
|
||||||
ser_posix.c \
|
|
||||||
ser_win32.c \
|
|
||||||
stk500.c \
|
stk500.c \
|
||||||
stk500.h \
|
stk500.h \
|
||||||
stk500_private.h \
|
stk500_private.h \
|
||||||
|
|||||||
76
avrdude/NEWS
76
avrdude/NEWS
@@ -6,84 +6,18 @@ Approximate change log for AVRDUDE by version.
|
|||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Current:
|
|
||||||
|
|
||||||
* Add ATmega8515 support.
|
|
||||||
Contributed by: Matthias Wei<65>er <matthias@matwei.de>
|
|
||||||
|
|
||||||
* Add ATmega64 support.
|
|
||||||
Contributed by: Erik Christiansen <erik@dd.nec.com.au>
|
|
||||||
|
|
||||||
* Improved polling algorithm to speed up
|
|
||||||
programming of byte oriented parallel programmers.
|
|
||||||
Contributed by: Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>
|
|
||||||
|
|
||||||
* Add "fuse" and "lock" definitions for the AT90S8535.
|
|
||||||
|
|
||||||
* STK500 skips empty pages in paged write resulting in faster downloads
|
|
||||||
when there are empty blocks in between code (such as files that contain
|
|
||||||
application code and bootloader code).
|
|
||||||
|
|
||||||
|
|
||||||
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
|
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 "Eric B. Weddington" <eric@ecentral.com>.
|
* Now support Windows - added by "E. Weddington" <eric@umginc.net>
|
||||||
|
|
||||||
* Use 'configure' scripts to tailor the code to the system avrdude
|
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
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 "
|
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||||
<tsar@kemford.com>.
|
<tsar@kemford.com>
|
||||||
|
|
||||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||||
'bs2' keywords to the config file for this purpose.
|
'bs2' keywords to the config file for this purpose.
|
||||||
@@ -299,4 +233,4 @@ Version 1.3.0 :
|
|||||||
|
|
||||||
Version 1.2.2 :
|
Version 1.2.2 :
|
||||||
|
|
||||||
* Initial public release.
|
* Initial public release
|
||||||
|
|||||||
720
avrdude/avr.c
720
avrdude/avr.c
@@ -25,8 +25,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
@@ -45,8 +43,255 @@ extern PROGRAMMER * pgm;
|
|||||||
extern int do_cycles;
|
extern int do_cycles;
|
||||||
|
|
||||||
|
|
||||||
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
AVRPART * avr_new_part(void)
|
||||||
unsigned long addr, unsigned char * value)
|
{
|
||||||
|
AVRPART * p;
|
||||||
|
|
||||||
|
p = (AVRPART *)malloc(sizeof(AVRPART));
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "new_part(): out of memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(p, 0, sizeof(*p));
|
||||||
|
|
||||||
|
p->id[0] = 0;
|
||||||
|
p->desc[0] = 0;
|
||||||
|
p->reset_disposition = RESET_DEDICATED;
|
||||||
|
p->retry_pulse = PIN_AVR_SCK;
|
||||||
|
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;
|
||||||
|
p->config_file[0] = 0;
|
||||||
|
p->lineno = 0;
|
||||||
|
|
||||||
|
p->mem = lcreat(NULL, 0);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OPCODE * avr_new_opcode(void)
|
||||||
|
{
|
||||||
|
OPCODE * m;
|
||||||
|
|
||||||
|
m = (OPCODE *)malloc(sizeof(*m));
|
||||||
|
if (m == NULL) {
|
||||||
|
fprintf(stderr, "avr_new_opcode(): out of memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(m, 0, sizeof(*m));
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AVRMEM * avr_new_memtype(void)
|
||||||
|
{
|
||||||
|
AVRMEM * m;
|
||||||
|
|
||||||
|
m = (AVRMEM *)malloc(sizeof(*m));
|
||||||
|
if (m == NULL) {
|
||||||
|
fprintf(stderr, "avr_new_memtype(): out of memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(m, 0, sizeof(*m));
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AVRMEM * avr_dup_mem(AVRMEM * m)
|
||||||
|
{
|
||||||
|
AVRMEM * n;
|
||||||
|
|
||||||
|
n = avr_new_memtype();
|
||||||
|
|
||||||
|
*n = *m;
|
||||||
|
|
||||||
|
n->buf = (unsigned char *)malloc(n->size);
|
||||||
|
if (n->buf == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||||
|
n->size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(n->buf, 0, n->size);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AVRPART * avr_dup_part(AVRPART * d)
|
||||||
|
{
|
||||||
|
AVRPART * p;
|
||||||
|
LISTID save;
|
||||||
|
LNODEID ln;
|
||||||
|
|
||||||
|
p = avr_new_part();
|
||||||
|
save = p->mem;
|
||||||
|
|
||||||
|
*p = *d;
|
||||||
|
|
||||||
|
p->mem = save;
|
||||||
|
|
||||||
|
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
||||||
|
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||||
|
{
|
||||||
|
AVRMEM * m, * match;
|
||||||
|
LNODEID ln;
|
||||||
|
int matches;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
l = strlen(desc);
|
||||||
|
matches = 0;
|
||||||
|
match = NULL;
|
||||||
|
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||||
|
m = ldata(ln);
|
||||||
|
if (strncmp(desc, m->desc, l) == 0) {
|
||||||
|
match = m;
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches == 1)
|
||||||
|
return match;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avr_set_bits()
|
||||||
|
*
|
||||||
|
* Set instruction bits in the specified command based on the opcode.
|
||||||
|
*/
|
||||||
|
int avr_set_bits(OPCODE * op, unsigned char * cmd)
|
||||||
|
{
|
||||||
|
int i, j, bit;
|
||||||
|
unsigned char mask;
|
||||||
|
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if (op->bit[i].type == AVR_CMDBIT_VALUE) {
|
||||||
|
j = 3 - i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
mask = 1 << bit;
|
||||||
|
if (op->bit[i].value)
|
||||||
|
cmd[j] = cmd[j] | mask;
|
||||||
|
else
|
||||||
|
cmd[j] = cmd[j] & ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avr_set_addr()
|
||||||
|
*
|
||||||
|
* Set address bits in the specified command based on the opcode, and
|
||||||
|
* the address.
|
||||||
|
*/
|
||||||
|
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
|
||||||
|
{
|
||||||
|
int i, j, bit;
|
||||||
|
unsigned long value;
|
||||||
|
unsigned char mask;
|
||||||
|
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
|
||||||
|
j = 3 - i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
mask = 1 << bit;
|
||||||
|
value = addr >> op->bit[i].bitno & 0x01;
|
||||||
|
if (value)
|
||||||
|
cmd[j] = cmd[j] | mask;
|
||||||
|
else
|
||||||
|
cmd[j] = cmd[j] & ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avr_set_input()
|
||||||
|
*
|
||||||
|
* Set input data bits in the specified command based on the opcode,
|
||||||
|
* and the data byte.
|
||||||
|
*/
|
||||||
|
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
|
||||||
|
{
|
||||||
|
int i, j, bit;
|
||||||
|
unsigned char value;
|
||||||
|
unsigned char mask;
|
||||||
|
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if (op->bit[i].type == AVR_CMDBIT_INPUT) {
|
||||||
|
j = 3 - i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
mask = 1 << bit;
|
||||||
|
value = data >> op->bit[i].bitno & 0x01;
|
||||||
|
if (value)
|
||||||
|
cmd[j] = cmd[j] | mask;
|
||||||
|
else
|
||||||
|
cmd[j] = cmd[j] & ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avr_get_output()
|
||||||
|
*
|
||||||
|
* Retreive output data bits from the command results based on the
|
||||||
|
* opcode data.
|
||||||
|
*/
|
||||||
|
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
||||||
|
{
|
||||||
|
int i, j, bit;
|
||||||
|
unsigned char value;
|
||||||
|
unsigned char mask;
|
||||||
|
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
|
||||||
|
j = 3 - i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
mask = 1 << bit;
|
||||||
|
value = ((res[j] & mask) >> bit) & 0x01;
|
||||||
|
value = value << op->bit[i].bitno;
|
||||||
|
if (value)
|
||||||
|
*data = *data | value;
|
||||||
|
else
|
||||||
|
*data = *data & ~value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
unsigned char res[4];
|
unsigned char res[4];
|
||||||
@@ -95,53 +340,6 @@ int avr_read_byte_default(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
|
* Read the entirety of the specified memory type into the
|
||||||
* corresponding buffer of the avrpart pointed to by 'p'. If size =
|
* corresponding buffer of the avrpart pointed to by 'p'. If size =
|
||||||
@@ -157,6 +355,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
AVRMEM * mem;
|
AVRMEM * mem;
|
||||||
int rc;
|
int rc;
|
||||||
|
int printed;
|
||||||
|
|
||||||
mem = avr_locate_mem(p, memtype);
|
mem = avr_locate_mem(p, memtype);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
@@ -170,11 +369,6 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
size = mem->size;
|
size = mem->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* start with all 0xff
|
|
||||||
*/
|
|
||||||
memset(buf, 0xff, size);
|
|
||||||
|
|
||||||
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
|
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
|
||||||
if (pgm->paged_load != NULL) {
|
if (pgm->paged_load != NULL) {
|
||||||
/*
|
/*
|
||||||
@@ -183,27 +377,16 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
* instead
|
* instead
|
||||||
*/
|
*/
|
||||||
if (mem->paged) {
|
if (mem->paged) {
|
||||||
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
return pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||||
if (rc < 0)
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
|
return 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(mem->desc, "signature") == 0) {
|
|
||||||
if (pgm->read_sig_bytes) {
|
printed = 0;
|
||||||
return pgm->read_sig_bytes(pgm, p, mem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
|
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
|
||||||
@@ -216,13 +399,19 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
buf[i] = rbyte;
|
buf[i] = rbyte;
|
||||||
report_progress(i, size, NULL);
|
if (verbose) {
|
||||||
|
if ((i % 16 == 0)||(i == (size-1))) {
|
||||||
|
printed = 1;
|
||||||
|
fprintf(stderr, "\r \r%6lu", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(mem->desc, "flash") == 0)
|
if (printed) {
|
||||||
return avr_mem_hiaddr(mem);
|
fprintf(stderr, "\n");
|
||||||
else
|
}
|
||||||
return i;
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -262,7 +451,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* since we don't know what voltage the target AVR is powered by, be
|
* since we don't know what voltage the target AVR is powered by, be
|
||||||
* conservative and delay the max amount the spec says to wait
|
* conservative and delay the max amount the spec says to wait
|
||||||
*/
|
*/
|
||||||
usleep(mem->max_write_delay);
|
usleep(mem->max_write_delay);
|
||||||
|
|
||||||
@@ -271,7 +460,10 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int avr_write_byte_default(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)
|
unsigned long addr, unsigned char data)
|
||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
@@ -279,14 +471,11 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
unsigned char r;
|
unsigned char r;
|
||||||
int ready;
|
int ready;
|
||||||
int tries;
|
int tries;
|
||||||
unsigned long start_time;
|
|
||||||
unsigned long prog_time;
|
|
||||||
unsigned char b;
|
unsigned char b;
|
||||||
unsigned short caddr;
|
unsigned short caddr;
|
||||||
OPCODE * writeop;
|
OPCODE * writeop;
|
||||||
int rc;
|
int rc;
|
||||||
int readok=0;
|
int readok=0;
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
if (!mem->paged) {
|
if (!mem->paged) {
|
||||||
/*
|
/*
|
||||||
@@ -376,6 +565,13 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
tries = 0;
|
tries = 0;
|
||||||
ready = 0;
|
ready = 0;
|
||||||
while (!ready) {
|
while (!ready) {
|
||||||
|
usleep(mem->min_write_delay);
|
||||||
|
rc = avr_read_byte(pgm, p, mem, addr, &r);
|
||||||
|
if (rc != 0) {
|
||||||
|
pgm->pgm_led(pgm, OFF);
|
||||||
|
pgm->err_led(pgm, ON);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
if ((data == mem->readback[0]) ||
|
if ((data == mem->readback[0]) ||
|
||||||
(data == mem->readback[1])) {
|
(data == mem->readback[1])) {
|
||||||
@@ -393,29 +589,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
gettimeofday (&tv, NULL);
|
|
||||||
start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
|
|
||||||
do {
|
|
||||||
/*
|
|
||||||
* Do polling, but timeout after max_write_delay.
|
|
||||||
*/
|
|
||||||
rc = avr_read_byte(pgm, p, mem, addr, &r);
|
|
||||||
if (rc != 0) {
|
|
||||||
pgm->pgm_led(pgm, OFF);
|
|
||||||
pgm->err_led(pgm, ON);
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
gettimeofday (&tv, NULL);
|
|
||||||
prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
|
|
||||||
} while ((r != data) &&
|
|
||||||
((prog_time-start_time) < mem->max_write_delay));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* At this point we either have a valid readback or the
|
|
||||||
* max_write_delay is expired.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (r == data) {
|
if (r == data) {
|
||||||
ready = 1;
|
ready = 1;
|
||||||
@@ -428,6 +601,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
* memory bits but not all. We only actually power-off the
|
* memory bits but not all. We only actually power-off the
|
||||||
* device if the data read back does not match what we wrote.
|
* device if the data read back does not match what we wrote.
|
||||||
*/
|
*/
|
||||||
|
usleep(mem->max_write_delay); /* maximum write delay */
|
||||||
pgm->pgm_led(pgm, OFF);
|
pgm->pgm_led(pgm, OFF);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: this device must be powered off and back on to continue\n",
|
"%s: this device must be powered off and back on to continue\n",
|
||||||
@@ -474,26 +648,6 @@ int avr_write_byte_default(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
|
* Write the whole memory region of the specified memory from the
|
||||||
* corresponding buffer of the avrpart pointed to by 'p'. Write up to
|
* corresponding buffer of the avrpart pointed to by 'p'. Write up to
|
||||||
@@ -512,6 +666,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
unsigned char data;
|
unsigned char data;
|
||||||
int werror;
|
int werror;
|
||||||
AVRMEM * m;
|
AVRMEM * m;
|
||||||
|
int printed;
|
||||||
|
|
||||||
m = avr_locate_mem(p, memtype);
|
m = avr_locate_mem(p, memtype);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
@@ -522,6 +677,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
|
|
||||||
pgm->err_led(pgm, OFF);
|
pgm->err_led(pgm, OFF);
|
||||||
|
|
||||||
|
printed = 0;
|
||||||
werror = 0;
|
werror = 0;
|
||||||
|
|
||||||
wsize = m->size;
|
wsize = m->size;
|
||||||
@@ -548,14 +704,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++) {
|
for (i=0; i<wsize; i++) {
|
||||||
data = m->buf[i];
|
data = m->buf[i];
|
||||||
report_progress(i, wsize, NULL);
|
if (verbose) {
|
||||||
|
if ((i % 16 == 0)||(i == (wsize-1))) {
|
||||||
|
fprintf(stderr, "\r \r%6lu", i);
|
||||||
|
printed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
rc = avr_write_byte(pgm, p, m, i, data);
|
rc = avr_write_byte(pgm, p, m, i, data);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, " ***failed; ");
|
fprintf(stderr, " ***failed; ");
|
||||||
@@ -588,11 +744,15 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||||||
if (werror) {
|
if (werror) {
|
||||||
/*
|
/*
|
||||||
* make sure the error led stay on if there was a previous write
|
* make sure the error led stay on if there was a previous write
|
||||||
* error, otherwise it gets cleared in avr_write_byte()
|
* error, otherwise it gets cleared in avr_write_byte()
|
||||||
*/
|
*/
|
||||||
pgm->err_led(pgm, ON);
|
pgm->err_led(pgm, ON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (printed)
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,15 +765,36 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
report_progress (0,1,"Reading");
|
|
||||||
rc = avr_read(pgm, p, "signature", 0, 0);
|
rc = avr_read(pgm, p, "signature", 0, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: error reading signature data for part \"%s\", rc=%d\n",
|
"%s: error reading signature data for part \"%s\", rc=%d\n",
|
||||||
progname, p->desc, rc);
|
progname, p->desc, rc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
report_progress (1,1,NULL);
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and initialize memory buffers for each of the device's
|
||||||
|
* defined memory regions.
|
||||||
|
*/
|
||||||
|
int avr_initmem(AVRPART * p)
|
||||||
|
{
|
||||||
|
LNODEID ln;
|
||||||
|
AVRMEM * m;
|
||||||
|
|
||||||
|
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||||
|
m = ldata(ln);
|
||||||
|
m->buf = (unsigned char *) malloc(m->size);
|
||||||
|
if (m->buf == NULL) {
|
||||||
|
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
|
||||||
|
progname, m->desc, m->size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -624,7 +805,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
* may be a subset of p. The byte range of p should cover the whole
|
* may be a subset of p. The byte range of p should cover the whole
|
||||||
* chip's memory size.
|
* chip's memory size.
|
||||||
*
|
*
|
||||||
* Return the number of bytes verified, or -1 if they don't match.
|
* Return the number of bytes verified, or -1 if they don't match.
|
||||||
*/
|
*/
|
||||||
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
||||||
{
|
{
|
||||||
@@ -682,37 +863,54 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
|||||||
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
|
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
|
||||||
{
|
{
|
||||||
AVRMEM * a;
|
AVRMEM * a;
|
||||||
unsigned int cycle_count = 0;
|
int cycle_count;
|
||||||
unsigned char v1;
|
unsigned char v1, v2, v3, v4;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
|
||||||
|
|
||||||
a = avr_locate_mem(p, "eeprom");
|
a = avr_locate_mem(p, "eeprom");
|
||||||
if (a == NULL) {
|
if (a == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=4; i>0; i--) {
|
rc = avr_read_byte(pgm, p, a, a->size-4, &v1);
|
||||||
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||||
progname, rc);
|
progname, rc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cycle_count = (cycle_count << 8) | v1;
|
|
||||||
|
rc = avr_read_byte(pgm, p, a, a->size-3, &v2);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||||
|
progname, rc);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
rc = avr_read_byte(pgm, p, a, a->size-2, &v3);
|
||||||
* If the EEPROM is erased, the cycle count reads 0xffffffff.
|
if (rc < 0) {
|
||||||
* In this case we return a cycle_count of zero.
|
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||||
* So, the calling function don't have to care about whether or not
|
progname, rc);
|
||||||
* the cycle count was initialized.
|
return -1;
|
||||||
*/
|
|
||||||
if (cycle_count == 0xffffffff) {
|
|
||||||
cycle_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*cycles = (int) cycle_count;
|
rc = avr_read_byte(pgm, p, a, a->size-1, &v4);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||||
|
progname, rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((v1 == 0xff) && (v2 == 0xff) && (v3 != 0xff) && (v4 != 0xff)) {
|
||||||
|
v1 = 0;
|
||||||
|
v2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_count = (((unsigned int)v1) << 24) |
|
||||||
|
(((unsigned int)v2) << 16) |
|
||||||
|
(((unsigned int)v3) << 8) |
|
||||||
|
v4;
|
||||||
|
|
||||||
|
*cycles = cycle_count;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -721,56 +919,214 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
|
|||||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
|
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
|
||||||
{
|
{
|
||||||
AVRMEM * a;
|
AVRMEM * a;
|
||||||
unsigned char v1;
|
unsigned char v1, v2, v3, v4;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
|
||||||
|
|
||||||
a = avr_locate_mem(p, "eeprom");
|
a = avr_locate_mem(p, "eeprom");
|
||||||
if (a == NULL) {
|
if (a == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=1; i<=4; i++) {
|
v4 = cycles & 0x0ff;
|
||||||
v1 = cycles & 0xff;
|
v3 = (cycles & 0x0ff00) >> 8;
|
||||||
cycles = cycles >> 8;
|
v2 = (cycles & 0x0ff0000) >> 16;
|
||||||
|
v1 = (cycles & 0x0ff000000) >> 24;
|
||||||
|
|
||||||
rc = avr_write_byte(pgm, p, a, a->size-i, v1);
|
rc = avr_write_byte(pgm, p, a, a->size-4, v1);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
|
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
|
||||||
progname, rc);
|
progname, rc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
rc = avr_write_byte(pgm, p, a, a->size-3, v2);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
|
||||||
|
progname, rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rc = avr_write_byte(pgm, p, a, a->size-2, v3);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
|
||||||
|
progname, rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rc = avr_write_byte(pgm, p, a, a->size-1, v4);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
|
||||||
|
progname, rc);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|
||||||
|
|
||||||
|
char * avr_op_str(int op)
|
||||||
{
|
{
|
||||||
int cycles;
|
switch (op) {
|
||||||
int rc;
|
case AVR_OP_READ : return "READ"; break;
|
||||||
|
case AVR_OP_WRITE : return "WRITE"; break;
|
||||||
|
case AVR_OP_READ_LO : return "READ_LO"; break;
|
||||||
|
case AVR_OP_READ_HI : return "READ_HI"; break;
|
||||||
|
case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
|
||||||
|
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
|
||||||
|
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
|
||||||
|
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
|
||||||
|
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
|
||||||
|
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
|
||||||
|
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
|
||||||
|
default : return "<unknown opcode>"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (do_cycles) {
|
|
||||||
rc = avr_get_cycle_count(pgm, p, &cycles);
|
char * bittype(int type)
|
||||||
/*
|
{
|
||||||
* Don't update the cycle counter, if read failed
|
switch (type) {
|
||||||
*/
|
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
|
||||||
if(rc != 0) {
|
case AVR_CMDBIT_VALUE : return "VALUE"; break;
|
||||||
do_cycles = 0;
|
case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
|
||||||
|
case AVR_CMDBIT_INPUT : return "INPUT"; break;
|
||||||
|
case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
|
||||||
|
default : return "<unknown bit type>"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
||||||
|
int verbose)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char * optr;
|
||||||
|
|
||||||
|
if (m == NULL) {
|
||||||
|
fprintf(f,
|
||||||
|
"%s Page Polled\n"
|
||||||
|
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
|
||||||
|
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
|
||||||
|
prefix, prefix, prefix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (verbose > 2) {
|
||||||
|
fprintf(f,
|
||||||
|
"%s Page Polled\n"
|
||||||
|
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
|
||||||
|
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
|
||||||
|
prefix, prefix, prefix);
|
||||||
|
}
|
||||||
|
fprintf(f,
|
||||||
|
"%s%-11s %-6s %6d %4d %5d %5d %5d 0x%02x 0x%02x\n",
|
||||||
|
prefix, m->desc,
|
||||||
|
m->paged ? "yes" : "no",
|
||||||
|
m->size,
|
||||||
|
m->page_size,
|
||||||
|
m->num_pages,
|
||||||
|
m->min_write_delay,
|
||||||
|
m->max_write_delay,
|
||||||
|
m->readback[0],
|
||||||
|
m->readback[1]);
|
||||||
|
if (verbose > 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s Memory Ops:\n"
|
||||||
|
"%s Oeration Inst Bit Bit Type Bitno Value\n"
|
||||||
|
"%s ----------- -------- -------- ----- -----\n",
|
||||||
|
prefix, prefix, prefix);
|
||||||
|
for (i=0; i<AVR_OP_MAX; i++) {
|
||||||
|
if (m->op[i]) {
|
||||||
|
for (j=31; j>=0; j--) {
|
||||||
|
if (j==31)
|
||||||
|
optr = avr_op_str(i);
|
||||||
|
else
|
||||||
|
optr = " ";
|
||||||
|
fprintf(f,
|
||||||
|
"%s %-11s %8d %8s %5d %5d\n",
|
||||||
|
prefix, optr, j,
|
||||||
|
bittype(m->op[i]->bit[j].type),
|
||||||
|
m->op[i]->bit[j].bitno,
|
||||||
|
m->op[i]->bit[j].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc = pgm->chip_erase(pgm, p);
|
|
||||||
|
|
||||||
/*
|
char * reset_disp_str(int r)
|
||||||
* Don't update the cycle counter, if erase failed
|
{
|
||||||
*/
|
switch (r) {
|
||||||
if (do_cycles && (rc == 0)) {
|
case RESET_DEDICATED : return "dedicated";
|
||||||
cycles++;
|
case RESET_IO : return "possible i/o";
|
||||||
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
default : return "<invalid>";
|
||||||
progname, cycles);
|
}
|
||||||
avr_put_cycle_count(pgm, p, cycles);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char * pin_name(int pinno)
|
||||||
|
{
|
||||||
|
switch (pinno) {
|
||||||
|
case PIN_AVR_RESET : return "RESET";
|
||||||
|
case PIN_AVR_MISO : return "MISO";
|
||||||
|
case PIN_AVR_MOSI : return "MOSI";
|
||||||
|
case PIN_AVR_SCK : return "SCK";
|
||||||
|
default : return "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char * buf;
|
||||||
|
char * px;
|
||||||
|
LNODEID ln;
|
||||||
|
AVRMEM * m;
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"%sAVR Part : %s\n"
|
||||||
|
"%sChip Erase delay : %d us\n"
|
||||||
|
"%sPAGEL : P%02X\n"
|
||||||
|
"%sBS2 : P%02X\n"
|
||||||
|
"%sRESET disposition : %s\n"
|
||||||
|
"%sRETRY pulse : %s\n"
|
||||||
|
"%sserial program mode : %s\n"
|
||||||
|
"%sparallel program mode : %s\n"
|
||||||
|
"%sMemory Detail :\n\n",
|
||||||
|
prefix, p->desc,
|
||||||
|
prefix, p->chip_erase_delay,
|
||||||
|
prefix, p->pagel,
|
||||||
|
prefix, p->bs2,
|
||||||
|
prefix, reset_disp_str(p->reset_disposition),
|
||||||
|
prefix, pin_name(p->retry_pulse),
|
||||||
|
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
|
||||||
|
prefix, (p->flags & AVRPART_PARALLELOK) ?
|
||||||
|
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
|
||||||
|
prefix);
|
||||||
|
|
||||||
|
px = prefix;
|
||||||
|
i = strlen(prefix) + 5;
|
||||||
|
buf = (char *)malloc(i);
|
||||||
|
if (buf == NULL) {
|
||||||
|
/* ugh, this is not important enough to bail, just ignore it */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcpy(buf, prefix);
|
||||||
|
strcat(buf, " ");
|
||||||
|
px = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose <= 2) {
|
||||||
|
avr_mem_display(px, f, NULL, 0, verbose);
|
||||||
|
}
|
||||||
|
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||||
|
m = ldata(ln);
|
||||||
|
avr_mem_display(px, f, m, i, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
if (buf)
|
||||||
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,14 +33,29 @@
|
|||||||
extern struct avrpart parts[];
|
extern struct avrpart parts[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AVRPART * avr_find_part(char * p);
|
||||||
|
|
||||||
|
AVRPART * avr_new_part(void);
|
||||||
|
|
||||||
|
OPCODE * avr_new_opcode(void);
|
||||||
|
|
||||||
|
AVRMEM * avr_new_memtype(void);
|
||||||
|
|
||||||
|
AVRPART * avr_dup_part(AVRPART * d);
|
||||||
|
|
||||||
|
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
||||||
|
|
||||||
int avr_txrx_bit(int fd, int bit);
|
int avr_txrx_bit(int fd, int bit);
|
||||||
|
|
||||||
unsigned char avr_txrx(int fd, unsigned char byte);
|
unsigned char avr_txrx(int fd, unsigned char byte);
|
||||||
|
|
||||||
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
||||||
|
|
||||||
|
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
unsigned long addr, unsigned char * value);
|
unsigned long addr, unsigned char * value);
|
||||||
|
|
||||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||||
int verbose);
|
int verbose);
|
||||||
|
|
||||||
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
@@ -49,7 +64,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
unsigned long addr, unsigned char data);
|
unsigned long addr, unsigned char data);
|
||||||
|
|
||||||
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||||
int verbose);
|
int verbose);
|
||||||
|
|
||||||
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
|
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
|
||||||
@@ -60,17 +75,13 @@ int avr_initmem(AVRPART * p);
|
|||||||
|
|
||||||
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
|
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
|
||||||
|
|
||||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
||||||
int verbose);
|
int verbose);
|
||||||
|
|
||||||
|
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
||||||
|
|
||||||
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||||
|
|
||||||
int avr_put_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);
|
|
||||||
|
|
||||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
|
||||||
|
|
||||||
extern void report_progress (int completed, int total, char *hdr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
671
avrdude/avr910.c
671
avrdude/avr910.c
@@ -1,671 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
|
|
||||||
{
|
|
||||||
return serial_send(pgm->fd, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
|
||||||
{
|
|
||||||
return serial_recv(pgm->fd, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_drain(PROGRAMMER * pgm, int display)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_err_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_pgm_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int avr910_vfy_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* issue the 'chip erase' command to the AVR device
|
|
||||||
*/
|
|
||||||
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* apply power to the AVR processor
|
|
||||||
*/
|
|
||||||
static void avr910_powerup(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* remove power from the AVR processor
|
|
||||||
*/
|
|
||||||
static void avr910_powerdown(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
AVRPART * part;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
part = locate_part_by_avr910_devcode(part_list, c);
|
|
||||||
|
|
||||||
fprintf(stderr, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void avr910_restore(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void avr910_disable(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void avr910_enable(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
/* 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];
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If baudrate was not specified use 19.200 Baud
|
|
||||||
*/
|
|
||||||
if(pgm->baudrate == 0) {
|
|
||||||
pgm->baudrate = 19200;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(pgm->port, port);
|
|
||||||
pgm->fd = serial_open(port, pgm->baudrate);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* drain any extraneous input
|
|
||||||
*/
|
|
||||||
avr910_drain (pgm, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void avr910_close(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
avr910_leave_prog_mode(pgm);
|
|
||||||
|
|
||||||
serial_close(pgm->fd);
|
|
||||||
pgm->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void avr910_display(PROGRAMMER * pgm, char * p)
|
|
||||||
{
|
|
||||||
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];
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.Dd DATE November 26, 2003
|
.Dd DATE January 11, 2002
|
||||||
.Os
|
.Os
|
||||||
.Dt AVRDUDE 1
|
.Dt AVRDUDE 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -30,7 +30,6 @@
|
|||||||
.Fl p Ar partno
|
.Fl p Ar partno
|
||||||
.Op Fl c Ar programmer-id
|
.Op Fl c Ar programmer-id
|
||||||
.Op Fl C Ar config-file
|
.Op Fl C Ar config-file
|
||||||
.Op Fl D
|
|
||||||
.Op Fl e
|
.Op Fl e
|
||||||
.Oo Fl E Ar exitspec Ns
|
.Oo Fl E Ar exitspec Ns
|
||||||
.Op \&, Ns Ar exitspec
|
.Op \&, Ns Ar exitspec
|
||||||
@@ -42,9 +41,7 @@
|
|||||||
.Op Fl o Ar filename
|
.Op Fl o Ar filename
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
.Op Fl P Ar port
|
.Op Fl P Ar port
|
||||||
.Op Fl q
|
|
||||||
.Op Fl t
|
.Op Fl t
|
||||||
.Op Fl U Ar memtype:op:filename:filefmt
|
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Op Fl V
|
.Op Fl V
|
||||||
.Op Fl y
|
.Op Fl y
|
||||||
@@ -115,9 +112,6 @@ been code-protected previously, of course) and store the data in a
|
|||||||
file. Finally, a ``terminal'' mode is available that allows one to
|
file. Finally, a ``terminal'' mode is available that allows one to
|
||||||
interactively communicate with the MCU, and to display or program
|
interactively communicate with the MCU, and to display or program
|
||||||
individual memory cells.
|
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
|
.Ss Options
|
||||||
In order to control all the different operation modi, a number of options
|
In order to control all the different operation modi, a number of options
|
||||||
need to be specified to
|
need to be specified to
|
||||||
@@ -181,19 +175,6 @@ submit a patch back to the author so that it can be incorporated for
|
|||||||
the next version). See the config file, located at
|
the next version). See the config file, located at
|
||||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||||
which contains a description of the format.
|
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
|
.It Fl e
|
||||||
Causes a chip erase to be executed. This will reset the contents of the
|
Causes a chip erase to be executed. This will reset the contents of the
|
||||||
flash ROM and EEPROM to the value
|
flash ROM and EEPROM to the value
|
||||||
@@ -258,10 +239,8 @@ Multiple
|
|||||||
.Ar exitspec
|
.Ar exitspec
|
||||||
arguments can be separated with commas.
|
arguments can be separated with commas.
|
||||||
.It Fl f Ar format
|
.It Fl f Ar format
|
||||||
(Deprecated, use
|
This option specifies the file format for the input or output files
|
||||||
.Fl U
|
to be processed.
|
||||||
instead.) This option specifies the file format for the input or
|
|
||||||
output files to be processed.
|
|
||||||
.Ar Format
|
.Ar Format
|
||||||
can be one of:
|
can be one of:
|
||||||
.Bl -tag -width sss
|
.Bl -tag -width sss
|
||||||
@@ -271,10 +250,6 @@ Intel Hex
|
|||||||
Motorola S-record
|
Motorola S-record
|
||||||
.It Ar r
|
.It Ar r
|
||||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
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
|
.It Ar a
|
||||||
auto detect; valid for input only, and only if the input is not
|
auto detect; valid for input only, and only if the input is not
|
||||||
provided at
|
provided at
|
||||||
@@ -292,31 +267,15 @@ that a device has a broken (erased or overwritten) device signature
|
|||||||
but is otherwise operating normally, this options is provided to
|
but is otherwise operating normally, this options is provided to
|
||||||
override the check.
|
override the check.
|
||||||
.It Fl i Ar filename
|
.It Fl i Ar filename
|
||||||
(Deprecated, use
|
Specifies the input file to be programmed into the MCU. Can be specified
|
||||||
.Fl U
|
as
|
||||||
instead.) Specifies the input file to be programmed into the MCU.
|
|
||||||
Can be specified as
|
|
||||||
.Ql \&-
|
.Ql \&-
|
||||||
to use
|
to use
|
||||||
.Em stdin
|
.Em stdin
|
||||||
as the input.
|
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
|
.It Fl m Ar memtype
|
||||||
(Deprecated, use
|
Specifies which program area of the MCU to read or write; allowable
|
||||||
.Fl U
|
values depend on the MCU being programmed, but most support at least
|
||||||
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
|
.Em eeprom
|
||||||
for the EEPROM, and
|
for the EEPROM, and
|
||||||
.Em flash
|
.Em flash
|
||||||
@@ -332,11 +291,8 @@ No-write - disables actually writing data to the MCU (useful for debugging
|
|||||||
.Nm avrdude
|
.Nm avrdude
|
||||||
).
|
).
|
||||||
.It Fl o Ar filename
|
.It Fl o Ar filename
|
||||||
(Deprecated, use
|
Specifies the name of the output file to write, and causes the respective
|
||||||
.Fl U
|
memory area to be read from the MCU. Can be specified as
|
||||||
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 \&-
|
.Ql \&-
|
||||||
to write to
|
to write to
|
||||||
.Em stdout .
|
.Em stdout .
|
||||||
@@ -351,49 +307,11 @@ serial port, the
|
|||||||
.Pa /dev/cuaa0
|
.Pa /dev/cuaa0
|
||||||
port is the default. If you need to use a different parallel or
|
port is the default. If you need to use a different parallel or
|
||||||
serial port, use this option to specify the alternate port name.
|
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
|
.It Fl t
|
||||||
Tells
|
Tells
|
||||||
.Nm
|
.Nm
|
||||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||||
files. See below for a detailed description of the terminal mode.
|
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.
|
|
||||||
Note that if
|
|
||||||
.Ar filename
|
|
||||||
contains a colon, the
|
|
||||||
.Ar format
|
|
||||||
field is no longer optional since the filename part following the colon
|
|
||||||
would otherwise be misinterpreted as
|
|
||||||
.Ar format .
|
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Enable verbose output.
|
Enable verbose output.
|
||||||
.It Fl V
|
.It Fl V
|
||||||
@@ -467,35 +385,6 @@ does not implement the command.
|
|||||||
Display the device signature bytes.
|
Display the device signature bytes.
|
||||||
.It Ar part
|
.It Ar part
|
||||||
Display the current part settings.
|
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 \&?
|
||||||
.It Ar help
|
.It Ar help
|
||||||
Give a short on-line summary of the available commands.
|
Give a short on-line summary of the available commands.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,6 @@
|
|||||||
## @configure_input@
|
## @configure_input@
|
||||||
##
|
##
|
||||||
|
|
||||||
%define debug_package %{nil}
|
|
||||||
|
|
||||||
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||||
Name: avrdude
|
Name: avrdude
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
@@ -45,9 +43,6 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
|
|||||||
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
||||||
install
|
install
|
||||||
|
|
||||||
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
|
|
||||||
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
@@ -73,17 +68,11 @@ fi
|
|||||||
%attr(0644,root,root) %config /etc/avrdude.conf
|
%attr(0644,root,root) %config /etc/avrdude.conf
|
||||||
|
|
||||||
%files docs
|
%files docs
|
||||||
%doc doc/avrdude-html/*.html
|
%doc doc/avrdude-html
|
||||||
%doc doc/TODO
|
|
||||||
%doc doc/avrdude.ps
|
%doc doc/avrdude.ps
|
||||||
%doc doc/avrdude.pdf
|
%doc doc/avrdude.pdf
|
||||||
|
|
||||||
%changelog
|
%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>
|
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
- Add docs sub-package.
|
- Add docs sub-package.
|
||||||
- Add %post and %preun scriptlets for handling info files.
|
- Add %post and %preun scriptlets for handling info files.
|
||||||
|
|||||||
@@ -1,523 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
|
||||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.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
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "avrpart.h"
|
|
||||||
#include "pindefs.h"
|
|
||||||
|
|
||||||
extern char * progname;
|
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
*** Elementary functions dealing with OPCODE structures
|
|
||||||
***/
|
|
||||||
|
|
||||||
OPCODE * avr_new_opcode(void)
|
|
||||||
{
|
|
||||||
OPCODE * m;
|
|
||||||
|
|
||||||
m = (OPCODE *)malloc(sizeof(*m));
|
|
||||||
if (m == NULL) {
|
|
||||||
fprintf(stderr, "avr_new_opcode(): out of memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(m, 0, sizeof(*m));
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* avr_set_bits()
|
|
||||||
*
|
|
||||||
* Set instruction bits in the specified command based on the opcode.
|
|
||||||
*/
|
|
||||||
int avr_set_bits(OPCODE * op, unsigned char * cmd)
|
|
||||||
{
|
|
||||||
int i, j, bit;
|
|
||||||
unsigned char mask;
|
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
if (op->bit[i].type == AVR_CMDBIT_VALUE) {
|
|
||||||
j = 3 - i / 8;
|
|
||||||
bit = i % 8;
|
|
||||||
mask = 1 << bit;
|
|
||||||
if (op->bit[i].value)
|
|
||||||
cmd[j] = cmd[j] | mask;
|
|
||||||
else
|
|
||||||
cmd[j] = cmd[j] & ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* avr_set_addr()
|
|
||||||
*
|
|
||||||
* Set address bits in the specified command based on the opcode, and
|
|
||||||
* the address.
|
|
||||||
*/
|
|
||||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
|
|
||||||
{
|
|
||||||
int i, j, bit;
|
|
||||||
unsigned long value;
|
|
||||||
unsigned char mask;
|
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
|
|
||||||
j = 3 - i / 8;
|
|
||||||
bit = i % 8;
|
|
||||||
mask = 1 << bit;
|
|
||||||
value = addr >> op->bit[i].bitno & 0x01;
|
|
||||||
if (value)
|
|
||||||
cmd[j] = cmd[j] | mask;
|
|
||||||
else
|
|
||||||
cmd[j] = cmd[j] & ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* avr_set_input()
|
|
||||||
*
|
|
||||||
* Set input data bits in the specified command based on the opcode,
|
|
||||||
* and the data byte.
|
|
||||||
*/
|
|
||||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
|
|
||||||
{
|
|
||||||
int i, j, bit;
|
|
||||||
unsigned char value;
|
|
||||||
unsigned char mask;
|
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
if (op->bit[i].type == AVR_CMDBIT_INPUT) {
|
|
||||||
j = 3 - i / 8;
|
|
||||||
bit = i % 8;
|
|
||||||
mask = 1 << bit;
|
|
||||||
value = data >> op->bit[i].bitno & 0x01;
|
|
||||||
if (value)
|
|
||||||
cmd[j] = cmd[j] | mask;
|
|
||||||
else
|
|
||||||
cmd[j] = cmd[j] & ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* avr_get_output()
|
|
||||||
*
|
|
||||||
* Retreive output data bits from the command results based on the
|
|
||||||
* opcode data.
|
|
||||||
*/
|
|
||||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
|
||||||
{
|
|
||||||
int i, j, bit;
|
|
||||||
unsigned char value;
|
|
||||||
unsigned char mask;
|
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
|
|
||||||
j = 3 - i / 8;
|
|
||||||
bit = i % 8;
|
|
||||||
mask = 1 << bit;
|
|
||||||
value = ((res[j] & mask) >> bit) & 0x01;
|
|
||||||
value = value << op->bit[i].bitno;
|
|
||||||
if (value)
|
|
||||||
*data = *data | value;
|
|
||||||
else
|
|
||||||
*data = *data & ~value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char * avr_op_str(int op)
|
|
||||||
{
|
|
||||||
switch (op) {
|
|
||||||
case AVR_OP_READ : return "READ"; break;
|
|
||||||
case AVR_OP_WRITE : return "WRITE"; break;
|
|
||||||
case AVR_OP_READ_LO : return "READ_LO"; break;
|
|
||||||
case AVR_OP_READ_HI : return "READ_HI"; break;
|
|
||||||
case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
|
|
||||||
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
|
|
||||||
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
|
|
||||||
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
|
|
||||||
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
|
|
||||||
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
|
|
||||||
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
|
|
||||||
default : return "<unknown opcode>"; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char * bittype(int type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
|
|
||||||
case AVR_CMDBIT_VALUE : return "VALUE"; break;
|
|
||||||
case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
|
|
||||||
case AVR_CMDBIT_INPUT : return "INPUT"; break;
|
|
||||||
case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
|
|
||||||
default : return "<unknown bit type>"; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
*** Elementary functions dealing with AVRMEM structures
|
|
||||||
***/
|
|
||||||
|
|
||||||
AVRMEM * avr_new_memtype(void)
|
|
||||||
{
|
|
||||||
AVRMEM * m;
|
|
||||||
|
|
||||||
m = (AVRMEM *)malloc(sizeof(*m));
|
|
||||||
if (m == NULL) {
|
|
||||||
fprintf(stderr, "avr_new_memtype(): out of memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(m, 0, sizeof(*m));
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate and initialize memory buffers for each of the device's
|
|
||||||
* defined memory regions.
|
|
||||||
*/
|
|
||||||
int avr_initmem(AVRPART * p)
|
|
||||||
{
|
|
||||||
LNODEID ln;
|
|
||||||
AVRMEM * m;
|
|
||||||
|
|
||||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
|
||||||
m = ldata(ln);
|
|
||||||
m->buf = (unsigned char *) malloc(m->size);
|
|
||||||
if (m->buf == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
|
|
||||||
progname, m->desc, m->size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVRMEM * avr_dup_mem(AVRMEM * m)
|
|
||||||
{
|
|
||||||
AVRMEM * n;
|
|
||||||
|
|
||||||
n = avr_new_memtype();
|
|
||||||
|
|
||||||
*n = *m;
|
|
||||||
|
|
||||||
n->buf = (unsigned char *)malloc(n->size);
|
|
||||||
if (n->buf == NULL) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
|
||||||
n->size);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset(n->buf, 0, n->size);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
|
||||||
{
|
|
||||||
AVRMEM * m, * match;
|
|
||||||
LNODEID ln;
|
|
||||||
int matches;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
l = strlen(desc);
|
|
||||||
matches = 0;
|
|
||||||
match = NULL;
|
|
||||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
|
||||||
m = ldata(ln);
|
|
||||||
if (strncmp(desc, m->desc, l) == 0) {
|
|
||||||
match = m;
|
|
||||||
matches++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matches == 1)
|
|
||||||
return match;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
|
||||||
int verbose)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
char * optr;
|
|
||||||
|
|
||||||
if (m == NULL) {
|
|
||||||
fprintf(f,
|
|
||||||
"%s Page Polled\n"
|
|
||||||
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
|
|
||||||
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
|
|
||||||
prefix, prefix, prefix);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (verbose > 2) {
|
|
||||||
fprintf(f,
|
|
||||||
"%s Page Polled\n"
|
|
||||||
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
|
|
||||||
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
|
|
||||||
prefix, prefix, prefix);
|
|
||||||
}
|
|
||||||
fprintf(f,
|
|
||||||
"%s%-11s %-6s %6d %4d %5d %5d %5d 0x%02x 0x%02x\n",
|
|
||||||
prefix, m->desc,
|
|
||||||
m->paged ? "yes" : "no",
|
|
||||||
m->size,
|
|
||||||
m->page_size,
|
|
||||||
m->num_pages,
|
|
||||||
m->min_write_delay,
|
|
||||||
m->max_write_delay,
|
|
||||||
m->readback[0],
|
|
||||||
m->readback[1]);
|
|
||||||
if (verbose > 2) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s Memory Ops:\n"
|
|
||||||
"%s Oeration Inst Bit Bit Type Bitno Value\n"
|
|
||||||
"%s ----------- -------- -------- ----- -----\n",
|
|
||||||
prefix, prefix, prefix);
|
|
||||||
for (i=0; i<AVR_OP_MAX; i++) {
|
|
||||||
if (m->op[i]) {
|
|
||||||
for (j=31; j>=0; j--) {
|
|
||||||
if (j==31)
|
|
||||||
optr = avr_op_str(i);
|
|
||||||
else
|
|
||||||
optr = " ";
|
|
||||||
fprintf(f,
|
|
||||||
"%s %-11s %8d %8s %5d %5d\n",
|
|
||||||
prefix, optr, j,
|
|
||||||
bittype(m->op[i]->bit[j].type),
|
|
||||||
m->op[i]->bit[j].bitno,
|
|
||||||
m->op[i]->bit[j].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Elementary functions dealing with AVRPART structures
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
AVRPART * avr_new_part(void)
|
|
||||||
{
|
|
||||||
AVRPART * p;
|
|
||||||
|
|
||||||
p = (AVRPART *)malloc(sizeof(AVRPART));
|
|
||||||
if (p == NULL) {
|
|
||||||
fprintf(stderr, "new_part(): out of memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
|
|
||||||
p->id[0] = 0;
|
|
||||||
p->desc[0] = 0;
|
|
||||||
p->reset_disposition = RESET_DEDICATED;
|
|
||||||
p->retry_pulse = PIN_AVR_SCK;
|
|
||||||
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;
|
|
||||||
p->config_file[0] = 0;
|
|
||||||
p->lineno = 0;
|
|
||||||
|
|
||||||
p->mem = lcreat(NULL, 0);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVRPART * avr_dup_part(AVRPART * d)
|
|
||||||
{
|
|
||||||
AVRPART * p;
|
|
||||||
LISTID save;
|
|
||||||
LNODEID ln;
|
|
||||||
|
|
||||||
p = avr_new_part();
|
|
||||||
save = p->mem;
|
|
||||||
|
|
||||||
*p = *d;
|
|
||||||
|
|
||||||
p->mem = save;
|
|
||||||
|
|
||||||
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
|
||||||
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVRPART * locate_part(LISTID parts, char * partdesc)
|
|
||||||
{
|
|
||||||
LNODEID ln1;
|
|
||||||
AVRPART * p = NULL;
|
|
||||||
int found;
|
|
||||||
|
|
||||||
found = 0;
|
|
||||||
|
|
||||||
for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
|
|
||||||
p = ldata(ln1);
|
|
||||||
if ((strcasecmp(partdesc, p->id) == 0) ||
|
|
||||||
(strcasecmp(partdesc, p->desc) == 0))
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
return p;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
|
|
||||||
{
|
|
||||||
LNODEID ln1;
|
|
||||||
AVRPART * p = NULL;
|
|
||||||
|
|
||||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
|
||||||
p = ldata(ln1);
|
|
||||||
if (p->avr910_devcode == devcode)
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void list_parts(FILE * f, char * prefix, LISTID parts)
|
|
||||||
{
|
|
||||||
LNODEID ln1;
|
|
||||||
AVRPART * p;
|
|
||||||
|
|
||||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
|
||||||
p = ldata(ln1);
|
|
||||||
fprintf(f, "%s%-4s = %-15s [%s:%d]\n",
|
|
||||||
prefix, p->id, p->desc, p->config_file, p->lineno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char * reset_disp_str(int r)
|
|
||||||
{
|
|
||||||
switch (r) {
|
|
||||||
case RESET_DEDICATED : return "dedicated";
|
|
||||||
case RESET_IO : return "possible i/o";
|
|
||||||
default : return "<invalid>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char * pin_name(int pinno)
|
|
||||||
{
|
|
||||||
switch (pinno) {
|
|
||||||
case PIN_AVR_RESET : return "RESET";
|
|
||||||
case PIN_AVR_MISO : return "MISO";
|
|
||||||
case PIN_AVR_MOSI : return "MOSI";
|
|
||||||
case PIN_AVR_SCK : return "SCK";
|
|
||||||
default : return "<unknown>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char * buf;
|
|
||||||
char * px;
|
|
||||||
LNODEID ln;
|
|
||||||
AVRMEM * m;
|
|
||||||
|
|
||||||
fprintf(f,
|
|
||||||
"%sAVR Part : %s\n"
|
|
||||||
"%sChip Erase delay : %d us\n"
|
|
||||||
"%sPAGEL : P%02X\n"
|
|
||||||
"%sBS2 : P%02X\n"
|
|
||||||
"%sRESET disposition : %s\n"
|
|
||||||
"%sRETRY pulse : %s\n"
|
|
||||||
"%sserial program mode : %s\n"
|
|
||||||
"%sparallel program mode : %s\n"
|
|
||||||
"%sMemory Detail :\n\n",
|
|
||||||
prefix, p->desc,
|
|
||||||
prefix, p->chip_erase_delay,
|
|
||||||
prefix, p->pagel,
|
|
||||||
prefix, p->bs2,
|
|
||||||
prefix, reset_disp_str(p->reset_disposition),
|
|
||||||
prefix, pin_name(p->retry_pulse),
|
|
||||||
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
|
|
||||||
prefix, (p->flags & AVRPART_PARALLELOK) ?
|
|
||||||
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
|
|
||||||
prefix);
|
|
||||||
|
|
||||||
px = prefix;
|
|
||||||
i = strlen(prefix) + 5;
|
|
||||||
buf = (char *)malloc(i);
|
|
||||||
if (buf == NULL) {
|
|
||||||
/* ugh, this is not important enough to bail, just ignore it */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
strcpy(buf, prefix);
|
|
||||||
strcat(buf, " ");
|
|
||||||
px = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose <= 2) {
|
|
||||||
avr_mem_display(px, f, NULL, 0, verbose);
|
|
||||||
}
|
|
||||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
|
||||||
m = ldata(ln);
|
|
||||||
avr_mem_display(px, f, m, i, verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf)
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
@@ -81,8 +81,7 @@ typedef struct opcode {
|
|||||||
typedef struct avrpart {
|
typedef struct avrpart {
|
||||||
char desc[AVR_DESCLEN]; /* long part name */
|
char desc[AVR_DESCLEN]; /* long part name */
|
||||||
char id[AVR_IDLEN]; /* short part name */
|
char id[AVR_IDLEN]; /* short part name */
|
||||||
int stk500_devcode; /* stk500 device code */
|
int devicecode; /* Atmel STK500 device code */
|
||||||
int avr910_devcode; /* avr910 device code */
|
|
||||||
int chip_erase_delay; /* microseconds */
|
int chip_erase_delay; /* microseconds */
|
||||||
unsigned char pagel; /* for parallel programming */
|
unsigned char pagel; /* for parallel programming */
|
||||||
unsigned char bs2; /* for parallel programming */
|
unsigned char bs2; /* for parallel programming */
|
||||||
@@ -116,27 +115,4 @@ typedef struct avrmem {
|
|||||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||||
} AVRMEM;
|
} AVRMEM;
|
||||||
|
|
||||||
/* Functions for OPCODE structures */
|
|
||||||
OPCODE * avr_new_opcode(void);
|
|
||||||
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
|
||||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
|
|
||||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
|
|
||||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
|
|
||||||
|
|
||||||
/* Functions for AVRMEM structures */
|
|
||||||
AVRMEM * avr_new_memtype(void);
|
|
||||||
int avr_initmem(AVRPART * p);
|
|
||||||
AVRMEM * avr_dup_mem(AVRMEM * m);
|
|
||||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
|
||||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
|
||||||
int verbose);
|
|
||||||
|
|
||||||
/* Functions for AVRPART structures */
|
|
||||||
AVRPART * avr_new_part(void);
|
|
||||||
AVRPART * avr_dup_part(AVRPART * d);
|
|
||||||
AVRPART * locate_part(LISTID parts, char * partdesc);
|
|
||||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
|
||||||
void list_parts(FILE * f, char * prefix, LISTID parts);
|
|
||||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,641 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 the serial programming mode of the Atmel butterfly
|
|
||||||
* evaluation board. This board features a bootloader which uses a protocol
|
|
||||||
* very similar, but not identical, to the one described in application note
|
|
||||||
* avr910.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "ac_cfg.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "avr.h"
|
|
||||||
#include "pgm.h"
|
|
||||||
#include "butterfly.h"
|
|
||||||
#include "serial.h"
|
|
||||||
|
|
||||||
extern char * progname;
|
|
||||||
extern int do_cycles;
|
|
||||||
|
|
||||||
static char has_auto_incr_addr;
|
|
||||||
static unsigned buffersize = 0;
|
|
||||||
|
|
||||||
/* 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 butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
return serial_send(pgm->fd, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
return serial_recv(pgm->fd, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_drain(PROGRAMMER * pgm, int display)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
return serial_drain(pgm->fd, display);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
|
|
||||||
butterfly_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 butterfly_rdy_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_err_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* issue the 'chip erase' command to the butterfly board
|
|
||||||
*/
|
|
||||||
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
butterfly_send(pgm, "e", 1);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "chip erase");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
butterfly_send(pgm, "P", 1);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "enter prog mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
butterfly_send(pgm, "L", 1);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "leave prog mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* issue the 'program enable' command to the AVR device
|
|
||||||
*/
|
|
||||||
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* apply power to the AVR processor
|
|
||||||
*/
|
|
||||||
static void butterfly_powerup(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* remove power from the AVR processor
|
|
||||||
*/
|
|
||||||
static void butterfly_powerdown(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* initialize the AVR device and prepare it to accept commands
|
|
||||||
*/
|
|
||||||
static int butterfly_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();
|
|
||||||
|
|
||||||
/* send some ESC to activate butterfly bootloader */
|
|
||||||
butterfly_send(pgm, "\033\033\033\033", 4);
|
|
||||||
butterfly_drain(pgm, 0);
|
|
||||||
|
|
||||||
/* Get the programmer identifier. Programmer returns exactly 7 chars
|
|
||||||
_without_ the null.*/
|
|
||||||
|
|
||||||
butterfly_send(pgm, "S", 1);
|
|
||||||
memset (id, 0, sizeof(id));
|
|
||||||
butterfly_recv(pgm, id, sizeof(id)-1);
|
|
||||||
|
|
||||||
/* Get the HW and SW versions to see if the programmer is present. */
|
|
||||||
|
|
||||||
butterfly_send(pgm, "V", 1);
|
|
||||||
butterfly_recv(pgm, sw, sizeof(sw));
|
|
||||||
|
|
||||||
butterfly_send(pgm, "v", 1);
|
|
||||||
butterfly_recv(pgm, hw, 1); /* first, read only _one_ byte */
|
|
||||||
if (hw[0]!='?') {
|
|
||||||
butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get the programmer type (serial or parallel). Expect serial. */
|
|
||||||
|
|
||||||
butterfly_send(pgm, "p", 1);
|
|
||||||
butterfly_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]);
|
|
||||||
if (hw[0]=='?') {
|
|
||||||
fprintf(stderr, "No Hardware Version given.\n");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* See if programmer supports autoincrement of address. */
|
|
||||||
|
|
||||||
butterfly_send(pgm, "a", 1);
|
|
||||||
butterfly_recv(pgm, &has_auto_incr_addr, 1);
|
|
||||||
if (has_auto_incr_addr == 'Y')
|
|
||||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
|
||||||
|
|
||||||
/* Check support for buffered memory access, abort if not available */
|
|
||||||
|
|
||||||
butterfly_send(pgm, "b", 1);
|
|
||||||
butterfly_recv(pgm, &c, 1);
|
|
||||||
if (c != 'Y') {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: error: buffered memory access not supported. Maybe it isn't\n"\
|
|
||||||
"a butterfly but a AVR910 device?\n", progname);
|
|
||||||
exit(1);
|
|
||||||
};
|
|
||||||
butterfly_recv(pgm, &c, 1);
|
|
||||||
buffersize = c<<8;
|
|
||||||
butterfly_recv(pgm, &c, 1);
|
|
||||||
buffersize += c;
|
|
||||||
fprintf(stderr,
|
|
||||||
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
|
|
||||||
buffersize);
|
|
||||||
|
|
||||||
/* Get list of devices that the programmer supports. */
|
|
||||||
|
|
||||||
butterfly_send(pgm, "t", 1);
|
|
||||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
|
||||||
while (1) {
|
|
||||||
butterfly_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;
|
|
||||||
|
|
||||||
butterfly_send(pgm, buf, 2);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "select device");
|
|
||||||
|
|
||||||
butterfly_enter_prog_mode(pgm);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_save(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_restore(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_disable(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_enable(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
/* Do nothing. */
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_open(PROGRAMMER * pgm, char * port)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
strcpy(pgm->port, port);
|
|
||||||
pgm->fd = serial_open(port, 19200);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* drain any extraneous input
|
|
||||||
*/
|
|
||||||
butterfly_drain (pgm, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_close(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
butterfly_leave_prog_mode(pgm);
|
|
||||||
|
|
||||||
serial_close(pgm->fd);
|
|
||||||
pgm->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_display(PROGRAMMER * pgm, char * p)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
|
||||||
{
|
|
||||||
unsigned char cmd[3];
|
|
||||||
|
|
||||||
cmd[0] = 'A';
|
|
||||||
cmd[1] = (addr >> 8) & 0xff;
|
|
||||||
cmd[2] = addr & 0xff;
|
|
||||||
|
|
||||||
butterfly_send(pgm, cmd, sizeof(cmd));
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "set addr");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
||||||
unsigned long addr, unsigned char value)
|
|
||||||
{
|
|
||||||
unsigned char cmd[6];
|
|
||||||
int size;
|
|
||||||
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
if ((strcmp(m->desc, "flash") != 0) && (strcmp(m->desc, "eeprom") != 0))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cmd[0] = 'B';
|
|
||||||
cmd[1] = 0;
|
|
||||||
if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */
|
|
||||||
cmd[2] = 1;
|
|
||||||
cmd[4] = value;
|
|
||||||
size = 5;
|
|
||||||
} else { /* write to flash */
|
|
||||||
/* @@@ not yet implemented */
|
|
||||||
cmd[2] = 2;
|
|
||||||
size = 6;
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
butterfly_set_addr(pgm, addr);
|
|
||||||
|
|
||||||
butterfly_send(pgm, cmd, size);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "write byte");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_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];
|
|
||||||
|
|
||||||
butterfly_set_addr(pgm, addr >> 1);
|
|
||||||
|
|
||||||
butterfly_send(pgm, "g\000\002F", 4);
|
|
||||||
|
|
||||||
/* Read back the program mem word (MSB first) */
|
|
||||||
butterfly_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 butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
||||||
unsigned long addr, unsigned char * value)
|
|
||||||
{
|
|
||||||
butterfly_set_addr(pgm, addr);
|
|
||||||
butterfly_send(pgm, "g\000\001E", 4);
|
|
||||||
butterfly_recv(pgm, value, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_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 butterfly_read_byte_flash(pgm, p, m, addr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(m->desc, "eeprom") == 0) {
|
|
||||||
return butterfly_read_byte_eeprom(pgm, p, m, addr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
||||||
int page_size, int n_bytes)
|
|
||||||
{
|
|
||||||
unsigned int addr = 0;
|
|
||||||
unsigned int max_addr = n_bytes;
|
|
||||||
unsigned char *cmd;
|
|
||||||
unsigned int blocksize = buffersize;
|
|
||||||
|
|
||||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
if (m->desc[0] == 'e')
|
|
||||||
blocksize = 1; /* Write to eeprom single bytes only */
|
|
||||||
|
|
||||||
butterfly_set_addr(pgm, addr);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
usleep(1000000);
|
|
||||||
butterfly_send(pgm, "y", 1);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "clear LED");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cmd = malloc(4+blocksize);
|
|
||||||
if (!cmd) return -1;
|
|
||||||
cmd[0] = 'B';
|
|
||||||
cmd[3] = toupper(m->desc[0]);
|
|
||||||
|
|
||||||
while (addr < max_addr) {
|
|
||||||
if ((max_addr - addr) < blocksize) {
|
|
||||||
blocksize = max_addr - addr;
|
|
||||||
};
|
|
||||||
memcpy(&cmd[4], &m->buf[addr], blocksize);
|
|
||||||
cmd[1] = (blocksize >> 8) & 0xff;
|
|
||||||
cmd[2] = blocksize & 0xff;
|
|
||||||
|
|
||||||
butterfly_send(pgm, cmd, 4+blocksize);
|
|
||||||
butterfly_vfy_cmd_sent(pgm, "write block");
|
|
||||||
|
|
||||||
addr += blocksize;
|
|
||||||
|
|
||||||
report_progress (addr, max_addr, NULL);
|
|
||||||
} /* while */
|
|
||||||
free(cmd);
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
||||||
int page_size, int n_bytes)
|
|
||||||
{
|
|
||||||
unsigned int addr = 0;
|
|
||||||
unsigned int max_addr = n_bytes;
|
|
||||||
int rd_size = 1;
|
|
||||||
|
|
||||||
/* check parameter syntax: only "flash" or "eeprom" is allowed */
|
|
||||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
{ /* use buffered mode */
|
|
||||||
unsigned char cmd[4];
|
|
||||||
int blocksize = buffersize;
|
|
||||||
|
|
||||||
cmd[0] = 'g';
|
|
||||||
cmd[3] = toupper(m->desc[0]);
|
|
||||||
|
|
||||||
butterfly_set_addr(pgm, addr);
|
|
||||||
while (addr < max_addr) {
|
|
||||||
if ((max_addr - addr) < blocksize) {
|
|
||||||
blocksize = max_addr - addr;
|
|
||||||
};
|
|
||||||
cmd[1] = (blocksize >> 8) & 0xff;
|
|
||||||
cmd[2] = blocksize & 0xff;
|
|
||||||
|
|
||||||
butterfly_send(pgm, cmd, 4);
|
|
||||||
butterfly_recv(pgm, &m->buf[addr], blocksize);
|
|
||||||
|
|
||||||
addr += blocksize;
|
|
||||||
|
|
||||||
report_progress (addr, max_addr, NULL);
|
|
||||||
} /* while */
|
|
||||||
}
|
|
||||||
|
|
||||||
return addr * rd_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Signature byte reads are always 3 bytes. */
|
|
||||||
static int butterfly_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
butterfly_send(pgm, "s", 1);
|
|
||||||
butterfly_recv(pgm, m->buf, 3);
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void butterfly_initpgm(PROGRAMMER * pgm)
|
|
||||||
{
|
|
||||||
no_show_func_info();
|
|
||||||
|
|
||||||
strcpy(pgm->type, "avr910");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mandatory functions
|
|
||||||
*/
|
|
||||||
pgm->rdy_led = butterfly_rdy_led;
|
|
||||||
pgm->err_led = butterfly_err_led;
|
|
||||||
pgm->pgm_led = butterfly_pgm_led;
|
|
||||||
pgm->vfy_led = butterfly_vfy_led;
|
|
||||||
pgm->initialize = butterfly_initialize;
|
|
||||||
pgm->display = butterfly_display;
|
|
||||||
pgm->save = butterfly_save;
|
|
||||||
pgm->restore = butterfly_restore;
|
|
||||||
pgm->enable = butterfly_enable;
|
|
||||||
pgm->disable = butterfly_disable;
|
|
||||||
pgm->powerup = butterfly_powerup;
|
|
||||||
pgm->powerdown = butterfly_powerdown;
|
|
||||||
pgm->program_enable = butterfly_program_enable;
|
|
||||||
pgm->chip_erase = butterfly_chip_erase;
|
|
||||||
/* pgm->cmd not supported, use default error message */
|
|
||||||
pgm->open = butterfly_open;
|
|
||||||
pgm->close = butterfly_close;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* optional functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
pgm->write_byte = butterfly_write_byte;
|
|
||||||
pgm->read_byte = butterfly_read_byte;
|
|
||||||
|
|
||||||
pgm->paged_write = butterfly_paged_write;
|
|
||||||
pgm->paged_load = butterfly_paged_load;
|
|
||||||
|
|
||||||
pgm->read_sig_bytes = butterfly_read_sig_bytes;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 __butterfly_h__
|
|
||||||
#define __butterfly_h__
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void butterfly_initpgm (PROGRAMMER * pgm);
|
|
||||||
|
|
||||||
#endif /* __butterfly_h__ */
|
|
||||||
@@ -33,8 +33,6 @@
|
|||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
#include "stk500.h"
|
#include "stk500.h"
|
||||||
#include "avr910.h"
|
|
||||||
#include "butterfly.h"
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
@@ -65,7 +63,6 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_PAGE_SIZE
|
%token K_PAGE_SIZE
|
||||||
%token K_PAGED
|
%token K_PAGED
|
||||||
|
|
||||||
%token K_BAUDRATE
|
|
||||||
%token K_BS2
|
%token K_BS2
|
||||||
%token K_BUFF
|
%token K_BUFF
|
||||||
%token K_CHIP_ERASE_DELAY
|
%token K_CHIP_ERASE_DELAY
|
||||||
@@ -75,8 +72,6 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_DEFAULT_SERIAL
|
%token K_DEFAULT_SERIAL
|
||||||
%token K_DESC
|
%token K_DESC
|
||||||
%token K_DEVICECODE
|
%token K_DEVICECODE
|
||||||
%token K_STK500_DEVCODE
|
|
||||||
%token K_AVR910_DEVCODE
|
|
||||||
%token K_EEPROM
|
%token K_EEPROM
|
||||||
%token K_ERRLED
|
%token K_ERRLED
|
||||||
%token K_FLASH
|
%token K_FLASH
|
||||||
@@ -106,8 +101,6 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_SCK
|
%token K_SCK
|
||||||
%token K_SIZE
|
%token K_SIZE
|
||||||
%token K_STK500
|
%token K_STK500
|
||||||
%token K_AVR910
|
|
||||||
%token K_BUTTERFLY
|
|
||||||
%token K_TYPE
|
%token K_TYPE
|
||||||
%token K_VCC
|
%token K_VCC
|
||||||
%token K_VFYLED
|
%token K_VFYLED
|
||||||
@@ -291,18 +284,6 @@ prog_parm :
|
|||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_TYPE TKN_EQUAL K_AVR910 {
|
|
||||||
{
|
|
||||||
avr910_initpgm(current_prog);
|
|
||||||
}
|
|
||||||
} |
|
|
||||||
|
|
||||||
K_TYPE TKN_EQUAL K_BUTTERFLY {
|
|
||||||
{
|
|
||||||
butterfly_initpgm(current_prog);
|
|
||||||
}
|
|
||||||
} |
|
|
||||||
|
|
||||||
K_DESC TKN_EQUAL TKN_STRING {
|
K_DESC TKN_EQUAL TKN_STRING {
|
||||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||||
current_prog->desc[PGM_DESCLEN-1] = 0;
|
current_prog->desc[PGM_DESCLEN-1] = 0;
|
||||||
@@ -359,12 +340,6 @@ prog_parm :
|
|||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|
||||||
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
|
|
||||||
{
|
|
||||||
current_prog->baudrate = $3->value.number;
|
|
||||||
}
|
|
||||||
} |
|
|
||||||
|
|
||||||
K_RESET TKN_EQUAL TKN_NUMBER { free_token($1);
|
K_RESET TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||||
assign_pin(PIN_AVR_RESET, $3); } |
|
assign_pin(PIN_AVR_RESET, $3); } |
|
||||||
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
|
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||||
@@ -428,24 +403,7 @@ part_parm :
|
|||||||
|
|
||||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
current_part->devicecode = $3->value.number;
|
||||||
"%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);
|
free_token($3);
|
||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT(avrdude, 4.3.0, avrdude-dev@nongnu.org)
|
AC_INIT(avrdude, 4.0.0, avrdude-dev@nongnu.org)
|
||||||
|
|
||||||
AC_CANONICAL_BUILD
|
AC_CANONICAL_BUILD
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@@ -42,7 +42,6 @@ AM_PROG_LEX
|
|||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
AC_CHECK_LIB([termcap], [tputs])
|
AC_CHECK_LIB([termcap], [tputs])
|
||||||
AC_CHECK_LIB([ncurses], [tputs])
|
|
||||||
AC_CHECK_LIB([readline], [readline])
|
AC_CHECK_LIB([readline], [readline])
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
@@ -125,12 +124,6 @@ case $target in
|
|||||||
esac
|
esac
|
||||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
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([
|
AC_CONFIG_FILES([
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
windows/Makefile
|
windows/Makefile
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,8 +30,6 @@ static char *filename;
|
|||||||
|
|
||||||
void win_sys_config_set(char sys_config[PATH_MAX])
|
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.*/
|
/* Use Windows API call to search for the Windows default system config file.*/
|
||||||
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
||||||
return;
|
return;
|
||||||
@@ -40,8 +38,6 @@ void win_sys_config_set(char sys_config[PATH_MAX])
|
|||||||
|
|
||||||
void win_usr_config_set(char usr_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. */
|
/* Use Windows API call to search for the Windows default user config file. */
|
||||||
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,22 +1,11 @@
|
|||||||
|
|
||||||
- Man page needs updated for avr910 info.
|
General:
|
||||||
|
|
||||||
- Website needs to link to docs:
|
|
||||||
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
|
|
||||||
|
|
||||||
- [Windows Port] Use Windows API for serial port communications (ser_win32.c).
|
|
||||||
(In Progress)
|
Windows:
|
||||||
|
- Use Windows API for stk500 serial port communications on Windows port.
|
||||||
|
This might remove dependency on Cygwin.
|
||||||
|
|
||||||
- Add "skip empty pages" optimization on avr910 paged write. The stk500 has
|
- Add ability to find all parallel port names available and base addresses
|
||||||
this optimization already.
|
of available ports.
|
||||||
|
|
||||||
- Fix "overfull \hbox" issues in building documentation.
|
|
||||||
|
|
||||||
- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
|
|
||||||
code.
|
|
||||||
|
|
||||||
- FIXME: avr910.c: avr910_cmd(): Insert version check here.
|
|
||||||
|
|
||||||
- FIXME: ser_posix.c: serial_close(): Should really restore the terminal to
|
|
||||||
original state here.
|
|
||||||
|
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
@setfilename avrdude.info
|
@setfilename avrdude.info
|
||||||
@settitle AVRDUDE
|
@settitle AVRDUDE
|
||||||
@finalout
|
|
||||||
|
|
||||||
@include version.texi
|
@include version.texi
|
||||||
|
|
||||||
@@ -98,11 +97,10 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
|
|||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Introduction::
|
* Introduction::
|
||||||
* Command Line Options::
|
* Command Line Options::
|
||||||
* Terminal Mode Operation::
|
* Terminal Mode Operation::
|
||||||
* Configuration File::
|
* Configuration File::
|
||||||
* Platform Dependent Information::
|
* Platform Dependent Information::
|
||||||
* Troubleshooting::
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@@ -129,24 +127,17 @@ from the contents of a file, while interactive mode is useful for
|
|||||||
exploring memory contents, modifing individual bytes of eeprom,
|
exploring memory contents, modifing individual bytes of eeprom,
|
||||||
programming fuse/lock bits, etc.
|
programming fuse/lock bits, etc.
|
||||||
|
|
||||||
AVRDUDE supports three basic programmer types: Atmel's STK500, appnote
|
AVRDUDE supports two basic programmer types: Atmel's STK500 and the PPI
|
||||||
avr910 and the PPI (parallel port interface). PPI represents a class
|
(parallel port interface). PPI represents a class of simple programmers
|
||||||
of simple programmers where the programming lines are directly
|
where the programming lines are directly connected to the PC parallel
|
||||||
connected to the PC parallel port. Several pin configurations exist
|
port, while the STK500 uses the serial port to communicate with the PC
|
||||||
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
|
and contains on-board logic to control the programming of the target
|
||||||
device. The fundamental difference between the two types lies in the
|
device. Several pin configurations exist for several variations of the
|
||||||
protocol used to control the programmer. The avr910 protocol is very
|
PPI programmers, and AVRDUDE can be be configured to work with them by
|
||||||
simplistic and can easily be used as the basis for a simple, home made
|
either specifying the appropriate programmer on the command line or by
|
||||||
programer since the firmware is available online. On the other hand,
|
creating a new entry in its configuration file. All that's usually
|
||||||
the STK500 protocol is more robust and complicated and the firmware is
|
required for a new entry is to tell AVRDUDE which pins to use for each
|
||||||
not openly available.
|
programming function.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* History::
|
* History::
|
||||||
@@ -156,7 +147,7 @@ not openly available.
|
|||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@node History, , Introduction, Introduction
|
@node History, , Introduction, Introduction
|
||||||
@section History and Credits
|
@section History
|
||||||
|
|
||||||
AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
|
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
|
the FreeBSD Operating System. Brian renamed the software to be called
|
||||||
@@ -188,8 +179,8 @@ Roth.
|
|||||||
@cindex options
|
@cindex options
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Option Descriptions::
|
* Option Descriptions::
|
||||||
* Example Command Line Invocations::
|
* Example Command Line Invocations::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@@ -213,7 +204,7 @@ following options are recognized:
|
|||||||
@item -p @var{partno}
|
@item -p @var{partno}
|
||||||
This is the only mandatory option and it tells AVRDUDE what type of part
|
This is the only mandatory option and it tells AVRDUDE what type of part
|
||||||
(MCU) that is connected to the programmer. The @var{partno} parameter
|
(MCU) that is connected to the programmer. The @var{partno} parameter
|
||||||
is the part's id listed in the configuration file. Specify -p ? to list
|
is the part's id listed in the configuration file. Specify -p ? to list
|
||||||
all parts in the configuration file. If a part is unknown
|
all parts in the configuration file. If a part is unknown
|
||||||
to AVRDUDE, it means that there is no config file entry for that part,
|
to AVRDUDE, it means that there is no config file entry for that part,
|
||||||
but it can be added to the configuration file if you have the Atmel
|
but it can be added to the configuration file if you have the Atmel
|
||||||
@@ -221,6 +212,9 @@ datasheet so that you can enter the programming specifications.
|
|||||||
Currently, the following MCU types are understood:
|
Currently, the following MCU types are understood:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
@itemx t15
|
||||||
|
ATtiny15
|
||||||
|
|
||||||
@itemx 1200
|
@itemx 1200
|
||||||
AT90S1200
|
AT90S1200
|
||||||
|
|
||||||
@@ -248,51 +242,24 @@ AT90S8515
|
|||||||
@itemx 8535
|
@itemx 8535
|
||||||
AT90S8535
|
AT90S8535
|
||||||
|
|
||||||
@itemx m103
|
|
||||||
ATMEGA103
|
|
||||||
|
|
||||||
@itemx m128
|
|
||||||
ATMEGA128
|
|
||||||
|
|
||||||
@itemx m16
|
|
||||||
ATMEGA16
|
|
||||||
|
|
||||||
@itemx m161
|
|
||||||
ATMEGA161
|
|
||||||
|
|
||||||
@itemx m162
|
|
||||||
ATMEGA162
|
|
||||||
|
|
||||||
@itemx m163
|
@itemx m163
|
||||||
ATMEGA163
|
ATMEGA163
|
||||||
|
|
||||||
@itemx m169
|
@itemx m169
|
||||||
ATMEGA169
|
ATMEGA169
|
||||||
|
|
||||||
@itemx m32
|
@itemx m128
|
||||||
ATMEGA32
|
ATMEGA128
|
||||||
|
|
||||||
@itemx m64
|
@itemx m103
|
||||||
ATMEGA64
|
ATMEGA103
|
||||||
|
|
||||||
|
@itemx m16
|
||||||
|
ATMEGA16
|
||||||
|
|
||||||
@itemx m8
|
@itemx m8
|
||||||
ATMEGA8
|
ATMEGA8
|
||||||
|
|
||||||
@itemx m8515
|
|
||||||
ATMEGA8515
|
|
||||||
|
|
||||||
@itemx m8535
|
|
||||||
ATMEGA8535
|
|
||||||
|
|
||||||
@itemx t12
|
|
||||||
ATtiny12
|
|
||||||
|
|
||||||
@itemx t15
|
|
||||||
ATtiny15
|
|
||||||
|
|
||||||
@itemx t26
|
|
||||||
ATTINY26
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
(*) The AT90S2323 uses the same algorithm.
|
(*) The AT90S2323 uses the same algorithm.
|
||||||
@@ -301,61 +268,12 @@ ATTINY26
|
|||||||
Specify the programmer to be used. AVRDUDE knows about several common
|
Specify the programmer to be used. AVRDUDE knows about several common
|
||||||
programmers. Use this option to specify which one to use. The
|
programmers. Use this option to specify which one to use. The
|
||||||
@var{programmer-id} parameter is the programmer's id listed in 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
|
configuration file. If you have a programmer that is unknown to
|
||||||
AVRDUDE, and the programmer is controlled via the PC parallel port,
|
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
|
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
|
file without any code changes to AVRDUDE. Simply copy an existing entry
|
||||||
and change the pin definitions to match that of the unknown programmer.
|
and change the pin definitions to match that of the unknown programmer.
|
||||||
Currently, the following programmer ids are understood and supported:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@itemx abcmini
|
|
||||||
ABCmini Board, aka Dick Smith HOTCHIP
|
|
||||||
|
|
||||||
@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 butterfly
|
|
||||||
Atmel Butterfly Development Board
|
|
||||||
|
|
||||||
@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}
|
@item -C @var{config-file}
|
||||||
Use the specified config file for configuration data. This file
|
Use the specified config file for configuration data. This file
|
||||||
@@ -367,20 +285,12 @@ specified, AVRDUDE reads the configuration file from
|
|||||||
/usr/local/etc/avrdude.conf (FreeBSD and Linux). See Appendix A for
|
/usr/local/etc/avrdude.conf (FreeBSD and Linux). See Appendix A for
|
||||||
the method of searching for the configuration file for Windows.
|
the method of searching for the configuration file for Windows.
|
||||||
|
|
||||||
@item -D
|
|
||||||
Disable auto erase for flash. When the -U option with flash memory is
|
|
||||||
specified, avrdude 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 -i, and -m options automatically disable the
|
|
||||||
auto erase feature.
|
|
||||||
|
|
||||||
@item -e
|
@item -e
|
||||||
Causes a chip erase to be executed. This will reset the contents of the
|
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
|
flash ROM and EEPROM to the value `0xff', and is basically a
|
||||||
prerequisite command before the flash ROM can be reprogrammed again.
|
prerequisite command before the flash ROM can be reprogrammed again.
|
||||||
The only exception would be if the new contents would exclusively cause
|
The only exception would be if the new contents would exclusively cause
|
||||||
bits to be programmed from the value `1' to `0'. Note that in order
|
bits to be pro- grammed from the value `1' to `0'. Note that in order
|
||||||
to reprogram EERPOM cells, no explicit prior chip erase is required
|
to reprogram EERPOM cells, no explicit prior chip erase is required
|
||||||
since the MCU provides an auto-erase cycle in that case before
|
since the MCU provides an auto-erase cycle in that case before
|
||||||
programming the cell.
|
programming the cell.
|
||||||
@@ -389,12 +299,12 @@ programming the cell.
|
|||||||
@item -E @var{exitspec}[,@dots{}]
|
@item -E @var{exitspec}[,@dots{}]
|
||||||
By default, AVRDUDE leaves the parallel port in the same state at exit
|
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
|
as it has been found at startup. This option modifies the state of the
|
||||||
`/RESET' and `Vcc' lines the parallel port is left at, according to
|
`/RESET' and `Vcc' lines the par- allel port is left at, according to
|
||||||
the exitspec arguments provided, as follows:
|
the exitspec arguments provided, as follows:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@itemx reset
|
@itemx reset
|
||||||
The `/RESET' signal will be left activated at program exit, that is it
|
The `/RESET' signal will be left activated at pro- gram exit, that is it
|
||||||
will be held low, in order to keep the MCU in reset state afterwards.
|
will be held low, in order to keep the MCU in reset state afterwards.
|
||||||
Note in particular that the programming algorithm for the AT90S1200
|
Note in particular that the programming algorithm for the AT90S1200
|
||||||
device mandates that the `/RESET' signal is active before powering up
|
device mandates that the `/RESET' signal is active before powering up
|
||||||
@@ -407,12 +317,12 @@ The `/RESET' line will be deactivated at program exit, thus allowing the
|
|||||||
MCU target program to run while the programming hardware remains
|
MCU target program to run while the programming hardware remains
|
||||||
connected.
|
connected.
|
||||||
|
|
||||||
@itemx vcc
|
@itemx vcc
|
||||||
This option will leave those parallel port pins active (i. e. high) that
|
This option will leave those parallel port pins active (i. e. high) that
|
||||||
can be used to supply `Vcc' power to the MCU.
|
can be used to supply `Vcc' power to the MCU.
|
||||||
|
|
||||||
@itemx novcc
|
@itemx novcc
|
||||||
This option will pull the `Vcc' pins of the parallel port down at
|
This option will pull the `Vcc' pins of the paral- lel port down at
|
||||||
program exit.
|
program exit.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
@@ -422,7 +332,7 @@ Multiple @var{exitspec} arguments can be separated with commas.
|
|||||||
|
|
||||||
|
|
||||||
@item -f @var{format}
|
@item -f @var{format}
|
||||||
This option specifies the file format for the input or output files to
|
This option specifies the file format for the input or out- put files to
|
||||||
be processed. Format can be one of:
|
be processed. Format can be one of:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@@ -435,16 +345,6 @@ Motorola S-record
|
|||||||
@itemx r
|
@itemx r
|
||||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
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
|
@itemx a
|
||||||
auto detect; valid for input only, and only if the input is not provided
|
auto detect; valid for input only, and only if the input is not provided
|
||||||
at stdin.
|
at stdin.
|
||||||
@@ -483,50 +383,17 @@ respective memory area to be read from the MCU. Can be specified as `-'
|
|||||||
to write to stdout.
|
to write to stdout.
|
||||||
|
|
||||||
@item -P @var{port}
|
@item -P @var{port}
|
||||||
Use port to identify the device to which the programmer is attached.
|
Use port to identify the device to which the programmer is attached. By
|
||||||
Normally, the default parallel port is used, but if the programmer type
|
default the @code{/dev/ppi0} port is used, but if the programmer type
|
||||||
normally connects to the serial port, the default serial port will be
|
normally connects to the serial port, the @code{/dev/cuaa0} port is the
|
||||||
used. See Appendix A, Platform Dependent Information, to find out the
|
default. If you need to use a different parallel or serial port, use
|
||||||
default port names for your platform. If you need to use a different
|
this option to spec- ify the alternate port name.
|
||||||
parallel or serial port, use 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
|
@item -t
|
||||||
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
||||||
or downloading files. See below for a detailed description of the
|
or downloading files. See below for a detailed description of the
|
||||||
terminal mode.
|
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.
|
|
||||||
Note that if @var{filename} contains a colon, the @var{format} field is
|
|
||||||
no longer optional since the filename part following the colon would
|
|
||||||
otherwise be misinterpreted as @var{format}.
|
|
||||||
|
|
||||||
@item -v
|
@item -v
|
||||||
Enable verbose output.
|
Enable verbose output.
|
||||||
|
|
||||||
@@ -538,14 +405,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
|
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
|
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
|
chip erase, the previous counter will be saved before the chip erase, it
|
||||||
is then incremented, and written back after the erase cycle completes.
|
is then incremented, and written back after the erase cycle com- pletes.
|
||||||
Presumably, the device would only be erased just before being
|
Presumably, the device would only be erased just before being
|
||||||
programmed, and thus, this can be utilized to give an indication of how
|
programmed, and thus, this can be utilized to give an indication of how
|
||||||
many erase-rewrite cycles the part has undergone. Since the FLASH
|
many erase-rewrite cycles the part has undergone. Since the FLASH
|
||||||
memory can only endure a finite number of erase-rewrite cycles, one can
|
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 typical
|
use this option to track when a part is nearing the limit. The typ-
|
||||||
limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
ical limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
||||||
application needs the last four bytes of EEPROM memory, this option
|
application needs the last four bytes of EEPROM mem- ory, this option
|
||||||
should not be used.
|
should not be used.
|
||||||
|
|
||||||
@item -Y @var{cycles}
|
@item -Y @var{cycles}
|
||||||
@@ -563,64 +430,50 @@ should not be used.
|
|||||||
@section Example Command Line Invocations
|
@section Example Command Line Invocations
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Download the file @code{diag.hex} to the ATmega128 chip using the
|
Download the file @code{m128diag.hex} to the ATmega128 chip using the
|
||||||
STK500 programmer connected to the default serial port:
|
STK500 programmer connected to the default serial port:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@cartouche
|
@cartouche
|
||||||
% avrdude -p m128 -c stk500 -e -U flash:w:diag.hex
|
% avrdude -p m128 -c stk500 -y -e -i m128diag.hex
|
||||||
|
|
||||||
avrdude: AVR device initialized and ready to accept instructions
|
avrdude: AVR device initialized and ready to accept instructions
|
||||||
|
|
||||||
Reading | ################################################## | 100% 0.03s
|
|
||||||
|
|
||||||
avrdude: Device signature = 0x1e9702
|
avrdude: Device signature = 0x1e9702
|
||||||
avrdude: erasing chip
|
avrdude: erasing chip
|
||||||
|
avrdude: erase-rewrite cycle count is now 52
|
||||||
avrdude: done.
|
avrdude: done.
|
||||||
avrdude: performing op: 1, flash, 0, diag.hex
|
avrdude: reading input file "m128diag.hex"
|
||||||
avrdude: reading input file "diag.hex"
|
avrdude: input file m128diag.hex auto detected as Intel Hex
|
||||||
avrdude: input file diag.hex auto detected as Intel Hex
|
avrdude: writing flash (18130 bytes):
|
||||||
avrdude: writing flash (19278 bytes):
|
18175
|
||||||
|
avrdude: 18176 bytes of flash written
|
||||||
Writing | ################################################## | 100% 7.60s
|
avrdude: verifying flash memory against m128diag.hex:
|
||||||
|
|
||||||
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:
|
avrdude: reading on-chip flash data:
|
||||||
|
18175
|
||||||
Reading | ################################################## | 100% 6.83s
|
|
||||||
|
|
||||||
avrdude: verifying ...
|
avrdude: verifying ...
|
||||||
avrdude: 19278 bytes of flash verified
|
avrdude: 18176 bytes of flash verified
|
||||||
|
|
||||||
avrdude done. Thank you.
|
avrdude done. Thank you.
|
||||||
|
|
||||||
%
|
%
|
||||||
@end cartouche
|
@end cartouche
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Upload the flash memory from the ATmega128 connected to the STK500
|
Upload the flash memory from the ATmega128 connected to the STK500
|
||||||
programmer and save it in raw binary format in the file named
|
programmer and save it in raw binary format in the file named
|
||||||
@code{c:/diag flash.bin}:
|
@code{m128diag.flash}:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@cartouche
|
@cartouche
|
||||||
% avrdude -p m128 -c stk500 -U flash:r:"c:/diag flash.bin":r
|
% avrdude -p m128 -c stk500 -f r -o m128diag.flash
|
||||||
|
|
||||||
avrdude: AVR device initialized and ready to accept instructions
|
avrdude: AVR device initialized and ready to accept instructions
|
||||||
|
|
||||||
Reading | ################################################## | 100% 0.03s
|
|
||||||
|
|
||||||
avrdude: Device signature = 0x1e9702
|
avrdude: Device signature = 0x1e9702
|
||||||
|
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
|
||||||
avrdude: reading flash memory:
|
avrdude: reading flash memory:
|
||||||
|
131071
|
||||||
Reading | ################################################## | 100% 46.10s
|
avrdude: writing output file "m128diag.flash"
|
||||||
|
|
||||||
avrdude: writing output file "c:/diag flash.bin"
|
|
||||||
|
|
||||||
avrdude done. Thank you.
|
avrdude done. Thank you.
|
||||||
|
|
||||||
@@ -628,55 +481,6 @@ avrdude done. Thank you.
|
|||||||
@end cartouche
|
@end cartouche
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
|
||||||
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 -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: 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.
|
|
||||||
|
|
||||||
%
|
|
||||||
@end cartouche
|
|
||||||
@end example
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@@ -744,33 +548,6 @@ Leave terminal mode and thus AVRDUDE.
|
|||||||
|
|
||||||
@end table
|
@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
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@@ -837,8 +614,8 @@ avrdude>
|
|||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Program the fuse bits of an ATmega128 (disable M103 compatibility,
|
Program the fuse bits of an ATmega128 (disable M103 compatibility,
|
||||||
enable high speed external crystal, enable brown-out detection, slowly
|
enable high speed external crystal, enable brown-out detection). First
|
||||||
rising power). First display the factory defaults, then reprogram:
|
display the factory defaults, then reprogram:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@cartouche
|
@cartouche
|
||||||
@@ -865,8 +642,8 @@ avrdude> w efuse 0 0xff
|
|||||||
avrdude> w hfuse 0 0x89
|
avrdude> w hfuse 0 0x89
|
||||||
>>> w hfuse 0 0x89
|
>>> w hfuse 0 0x89
|
||||||
|
|
||||||
avrdude> w lfuse 0 0x2f
|
avrdude> w lfuse 0 0x2e
|
||||||
>>> w lfuse 0 0x2f
|
>>> w lfuse 0 0x2e
|
||||||
|
|
||||||
avrdude>
|
avrdude>
|
||||||
@end cartouche
|
@end cartouche
|
||||||
@@ -942,18 +719,17 @@ The format of the programmer definition is as follows:
|
|||||||
@example
|
@example
|
||||||
programmer
|
programmer
|
||||||
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||||
desc = <description> ; # quoted string
|
desc = <description> ; # quoted string
|
||||||
type = par | stk500 ; # programmer type
|
type = par | stk500 ; # programmer type
|
||||||
baudrate = <num> ; # baudrate for avr910
|
vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||||
vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
reset = <num> ; # pin number
|
||||||
reset = <num> ; # pin number
|
sck = <num> ; # pin number
|
||||||
sck = <num> ; # pin number
|
mosi = <num> ; # pin number
|
||||||
mosi = <num> ; # pin number
|
miso = <num> ; # pin number
|
||||||
miso = <num> ; # pin number
|
errled = <num> ; # pin number
|
||||||
errled = <num> ; # pin number
|
rdyled = <num> ; # pin number
|
||||||
rdyled = <num> ; # pin number
|
pgmled = <num> ; # pin number
|
||||||
pgmled = <num> ; # pin number
|
vfyled = <num> ; # pin number
|
||||||
vfyled = <num> ; # pin number
|
|
||||||
;
|
;
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -1000,7 +776,7 @@ part
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Instruction Format::
|
* Instruction Format::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@@ -1048,7 +824,7 @@ instruction for an AT90S2313 AVR part could be encoded as:
|
|||||||
|
|
||||||
@example
|
@example
|
||||||
|
|
||||||
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
|
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";
|
"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",
|
write = "1 1 0 0 0 0 0 0 x x x x x x x x",
|
||||||
@@ -1068,7 +844,7 @@ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
|
|||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
The @code{devicecode} parameter is the device code used by the STK500
|
The @code{devicecode} parameter is the device code used by the STK500
|
||||||
and is obtained from the software section (@code{avr061.zip}) of
|
and are obtained from the software section (@code{avr061.zip} of
|
||||||
Atmel's AVR061 application note available from
|
Atmel's AVR061 application note available from
|
||||||
@url{http://www.atmel.com/atmel/acrobat/doc2525.pdf}.
|
@url{http://www.atmel.com/atmel/acrobat/doc2525.pdf}.
|
||||||
|
|
||||||
@@ -1103,12 +879,12 @@ problem with the at90s4433/2333's; see the at90s4433 errata at:
|
|||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
|
@node Platform Dependent Information, , Configuration File, Top
|
||||||
@appendix Platform Dependent Information
|
@appendix Platform Dependent Information
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Unix::
|
* Unix::
|
||||||
* Windows::
|
* Windows::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@@ -1493,8 +1269,6 @@ 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
|
be able to subsequently execute the batch file from any directory and have
|
||||||
it successfully start the driver.
|
it successfully start the driver.
|
||||||
|
|
||||||
Note that you must have administrator privilege to load the giveio driver.
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@@ -1544,55 +1318,4 @@ line driven and for writing the batch files.
|
|||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@c
|
|
||||||
@c Node
|
|
||||||
@c
|
|
||||||
@node Troubleshooting, ,Platform Dependent Information ,Top
|
|
||||||
@appendix Troubleshooting
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
|
|
||||||
@item
|
|
||||||
Problem: I'm using a serial programmer under Windows and get the following
|
|
||||||
error:
|
|
||||||
|
|
||||||
@code{avrdude: serial_open(): can't set attributes for device "com1"},
|
|
||||||
|
|
||||||
Solution: This problem seems to appear with certain versions of Cygwin. Specifying
|
|
||||||
@code{"/dev/com1"} instead of @code{"com1"} should help.
|
|
||||||
|
|
||||||
|
|
||||||
@item
|
|
||||||
Problem: I'm using linux and my AVR910 programmer is really slow.
|
|
||||||
|
|
||||||
Solution (short): @code{setserial @var{port} low_latency}
|
|
||||||
|
|
||||||
Solution (long):
|
|
||||||
There are two problems here. First, the system may wait some time before it
|
|
||||||
passes data from the serial port to the program. Under Linux the following
|
|
||||||
command works around this (you may need root privileges for this).
|
|
||||||
|
|
||||||
@code{setserial @var{port} low_latency}
|
|
||||||
|
|
||||||
Secondly, the serial interface chip may delay the interrupt for some time.
|
|
||||||
This behaviour can be changed by setting the FIFO-threshold to one. Under Linux this
|
|
||||||
can only be done by changing the kernel source in @code{drivers/char/serial.c}.
|
|
||||||
Search the file for @code{UART_FCR_TRIGGER_8} and replace it with @code{UART_FCR_TRIGGER_1}. Note that overall performance might suffer if there
|
|
||||||
is high throughput on serial lines. Also note that you are modifying the kernel at
|
|
||||||
your own risk.
|
|
||||||
|
|
||||||
|
|
||||||
@item
|
|
||||||
Problem: I'm not using linux and my AVR910 programmer is really slow.
|
|
||||||
|
|
||||||
Solutions: The reasons for this are the same as above.
|
|
||||||
If you know how to work around this on your OS, please let us know.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@bye
|
@bye
|
||||||
|
|
||||||
|
|||||||
199
avrdude/fileio.c
199
avrdude/fileio.c
@@ -360,10 +360,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
char * outfile, FILE * outf)
|
char * outfile, FILE * outf)
|
||||||
{
|
{
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
unsigned int nextaddr;
|
unsigned int nextaddr, stopaddr;
|
||||||
int n, nbytes, addr_width;
|
int n, nbytes, addr_width;
|
||||||
int i;
|
int i;
|
||||||
unsigned char cksum;
|
unsigned char cksum;
|
||||||
|
unsigned char startf, stopf ,emptyf;
|
||||||
|
|
||||||
char * tmpl=0;
|
char * tmpl=0;
|
||||||
|
|
||||||
@@ -372,11 +373,39 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
progname, recsize);
|
progname, recsize);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextaddr = startaddr;
|
|
||||||
buf = inbuf;
|
|
||||||
nbytes = 0;
|
|
||||||
|
|
||||||
|
buf = inbuf;
|
||||||
|
nextaddr = 0;
|
||||||
|
stopaddr = 0;
|
||||||
|
startf = 0;
|
||||||
|
stopf = 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;
|
addr_width = 0;
|
||||||
|
|
||||||
while (bufsize) {
|
while (bufsize) {
|
||||||
@@ -406,23 +435,34 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
/* skip the lines filled with 0xff */
|
||||||
|
emptyf = 1;
|
||||||
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++) {
|
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||||
fprintf(outf, "%02X", buf[i]);
|
if (buf[i] != 0xff) {
|
||||||
cksum += buf[i];
|
emptyf=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cksum = 0xff - cksum;
|
if (emptyf != 1) {
|
||||||
fprintf(outf, "%02X\n", cksum);
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
nextaddr += n;
|
nextaddr += n;
|
||||||
nbytes +=n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance to next 'recsize' bytes */
|
/* advance to next 'recsize' bytes */
|
||||||
@@ -688,49 +728,6 @@ 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,
|
int fileio_ihex(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size)
|
char * filename, FILE * f, unsigned char * buf, int size)
|
||||||
{
|
{
|
||||||
@@ -895,8 +892,8 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
char * fname;
|
char * fname;
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
struct fioparms fio;
|
struct fioparms fio;
|
||||||
|
int i;
|
||||||
AVRMEM * mem;
|
AVRMEM * mem;
|
||||||
int using_stdio;
|
|
||||||
|
|
||||||
mem = avr_locate_mem(p, memtype);
|
mem = avr_locate_mem(p, memtype);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
@@ -910,33 +907,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
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 (strcmp(filename, "-")==0) {
|
||||||
if (fio.op == FIO_READ) {
|
if (fio.op == FIO_READ) {
|
||||||
fname = "<stdin>";
|
fname = "<stdin>";
|
||||||
@@ -946,22 +916,30 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
fname = "<stdout>";
|
fname = "<stdout>";
|
||||||
f = stdout;
|
f = stdout;
|
||||||
}
|
}
|
||||||
using_stdio = 1;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fname = filename;
|
fname = filename;
|
||||||
f = NULL;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == FMT_AUTO) {
|
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);
|
format = fmt_autodetect(fname);
|
||||||
if (format < 0) {
|
if (format < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -974,17 +952,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
progname, fio.iodesc, fname, fmtstr(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) {
|
switch (format) {
|
||||||
case FMT_IHEX:
|
case FMT_IHEX:
|
||||||
rc = fileio_ihex(&fio, fname, f, buf, size);
|
rc = fileio_ihex(&fio, fname, f, buf, size);
|
||||||
@@ -998,26 +965,12 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
rc = fileio_rbin(&fio, fname, f, buf, size);
|
rc = fileio_rbin(&fio, fname, f, buf, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FMT_IMM:
|
|
||||||
rc = fileio_imm(&fio, fname, f, buf, size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||||
progname, fio.iodesc, format);
|
progname, fio.iodesc, format);
|
||||||
return -1;
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ typedef enum {
|
|||||||
FMT_AUTO,
|
FMT_AUTO,
|
||||||
FMT_SREC,
|
FMT_SREC,
|
||||||
FMT_IHEX,
|
FMT_IHEX,
|
||||||
FMT_RBIN,
|
FMT_RBIN
|
||||||
FMT_IMM
|
|
||||||
} FILEFMT;
|
} FILEFMT;
|
||||||
|
|
||||||
struct fioparms {
|
struct fioparms {
|
||||||
|
|||||||
@@ -117,7 +117,6 @@ SIGN [+-]
|
|||||||
|
|
||||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||||
banked { yylval=NULL; return K_PAGED; }
|
banked { yylval=NULL; return K_PAGED; }
|
||||||
baudrate { yylval=NULL; return K_BAUDRATE; }
|
|
||||||
bs2 { yylval=NULL; return K_BS2; }
|
bs2 { yylval=NULL; return K_BS2; }
|
||||||
buff { yylval=NULL; return K_BUFF; }
|
buff { yylval=NULL; return K_BUFF; }
|
||||||
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
||||||
@@ -126,8 +125,6 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
|||||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
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; }
|
eeprom { yylval=NULL; return K_EEPROM; }
|
||||||
errled { yylval=NULL; return K_ERRLED; }
|
errled { yylval=NULL; return K_ERRLED; }
|
||||||
flash { yylval=NULL; return K_FLASH; }
|
flash { yylval=NULL; return K_FLASH; }
|
||||||
@@ -155,8 +152,6 @@ retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
|||||||
serial { yylval=NULL; return K_SERIAL; }
|
serial { yylval=NULL; return K_SERIAL; }
|
||||||
size { yylval=NULL; return K_SIZE; }
|
size { yylval=NULL; return K_SIZE; }
|
||||||
stk500 { yylval=NULL; return K_STK500; }
|
stk500 { yylval=NULL; return K_STK500; }
|
||||||
avr910 { yylval=NULL; return K_AVR910; }
|
|
||||||
butterfly { yylval=NULL; return K_BUTTERFLY; }
|
|
||||||
type { yylval=NULL; return K_TYPE; }
|
type { yylval=NULL; return K_TYPE; }
|
||||||
vcc { yylval=NULL; return K_VCC; }
|
vcc { yylval=NULL; return K_VCC; }
|
||||||
vfyled { yylval=NULL; return K_VFYLED; }
|
vfyled { yylval=NULL; return K_VFYLED; }
|
||||||
|
|||||||
870
avrdude/main.c
870
avrdude/main.c
File diff suppressed because it is too large
Load Diff
@@ -319,6 +319,8 @@ static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
unsigned char res[4];
|
unsigned char res[4];
|
||||||
|
int cycles;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||||
@@ -326,6 +328,19 @@ static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = avr_get_cycle_count(pgm, p, &cycles);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* only print out the current cycle count if we aren't going to
|
||||||
|
* display it below
|
||||||
|
*/
|
||||||
|
if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: current erase-rewrite cycle count is %d%s\n",
|
||||||
|
progname, cycles,
|
||||||
|
do_cycles ? "" : " (if being tracked)");
|
||||||
|
}
|
||||||
|
|
||||||
pgm->pgm_led(pgm, ON);
|
pgm->pgm_led(pgm, ON);
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(cmd));
|
memset(cmd, 0, sizeof(cmd));
|
||||||
@@ -337,6 +352,16 @@ static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
|
|
||||||
pgm->pgm_led(pgm, OFF);
|
pgm->pgm_led(pgm, OFF);
|
||||||
|
|
||||||
|
if (do_cycles && (cycles != -1)) {
|
||||||
|
if (cycles == 0x00ffff) {
|
||||||
|
cycles = 0;
|
||||||
|
}
|
||||||
|
cycles++;
|
||||||
|
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
||||||
|
progname, cycles);
|
||||||
|
avr_put_cycle_count(pgm, p, cycles);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ PROGRAMMER * pgm_new(void)
|
|||||||
pgm->type[0] = 0;
|
pgm->type[0] = 0;
|
||||||
pgm->config_file[0] = 0;
|
pgm->config_file[0] = 0;
|
||||||
pgm->lineno = 0;
|
pgm->lineno = 0;
|
||||||
pgm->baudrate = 0;
|
|
||||||
|
|
||||||
for (i=0; i<N_PINS; i++)
|
for (i=0; i<N_PINS; i++)
|
||||||
pgm->pinno[i] = 0;
|
pgm->pinno[i] = 0;
|
||||||
@@ -90,13 +89,6 @@ PROGRAMMER * pgm_new(void)
|
|||||||
*/
|
*/
|
||||||
pgm->paged_write = NULL;
|
pgm->paged_write = NULL;
|
||||||
pgm->paged_load = 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;
|
return pgm;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ typedef struct programmer_t {
|
|||||||
char port[PGM_PORTLEN];
|
char port[PGM_PORTLEN];
|
||||||
unsigned int pinno[N_PINS];
|
unsigned int pinno[N_PINS];
|
||||||
int ppidata;
|
int ppidata;
|
||||||
int baudrate;
|
|
||||||
int fd;
|
int fd;
|
||||||
int page_size; /* page size if the programmer supports paged write/load */
|
int page_size; /* page size if the programmer supports paged write/load */
|
||||||
int (*rdy_led) (struct programmer_t * pgm, int value);
|
int (*rdy_led) (struct programmer_t * pgm, int value);
|
||||||
@@ -67,16 +66,6 @@ typedef struct programmer_t {
|
|||||||
int page_size, int n_bytes);
|
int page_size, int n_bytes);
|
||||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||||
int page_size, int n_bytes);
|
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 */
|
char config_file[PATH_MAX]; /* config file where defined */
|
||||||
int lineno; /* config file line number */
|
int lineno; /* config file line number */
|
||||||
} PROGRAMMER;
|
} PROGRAMMER;
|
||||||
|
|||||||
108
avrdude/ppi.c
108
avrdude/ppi.c
@@ -43,33 +43,24 @@
|
|||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
|
||||||
enum {
|
/*
|
||||||
PPI_READ,
|
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
|
||||||
PPI_WRITE,
|
* to get/set the specified PPI registers.
|
||||||
PPI_SHADOWREAD
|
*/
|
||||||
};
|
static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
|
||||||
|
|
||||||
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
|
|
||||||
{
|
{
|
||||||
static unsigned char shadow[3];
|
|
||||||
int shadow_num;
|
|
||||||
unsigned long set, get;
|
|
||||||
|
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
case PPIDATA:
|
case PPIDATA:
|
||||||
set = PPISDATA;
|
*set = PPISDATA;
|
||||||
get = PPIGDATA;
|
*get = PPIGDATA;
|
||||||
shadow_num = 0;
|
|
||||||
break;
|
break;
|
||||||
case PPICTRL:
|
case PPICTRL:
|
||||||
set = PPISCTRL;
|
*set = PPISCTRL;
|
||||||
get = PPIGCTRL;
|
*get = PPIGCTRL;
|
||||||
shadow_num = 1;
|
|
||||||
break;
|
break;
|
||||||
case PPISTATUS:
|
case PPISTATUS:
|
||||||
set = PPISSTATUS;
|
*set = PPISSTATUS;
|
||||||
get = PPIGSTATUS;
|
*get = PPIGSTATUS;
|
||||||
shadow_num = 2;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
|
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
|
||||||
@@ -78,37 +69,27 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case PPI_SHADOWREAD:
|
|
||||||
*v = shadow[shadow_num];
|
|
||||||
break;
|
|
||||||
case PPI_READ:
|
|
||||||
ioctl(fd, get, v);
|
|
||||||
shadow[shadow_num]=*v;
|
|
||||||
break;
|
|
||||||
case PPI_WRITE:
|
|
||||||
shadow[shadow_num]=*v;
|
|
||||||
ioctl(fd, set, v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set the indicated bit of the specified register.
|
* set the indicated bit of the specified register.
|
||||||
*/
|
*/
|
||||||
int ppi_set(int fd, int reg, int bit)
|
int ppi_set(int fd, int reg, int bit)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
rc = ppi_getops(reg, &get, &set);
|
||||||
v |= bit;
|
|
||||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ioctl(fd, get, &v);
|
||||||
|
v |= bit;
|
||||||
|
ioctl(fd, set, &v);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,15 +100,17 @@ int ppi_set(int fd, int reg, int bit)
|
|||||||
int ppi_clr(int fd, int reg, int bit)
|
int ppi_clr(int fd, int reg, int bit)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
rc = ppi_getops(reg, &get, &set);
|
||||||
v &= ~bit;
|
|
||||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ioctl(fd, get, &v);
|
||||||
|
v &= ~bit;
|
||||||
|
ioctl(fd, set, &v);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,14 +121,16 @@ int ppi_clr(int fd, int reg, int bit)
|
|||||||
int ppi_get(int fd, int reg, int bit)
|
int ppi_get(int fd, int reg, int bit)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
rc = ppi_getops(reg, &get, &set);
|
||||||
v &= bit;
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ioctl(fd, get, &v);
|
||||||
|
v &= bit;
|
||||||
|
|
||||||
return v; /* v == bit */
|
return v; /* v == bit */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,15 +140,17 @@ int ppi_get(int fd, int reg, int bit)
|
|||||||
int ppi_toggle(int fd, int reg, int bit)
|
int ppi_toggle(int fd, int reg, int bit)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
rc = ppi_getops(reg, &get, &set);
|
||||||
v ^= bit;
|
|
||||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ioctl(fd, get, &v);
|
||||||
|
v ^= bit;
|
||||||
|
ioctl(fd, set, &v);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,14 +161,16 @@ int ppi_toggle(int fd, int reg, int bit)
|
|||||||
int ppi_getall(int fd, int reg)
|
int ppi_getall(int fd, int reg)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
rc = ppi_getops(reg, &get, &set);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return v; /* v == bit */
|
ioctl(fd, get, &v);
|
||||||
|
|
||||||
|
return (int)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -190,14 +179,16 @@ int ppi_getall(int fd, int reg)
|
|||||||
int ppi_setall(int fd, int reg, int val)
|
int ppi_setall(int fd, int reg, int val)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
unsigned long get, set;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
v = val;
|
rc = ppi_getops(reg, &get, &set);
|
||||||
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
v = val;
|
||||||
|
ioctl(fd, set, &v);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +196,6 @@ int ppi_setall(int fd, int reg, int val)
|
|||||||
int ppi_open(char * port)
|
int ppi_open(char * port)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
unsigned char v;
|
|
||||||
|
|
||||||
fd = open(port, O_RDWR);
|
fd = open(port, O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -214,14 +204,6 @@ int ppi_open(char * port)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize shadow registers
|
|
||||||
*/
|
|
||||||
|
|
||||||
ppi_shadow_access (fd, PPIDATA, &v, PPI_READ);
|
|
||||||
ppi_shadow_access (fd, PPICTRL, &v, PPI_READ);
|
|
||||||
ppi_shadow_access (fd, PPISTATUS, &v, PPI_READ);
|
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
|
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,8 +39,6 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <w32api/windows.h>
|
|
||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -317,78 +315,6 @@ static void outb(unsigned char value, unsigned short port)
|
|||||||
return;
|
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
|
#endif
|
||||||
|
|||||||
@@ -1,352 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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__ */
|
|
||||||
549
avrdude/stk500.c
549
avrdude/stk500.c
@@ -33,42 +33,171 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
#include "stk500_private.h"
|
#include "stk500_private.h"
|
||||||
#include "serial.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern int verbose;
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
extern int do_cycles;
|
extern int do_cycles;
|
||||||
|
|
||||||
|
|
||||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
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_is_page_empty(unsigned int address, int page_size,
|
|
||||||
const unsigned char *buf);
|
|
||||||
|
|
||||||
|
|
||||||
static int stk500_send(PROGRAMMER * pgm, char * buf, size_t len)
|
static int stk500_send(PROGRAMMER * pgm, char * buf, int buflen)
|
||||||
{
|
{
|
||||||
return serial_send(pgm->fd, buf, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int stk500_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
|
||||||
|
static int stk500_recv(PROGRAMMER * pgm, char * buf, int n)
|
||||||
{
|
{
|
||||||
return serial_recv(pgm->fd, buf, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int stk500_drain(PROGRAMMER * pgm, int display)
|
static int stk500_drain(PROGRAMMER * pgm, int display)
|
||||||
{
|
{
|
||||||
return serial_drain(pgm->fd, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -171,6 +300,8 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
unsigned char res[4];
|
unsigned char res[4];
|
||||||
|
int cycles;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||||
@@ -178,6 +309,19 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = avr_get_cycle_count(pgm, p, &cycles);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* only print out the current cycle count if we aren't going to
|
||||||
|
* display it below
|
||||||
|
*/
|
||||||
|
if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: current erase-rewrite cycle count is %d%s\n",
|
||||||
|
progname, cycles,
|
||||||
|
do_cycles ? "" : " (if being tracked)");
|
||||||
|
}
|
||||||
|
|
||||||
pgm->pgm_led(pgm, ON);
|
pgm->pgm_led(pgm, ON);
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(cmd));
|
memset(cmd, 0, sizeof(cmd));
|
||||||
@@ -189,6 +333,16 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
|
|
||||||
pgm->pgm_led(pgm, OFF);
|
pgm->pgm_led(pgm, OFF);
|
||||||
|
|
||||||
|
if (do_cycles && (cycles != -1)) {
|
||||||
|
if (cycles == 0x00ffff) {
|
||||||
|
cycles = 0;
|
||||||
|
}
|
||||||
|
cycles++;
|
||||||
|
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
||||||
|
progname, cycles);
|
||||||
|
avr_put_cycle_count(pgm, p, cycles);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +518,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||||||
*/
|
*/
|
||||||
buf[0] = Cmnd_STK_SET_DEVICE;
|
buf[0] = Cmnd_STK_SET_DEVICE;
|
||||||
|
|
||||||
buf[1] = p->stk500_devcode;
|
buf[1] = p->devicecode;
|
||||||
buf[2] = 0; /* device revision */
|
buf[2] = 0; /* device revision */
|
||||||
|
|
||||||
if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
|
if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
|
||||||
@@ -585,10 +739,72 @@ 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)
|
static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
strcpy(pgm->port, port);
|
strcpy(pgm->port, port);
|
||||||
pgm->fd = serial_open(port, 115200);
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drain any extraneous input
|
* drain any extraneous input
|
||||||
@@ -603,7 +819,7 @@ static void stk500_open(PROGRAMMER * pgm, char * port)
|
|||||||
|
|
||||||
static void stk500_close(PROGRAMMER * pgm)
|
static void stk500_close(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
serial_close(pgm->fd);
|
close(pgm->fd);
|
||||||
pgm->fd = -1;
|
pgm->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,10 +878,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
int memtype;
|
int memtype;
|
||||||
unsigned int addr;
|
unsigned int addr;
|
||||||
int a_div;
|
int a_div;
|
||||||
int block_size;
|
int i;
|
||||||
int tries;
|
int tries;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
int flash;
|
|
||||||
|
|
||||||
if (page_size == 0) {
|
if (page_size == 0) {
|
||||||
page_size = 128;
|
page_size = 128;
|
||||||
@@ -673,11 +888,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
|
|
||||||
if (strcmp(m->desc, "flash") == 0) {
|
if (strcmp(m->desc, "flash") == 0) {
|
||||||
memtype = 'F';
|
memtype = 'F';
|
||||||
flash = 1;
|
|
||||||
}
|
}
|
||||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||||
memtype = 'E';
|
memtype = 'E';
|
||||||
flash = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -2;
|
return -2;
|
||||||
@@ -711,33 +924,20 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (addr = 0; addr < n; addr += page_size) {
|
for (addr = 0; addr < n; addr += page_size) {
|
||||||
report_progress (addr, n_bytes, NULL);
|
fprintf(stderr, "\r \r%6u", addr);
|
||||||
|
|
||||||
if (addr + page_size > n_bytes) {
|
|
||||||
block_size = n_bytes % page_size;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
block_size = page_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only skip on empty page if programming flash. */
|
|
||||||
if (flash) {
|
|
||||||
if (stk500_is_page_empty(addr, block_size, m->buf)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tries = 0;
|
tries = 0;
|
||||||
retry:
|
retry:
|
||||||
tries++;
|
tries++;
|
||||||
stk500_loadaddr(pgm, addr/a_div);
|
stk500_loadaddr(pgm, addr/a_div);
|
||||||
buf[0] = Cmnd_STK_PROG_PAGE;
|
buf[0] = Cmnd_STK_PROG_PAGE;
|
||||||
buf[1] = (block_size >> 8) & 0xff;
|
buf[1] = (page_size >> 8) & 0xff;
|
||||||
buf[2] = block_size & 0xff;
|
buf[2] = page_size & 0xff;
|
||||||
buf[3] = memtype;
|
buf[3] = memtype;
|
||||||
stk500_send(pgm, buf, 4);
|
stk500_send(pgm, buf, 4);
|
||||||
|
for (i=0; i<page_size; i++) {
|
||||||
stk500_send(pgm, &m->buf[addr], block_size);
|
buf[0] = m->buf[addr + i];
|
||||||
|
stk500_send(pgm, buf, 1);
|
||||||
|
}
|
||||||
buf[0] = Sync_CRC_EOP;
|
buf[0] = Sync_CRC_EOP;
|
||||||
stk500_send(pgm, buf, 1);
|
stk500_send(pgm, buf, 1);
|
||||||
|
|
||||||
@@ -768,24 +968,12 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "\r \r%6u", addr-1);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
return n_bytes;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stk500_is_page_empty(unsigned int address, int page_size,
|
|
||||||
const unsigned char *buf)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < page_size; i++) {
|
|
||||||
if(buf[address + i] != 0xFF) {
|
|
||||||
/* Page is not empty. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Page is empty. */
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||||
int page_size, int n_bytes)
|
int page_size, int n_bytes)
|
||||||
@@ -796,7 +984,6 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
int a_div;
|
int a_div;
|
||||||
int tries;
|
int tries;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
int block_size;
|
|
||||||
|
|
||||||
if (strcmp(m->desc, "flash") == 0) {
|
if (strcmp(m->desc, "flash") == 0) {
|
||||||
memtype = 'F';
|
memtype = 'F';
|
||||||
@@ -827,22 +1014,14 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (addr = 0; addr < n; addr += page_size) {
|
for (addr = 0; addr < n; addr += page_size) {
|
||||||
report_progress (addr, n_bytes, NULL);
|
fprintf(stderr, "\r \r%6u", addr);
|
||||||
|
|
||||||
if (addr + page_size > n_bytes) {
|
|
||||||
block_size = n_bytes % page_size;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
block_size = page_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
tries = 0;
|
tries = 0;
|
||||||
retry:
|
retry:
|
||||||
tries++;
|
tries++;
|
||||||
stk500_loadaddr(pgm, addr/a_div);
|
stk500_loadaddr(pgm, addr/a_div);
|
||||||
buf[0] = Cmnd_STK_READ_PAGE;
|
buf[0] = Cmnd_STK_READ_PAGE;
|
||||||
buf[1] = (block_size >> 8) & 0xff;
|
buf[1] = (page_size >> 8) & 0xff;
|
||||||
buf[2] = block_size & 0xff;
|
buf[2] = page_size & 0xff;
|
||||||
buf[3] = memtype;
|
buf[3] = memtype;
|
||||||
buf[4] = Sync_CRC_EOP;
|
buf[4] = Sync_CRC_EOP;
|
||||||
stk500_send(pgm, buf, 5);
|
stk500_send(pgm, buf, 5);
|
||||||
@@ -865,7 +1044,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
stk500_recv(pgm, &m->buf[addr], block_size);
|
stk500_recv(pgm, &m->buf[addr], page_size);
|
||||||
|
|
||||||
stk500_recv(pgm, buf, 1);
|
stk500_recv(pgm, buf, 1);
|
||||||
if (buf[0] != Resp_STK_OK) {
|
if (buf[0] != Resp_STK_OK) {
|
||||||
@@ -876,108 +1055,10 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "\r \r%6u", addr-1);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
return n_bytes;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1037,141 +1118,21 @@ 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)
|
static void stk500_display(PROGRAMMER * pgm, char * p)
|
||||||
{
|
{
|
||||||
unsigned maj, min, hdw, topcard;
|
unsigned maj, min, hdw;
|
||||||
|
|
||||||
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
|
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
|
||||||
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
||||||
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
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, "%sHardware Version: %d\n", p, hdw);
|
||||||
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
|
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;
|
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)
|
void stk500_initpgm(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
strcpy(pgm->type, "STK500");
|
strcpy(pgm->type, "STK500");
|
||||||
@@ -1202,9 +1163,7 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
|||||||
*/
|
*/
|
||||||
pgm->paged_write = stk500_paged_write;
|
pgm->paged_write = stk500_paged_write;
|
||||||
pgm->paged_load = stk500_paged_load;
|
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;
|
pgm->page_size = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
||||||
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
||||||
#define Parm_STK_SELFTIMED 0x96 // ' ' - 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 ]***************************
|
// *****************[ STK status bit definitions ]***************************
|
||||||
|
|
||||||
|
|||||||
128
avrdude/term.c
128
avrdude/term.c
@@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
#include "ac_cfg.h"
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -68,14 +66,6 @@ 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_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[] = {
|
struct command cmd[] = {
|
||||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||||
@@ -85,10 +75,6 @@ struct command cmd[] = {
|
|||||||
{ "sig", cmd_sig, "display device signature bytes" },
|
{ "sig", cmd_sig, "display device signature bytes" },
|
||||||
{ "part", cmd_part, "display the current part information" },
|
{ "part", cmd_part, "display the current part information" },
|
||||||
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
|
{ "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" },
|
{ "help", cmd_help, "help" },
|
||||||
{ "?", cmd_help, "help" },
|
{ "?", cmd_help, "help" },
|
||||||
{ "quit", cmd_quit, "quit" }
|
{ "quit", cmd_quit, "quit" }
|
||||||
@@ -511,120 +497,6 @@ 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 cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ EXTRA_DIST = \
|
|||||||
|
|
||||||
bin_PROGRAMS = loaddrv
|
bin_PROGRAMS = loaddrv
|
||||||
|
|
||||||
loaddrv_LDFLAGS = -mno-cygwin
|
loaddrv_CFLAGS = -mno-cygwin
|
||||||
|
|
||||||
loaddrv_SOURCES = \
|
loaddrv_SOURCES = \
|
||||||
loaddrv.c \
|
loaddrv.c \
|
||||||
|
|||||||
Reference in New Issue
Block a user