mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-16 10:41:07 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
078a334625 |
@@ -5,6 +5,5 @@ AVRDUDE was written by:
|
||||
Contributors:
|
||||
|
||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Eric Weddington <eric@ecentral.com>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Eric Weddington <eric@umginc.net>
|
||||
|
||||
|
||||
@@ -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.
|
||||
(AC_INIT): Set version to 4.3.0.
|
||||
* windows/Makefile.am: Fix uninstall-local rule (forget the $$file
|
||||
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.
|
||||
Move to all 2003 entries to ChangeLog-2003.
|
||||
* ChangeLog-2003: New file.
|
||||
* Makefile.am: Update copyright year.
|
||||
(EXTRA_DIST): Add ChangeLog-2003.
|
||||
* AUTHORS: Updated.
|
||||
* CHANGELOG: Move contents to NEWS and remove file.
|
||||
* ChangeLog: All of the changes for this year.
|
||||
* ChangeLog-2001: All 2001 changes.
|
||||
* 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
|
||||
hbox".
|
||||
* doc/avrdude.texi:
|
||||
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:
|
||||
Look up devicecode and report device.
|
||||
* stk500.c: Disable debugging printf.
|
||||
|
||||
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
|
||||
parameter baudrate to support avr910-programmers with non-standard
|
||||
baudrates.
|
||||
* avrdude.conf.in, doc/avrdude.texi: Added "baudrate" to documentation.
|
||||
2003-03-10 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
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
|
||||
avr_chip_erase() to unify handling of cycle-count.
|
||||
Makes cycle-count work for avr910-programmers.
|
||||
* bootstrap:
|
||||
Export ${AUTOCONF} so automake will find it by whatever name it will be
|
||||
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
|
||||
# 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
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,6 @@
|
||||
EXTRA_DIST = \
|
||||
ChangeLog-2001 \
|
||||
ChangeLog-2002 \
|
||||
ChangeLog-2003 \
|
||||
avrdude.1 \
|
||||
avrdude.pdf \
|
||||
avrdude.spec \
|
||||
@@ -40,9 +39,7 @@ DIST_SUBDIRS = doc windows
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
@@ -51,12 +48,7 @@ avrdude_SOURCES = \
|
||||
lexer.l \
|
||||
avr.c \
|
||||
avr.h \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrpart.c \
|
||||
avrpart.h \
|
||||
butterfly.c \
|
||||
butterfly.h \
|
||||
config.c \
|
||||
config.h \
|
||||
confwin.c \
|
||||
@@ -75,9 +67,6 @@ avrdude_SOURCES = \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
serial.h \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
stk500.c \
|
||||
stk500.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
|
||||
|
||||
* 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
|
||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
||||
<troth@openavr.org>.
|
||||
<troth@openavr.org>
|
||||
|
||||
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||
<tsar@kemford.com>.
|
||||
<tsar@kemford.com>
|
||||
|
||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||
'bs2' keywords to the config file for this purpose.
|
||||
@@ -299,4 +233,4 @@ Version 1.3.0 :
|
||||
|
||||
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 <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "avr.h"
|
||||
@@ -45,8 +43,255 @@ extern PROGRAMMER * pgm;
|
||||
extern int do_cycles;
|
||||
|
||||
|
||||
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 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
|
||||
* 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;
|
||||
AVRMEM * mem;
|
||||
int rc;
|
||||
int printed;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
@@ -170,11 +369,6 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
size = mem->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with all 0xff
|
||||
*/
|
||||
memset(buf, 0xff, size);
|
||||
|
||||
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
|
||||
if (pgm->paged_load != NULL) {
|
||||
/*
|
||||
@@ -183,27 +377,16 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
* instead
|
||||
*/
|
||||
if (mem->paged) {
|
||||
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||
}
|
||||
else {
|
||||
rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return pgm->paged_load(pgm, p, mem, pgm->page_size, size);
|
||||
}
|
||||
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) {
|
||||
return pgm->read_sig_bytes(pgm, p, mem);
|
||||
}
|
||||
}
|
||||
|
||||
printed = 0;
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
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;
|
||||
}
|
||||
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)
|
||||
return avr_mem_hiaddr(mem);
|
||||
else
|
||||
return i;
|
||||
if (printed) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
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
|
||||
* 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);
|
||||
|
||||
@@ -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 char cmd[4];
|
||||
@@ -279,14 +471,11 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned char r;
|
||||
int ready;
|
||||
int tries;
|
||||
unsigned long start_time;
|
||||
unsigned long prog_time;
|
||||
unsigned char b;
|
||||
unsigned short caddr;
|
||||
OPCODE * writeop;
|
||||
int rc;
|
||||
int readok=0;
|
||||
struct timeval tv;
|
||||
|
||||
if (!mem->paged) {
|
||||
/*
|
||||
@@ -376,6 +565,13 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
tries = 0;
|
||||
ready = 0;
|
||||
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]) ||
|
||||
(data == mem->readback[1])) {
|
||||
@@ -393,29 +589,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
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) {
|
||||
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
|
||||
* 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);
|
||||
fprintf(stderr,
|
||||
"%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
|
||||
* 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;
|
||||
int werror;
|
||||
AVRMEM * m;
|
||||
int printed;
|
||||
|
||||
m = avr_locate_mem(p, memtype);
|
||||
if (m == NULL) {
|
||||
@@ -522,6 +677,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
|
||||
printed = 0;
|
||||
werror = 0;
|
||||
|
||||
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++) {
|
||||
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);
|
||||
if (rc) {
|
||||
fprintf(stderr, " ***failed; ");
|
||||
@@ -588,11 +744,15 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
if (werror) {
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (printed)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -605,15 +765,36 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc;
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, p, "signature", 0, 0);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(stderr,
|
||||
"%s: error reading signature data for part \"%s\", rc=%d\n",
|
||||
progname, p->desc, rc);
|
||||
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;
|
||||
}
|
||||
@@ -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
|
||||
* 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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
AVRMEM * a;
|
||||
unsigned int cycle_count = 0;
|
||||
unsigned char v1;
|
||||
int cycle_count;
|
||||
unsigned char v1, v2, v3, v4;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
a = avr_locate_mem(p, "eeprom");
|
||||
if (a == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=4; i>0; i--) {
|
||||
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
|
||||
rc = avr_read_byte(pgm, p, a, a->size-4, &v1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||
progname, rc);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the EEPROM is erased, the cycle count reads 0xffffffff.
|
||||
* In this case we return a cycle_count of zero.
|
||||
* So, the calling function don't have to care about whether or not
|
||||
* the cycle count was initialized.
|
||||
*/
|
||||
if (cycle_count == 0xffffffff) {
|
||||
cycle_count = 0;
|
||||
rc = avr_read_byte(pgm, p, a, a->size-2, &v3);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||
progname, rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
AVRMEM * a;
|
||||
unsigned char v1;
|
||||
unsigned char v1, v2, v3, v4;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
a = avr_locate_mem(p, "eeprom");
|
||||
if (a == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=1; i<=4; i++) {
|
||||
v1 = cycles & 0xff;
|
||||
cycles = cycles >> 8;
|
||||
v4 = cycles & 0x0ff;
|
||||
v3 = (cycles & 0x0ff00) >> 8;
|
||||
v2 = (cycles & 0x0ff0000) >> 16;
|
||||
v1 = (cycles & 0x0ff000000) >> 24;
|
||||
|
||||
rc = avr_write_byte(pgm, p, a, a->size-i, v1);
|
||||
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-4, v1);
|
||||
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-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;
|
||||
}
|
||||
}
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
|
||||
char * avr_op_str(int op)
|
||||
{
|
||||
int cycles;
|
||||
int rc;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_cycles) {
|
||||
rc = avr_get_cycle_count(pgm, p, &cycles);
|
||||
/*
|
||||
* Don't update the cycle counter, if read failed
|
||||
*/
|
||||
if(rc != 0) {
|
||||
do_cycles = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* Don't update the cycle counter, if erase failed
|
||||
*/
|
||||
if (do_cycles && (rc == 0)) {
|
||||
cycles++;
|
||||
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
||||
progname, cycles);
|
||||
avr_put_cycle_count(pgm, p, cycles);
|
||||
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);
|
||||
}
|
||||
|
||||
return rc;
|
||||
if (buf)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,14 +33,29 @@
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 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,
|
||||
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 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);
|
||||
|
||||
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);
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
||||
|
||||
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
|
||||
|
||||
int avr_mem_hiaddr(AVRMEM * mem);
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
extern void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#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$
|
||||
.\"
|
||||
.Dd DATE November 26, 2003
|
||||
.Dd DATE January 11, 2002
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -30,7 +30,6 @@
|
||||
.Fl p Ar partno
|
||||
.Op Fl c Ar programmer-id
|
||||
.Op Fl C Ar config-file
|
||||
.Op Fl D
|
||||
.Op Fl e
|
||||
.Oo Fl E Ar exitspec Ns
|
||||
.Op \&, Ns Ar exitspec
|
||||
@@ -42,9 +41,7 @@
|
||||
.Op Fl o Ar filename
|
||||
.Op Fl n
|
||||
.Op Fl P Ar port
|
||||
.Op Fl q
|
||||
.Op Fl t
|
||||
.Op Fl U Ar memtype:op:filename:filefmt
|
||||
.Op Fl v
|
||||
.Op Fl V
|
||||
.Op Fl y
|
||||
@@ -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
|
||||
interactively communicate with the MCU, and to display or program
|
||||
individual memory cells.
|
||||
On the STK500 programmer, several operational parameters (target supply
|
||||
voltage, target Aref voltage, master clock) can be examined and changed
|
||||
from within terminal mode as well.
|
||||
.Ss Options
|
||||
In order to control all the different operation modi, a number of options
|
||||
need to be specified to
|
||||
@@ -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
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.It Fl D
|
||||
Disable auto erase for flash. When the
|
||||
.Fl U
|
||||
option with flash memory is specified,
|
||||
.Nm
|
||||
will perform a chip erase before starting any of the programming
|
||||
operations, since it generally is a mistake to program the flash
|
||||
without performing an erase first. This option disables that.
|
||||
However, to remain backward compatible, the
|
||||
.Fl i ,
|
||||
and
|
||||
.Fl m
|
||||
options automatically disable the auto erase feature.
|
||||
.It Fl e
|
||||
Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value
|
||||
@@ -258,10 +239,8 @@ Multiple
|
||||
.Ar exitspec
|
||||
arguments can be separated with commas.
|
||||
.It Fl f Ar format
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) This option specifies the file format for the input or
|
||||
output files to be processed.
|
||||
This option specifies the file format for the input or output files
|
||||
to be processed.
|
||||
.Ar Format
|
||||
can be one of:
|
||||
.Bl -tag -width sss
|
||||
@@ -271,10 +250,6 @@ Intel Hex
|
||||
Motorola S-record
|
||||
.It Ar r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
.It Ar m
|
||||
immediate; actual byte values specified on the command line, seperated
|
||||
by commas or spaces. This is good for programming fuse bytes without
|
||||
having to create a single-byte file or enter terminal mode.
|
||||
.It Ar a
|
||||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
@@ -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
|
||||
override the check.
|
||||
.It Fl i Ar filename
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies the input file to be programmed into the MCU.
|
||||
Can be specified as
|
||||
Specifies the input file to be programmed into the MCU. Can be specified
|
||||
as
|
||||
.Ql \&-
|
||||
to use
|
||||
.Em stdin
|
||||
as the input.
|
||||
.It Fl I Ar data
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Same as specifying
|
||||
.Fl i
|
||||
and
|
||||
.Fl f Ar m
|
||||
together, i.e., this is a shortcut for using immediate file input mode
|
||||
where the filename field is used as the data itself. Useful for
|
||||
programming single byte memories such as fuse bytes without having to
|
||||
use single byte files or enter interactive terminal mode.
|
||||
.It Fl m Ar memtype
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies which program area of the MCU to read or write;
|
||||
allowable values depend on the MCU being programmed, but most support
|
||||
at least
|
||||
Specifies which program area of the MCU to read or write; allowable
|
||||
values depend on the MCU being programmed, but most support at least
|
||||
.Em eeprom
|
||||
for the EEPROM, and
|
||||
.Em flash
|
||||
@@ -332,11 +291,8 @@ No-write - disables actually writing data to the MCU (useful for debugging
|
||||
.Nm avrdude
|
||||
).
|
||||
.It Fl o Ar filename
|
||||
(Deprecated, use
|
||||
.Fl U
|
||||
instead.) Specifies the name of the output file to write, and causes
|
||||
the respective memory area to be read from the MCU. Can be specified
|
||||
as
|
||||
Specifies the name of the output file to write, and causes the respective
|
||||
memory area to be read from the MCU. Can be specified as
|
||||
.Ql \&-
|
||||
to write to
|
||||
.Em stdout .
|
||||
@@ -351,49 +307,11 @@ serial port, the
|
||||
.Pa /dev/cuaa0
|
||||
port is the default. If you need to use a different parallel or
|
||||
serial port, use this option to specify the alternate port name.
|
||||
.It Fl q
|
||||
Disable (or quell) output of the progress bar while reading or writing
|
||||
to the device.
|
||||
.It Fl t
|
||||
Tells
|
||||
.Nm
|
||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||
files. See below for a detailed description of the terminal mode.
|
||||
.It Xo Fl U Ar memtype Ns
|
||||
.Ar \&: Ns Ar op Ns
|
||||
.Ar \&: Ns Ar filename Ns
|
||||
.Op \&: Ns Ar format
|
||||
.Xc
|
||||
Perform a memory operation as indicated. The
|
||||
.Ar memtype
|
||||
field specifies the memory type to operate on. The
|
||||
.Ar op
|
||||
field specifies what operation to perform:
|
||||
.Bl -tag -width noreset
|
||||
.It Ar r
|
||||
read device memory and write to the specified file
|
||||
.It Ar w
|
||||
read data from the specified file and write to the device memory
|
||||
.It Ar v
|
||||
read data from both the device and the specified file and perform a verify
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar filename
|
||||
field indicates the name of the file to read or write.
|
||||
The
|
||||
.Ar format
|
||||
field is optional and contains the format of the file to read or
|
||||
write. See the
|
||||
.Fl f
|
||||
option for possible values.
|
||||
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
|
||||
Enable verbose output.
|
||||
.It Fl V
|
||||
@@ -467,35 +385,6 @@ does not implement the command.
|
||||
Display the device signature bytes.
|
||||
.It Ar part
|
||||
Display the current part settings.
|
||||
.It Ar vtarg voltage
|
||||
Set the target's supply voltage to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar varef voltage
|
||||
Set the adjustable voltage source to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
.Em Aref
|
||||
input on the STK500.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc freq Ns Op M Ns \&| Ns k
|
||||
Set the master oscillator to
|
||||
.Ar freq
|
||||
Hz.
|
||||
An optional trailing letter
|
||||
.Ar \&M
|
||||
multiplies by 1E6, a trailing letter
|
||||
.Ar \&k
|
||||
by 1E3.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar \&?
|
||||
.It Ar help
|
||||
Give a short on-line summary of the available commands.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,6 @@
|
||||
## @configure_input@
|
||||
##
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||
Name: avrdude
|
||||
Version: @VERSION@
|
||||
@@ -45,9 +43,6 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
|
||||
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
||||
install
|
||||
|
||||
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
|
||||
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
@@ -73,17 +68,11 @@ fi
|
||||
%attr(0644,root,root) %config /etc/avrdude.conf
|
||||
|
||||
%files docs
|
||||
%doc doc/avrdude-html/*.html
|
||||
%doc doc/TODO
|
||||
%doc doc/avrdude-html
|
||||
%doc doc/avrdude.ps
|
||||
%doc doc/avrdude.pdf
|
||||
|
||||
%changelog
|
||||
* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
|
||||
[Thanks to Artur Lipowski <LAL@pro.onet.pl>]
|
||||
- Do not build debug package.
|
||||
- Remove files not packaged to quell RH9 rpmbuild complaints.
|
||||
|
||||
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
|
||||
- Add docs sub-package.
|
||||
- Add %post and %preun scriptlets for handling info files.
|
||||
|
||||
@@ -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 {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
int avr910_devcode; /* avr910 device code */
|
||||
int devicecode; /* Atmel STK500 device code */
|
||||
int chip_erase_delay; /* microseconds */
|
||||
unsigned char pagel; /* for parallel programming */
|
||||
unsigned char bs2; /* for parallel programming */
|
||||
@@ -116,27 +115,4 @@ typedef struct avrmem {
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
} 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
|
||||
|
||||
@@ -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 "pgm.h"
|
||||
#include "stk500.h"
|
||||
#include "avr910.h"
|
||||
#include "butterfly.h"
|
||||
#include "avr.h"
|
||||
|
||||
extern char * progname;
|
||||
@@ -65,7 +63,6 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_PAGE_SIZE
|
||||
%token K_PAGED
|
||||
|
||||
%token K_BAUDRATE
|
||||
%token K_BS2
|
||||
%token K_BUFF
|
||||
%token K_CHIP_ERASE_DELAY
|
||||
@@ -75,8 +72,6 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_DEFAULT_SERIAL
|
||||
%token K_DESC
|
||||
%token K_DEVICECODE
|
||||
%token K_STK500_DEVCODE
|
||||
%token K_AVR910_DEVCODE
|
||||
%token K_EEPROM
|
||||
%token K_ERRLED
|
||||
%token K_FLASH
|
||||
@@ -106,8 +101,6 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_SCK
|
||||
%token K_SIZE
|
||||
%token K_STK500
|
||||
%token K_AVR910
|
||||
%token K_BUTTERFLY
|
||||
%token K_TYPE
|
||||
%token K_VCC
|
||||
%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 {
|
||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||
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);
|
||||
assign_pin(PIN_AVR_RESET, $3); } |
|
||||
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||
@@ -428,24 +403,7 @@ part_parm :
|
||||
|
||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at %s:%d: devicecode is deprecated, use "
|
||||
"stk500_devcode instead\n",
|
||||
progname, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
} |
|
||||
|
||||
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->stk500_devcode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->avr910_devcode = $3->value.number;
|
||||
current_part->devicecode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
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_HOST
|
||||
@@ -42,7 +42,6 @@ AM_PROG_LEX
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([termcap], [tputs])
|
||||
AC_CHECK_LIB([ncurses], [tputs])
|
||||
AC_CHECK_LIB([readline], [readline])
|
||||
|
||||
# Checks for header files.
|
||||
@@ -125,12 +124,6 @@ case $target in
|
||||
esac
|
||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
fi
|
||||
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
doc/Makefile
|
||||
windows/Makefile
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@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
|
||||
* 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])
|
||||
{
|
||||
sys_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default system config file.*/
|
||||
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
||||
return;
|
||||
@@ -40,8 +38,6 @@ void win_sys_config_set(char sys_config[PATH_MAX])
|
||||
|
||||
void win_usr_config_set(char usr_config[PATH_MAX])
|
||||
{
|
||||
usr_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default user config file. */
|
||||
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@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
|
||||
* 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
|
||||
this optimization already.
|
||||
|
||||
- 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.
|
||||
|
||||
- Add ability to find all parallel port names available and base addresses
|
||||
of available ports.
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
@setfilename avrdude.info
|
||||
@settitle AVRDUDE
|
||||
@finalout
|
||||
|
||||
@include version.texi
|
||||
|
||||
@@ -98,11 +97,10 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
* Command Line Options::
|
||||
* Terminal Mode Operation::
|
||||
* Command Line Options::
|
||||
* Terminal Mode Operation::
|
||||
* Configuration File::
|
||||
* Platform Dependent Information::
|
||||
* Troubleshooting::
|
||||
* Platform Dependent Information::
|
||||
@end menu
|
||||
|
||||
@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,
|
||||
programming fuse/lock bits, etc.
|
||||
|
||||
AVRDUDE supports three basic programmer types: Atmel's STK500, appnote
|
||||
avr910 and the PPI (parallel port interface). PPI represents a class
|
||||
of simple programmers where the programming lines are directly
|
||||
connected to the PC parallel port. Several pin configurations exist
|
||||
for several variations of the PPI programmers, and AVRDUDE can be be
|
||||
configured to work with them by either specifying the appropriate
|
||||
programmer on the command line or by creating a new entry in its
|
||||
configuration file. All that's usually required for a new entry is to
|
||||
tell AVRDUDE which pins to use for each programming function.
|
||||
|
||||
The STK500 and avr910 use the serial port to communicate with the PC
|
||||
AVRDUDE supports two basic programmer types: Atmel's STK500 and the PPI
|
||||
(parallel port interface). PPI represents a class of simple programmers
|
||||
where the programming lines are directly connected to the PC parallel
|
||||
port, while the STK500 uses the serial port to communicate with the PC
|
||||
and contains on-board logic to control the programming of the target
|
||||
device. The fundamental difference between the two types lies in the
|
||||
protocol used to control the programmer. The avr910 protocol is very
|
||||
simplistic and can easily be used as the basis for a simple, home made
|
||||
programer since the firmware is available online. On the other hand,
|
||||
the STK500 protocol is more robust and complicated and the firmware is
|
||||
not openly available.
|
||||
device. Several pin configurations exist for several variations of the
|
||||
PPI programmers, and AVRDUDE can be be configured to work with them by
|
||||
either specifying the appropriate programmer on the command line or by
|
||||
creating a new entry in its configuration file. All that's usually
|
||||
required for a new entry is to tell AVRDUDE which pins to use for each
|
||||
programming function.
|
||||
|
||||
@menu
|
||||
* History::
|
||||
@@ -156,7 +147,7 @@ not openly available.
|
||||
@c Node
|
||||
@c
|
||||
@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
|
||||
the FreeBSD Operating System. Brian renamed the software to be called
|
||||
@@ -188,8 +179,8 @@ Roth.
|
||||
@cindex options
|
||||
|
||||
@menu
|
||||
* Option Descriptions::
|
||||
* Example Command Line Invocations::
|
||||
* Option Descriptions::
|
||||
* Example Command Line Invocations::
|
||||
@end menu
|
||||
|
||||
@c
|
||||
@@ -213,7 +204,7 @@ following options are recognized:
|
||||
@item -p @var{partno}
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -221,6 +212,9 @@ datasheet so that you can enter the programming specifications.
|
||||
Currently, the following MCU types are understood:
|
||||
|
||||
@table @code
|
||||
@itemx t15
|
||||
ATtiny15
|
||||
|
||||
@itemx 1200
|
||||
AT90S1200
|
||||
|
||||
@@ -248,51 +242,24 @@ AT90S8515
|
||||
@itemx 8535
|
||||
AT90S8535
|
||||
|
||||
@itemx m103
|
||||
ATMEGA103
|
||||
|
||||
@itemx m128
|
||||
ATMEGA128
|
||||
|
||||
@itemx m16
|
||||
ATMEGA16
|
||||
|
||||
@itemx m161
|
||||
ATMEGA161
|
||||
|
||||
@itemx m162
|
||||
ATMEGA162
|
||||
|
||||
@itemx m163
|
||||
ATMEGA163
|
||||
|
||||
@itemx m169
|
||||
ATMEGA169
|
||||
|
||||
@itemx m32
|
||||
ATMEGA32
|
||||
@itemx m128
|
||||
ATMEGA128
|
||||
|
||||
@itemx m64
|
||||
ATMEGA64
|
||||
@itemx m103
|
||||
ATMEGA103
|
||||
|
||||
@itemx m16
|
||||
ATMEGA16
|
||||
|
||||
@itemx m8
|
||||
ATMEGA8
|
||||
|
||||
@itemx m8515
|
||||
ATMEGA8515
|
||||
|
||||
@itemx m8535
|
||||
ATMEGA8535
|
||||
|
||||
@itemx t12
|
||||
ATtiny12
|
||||
|
||||
@itemx t15
|
||||
ATtiny15
|
||||
|
||||
@itemx t26
|
||||
ATTINY26
|
||||
|
||||
@end table
|
||||
|
||||
(*) The AT90S2323 uses the same algorithm.
|
||||
@@ -301,61 +268,12 @@ ATTINY26
|
||||
Specify the programmer to be used. AVRDUDE knows about several common
|
||||
programmers. Use this option to specify which one to use. The
|
||||
@var{programmer-id} parameter is the programmer's id listed in the
|
||||
configuration file. Specify -c ? to list all programmers in the
|
||||
configuration file. Specify -c ? to list all programmers in the
|
||||
configuration file. If you have a programmer that is unknown to
|
||||
AVRDUDE, and the programmer is controlled via the PC parallel port,
|
||||
there's a good chance that it can be easily added to the configuration
|
||||
file without any code changes to AVRDUDE. Simply copy an existing entry
|
||||
and change the pin definitions to match that of the unknown programmer.
|
||||
Currently, the following programmer ids are understood and supported:
|
||||
|
||||
@table @code
|
||||
|
||||
@itemx 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}
|
||||
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
|
||||
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
|
||||
Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value `0xff', and is basically a
|
||||
prerequisite command before the flash ROM can be reprogrammed again.
|
||||
The only exception would be if the new contents would exclusively cause
|
||||
bits to be 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
|
||||
since the MCU provides an auto-erase cycle in that case before
|
||||
programming the cell.
|
||||
@@ -389,12 +299,12 @@ programming the cell.
|
||||
@item -E @var{exitspec}[,@dots{}]
|
||||
By default, AVRDUDE leaves the parallel port in the same state at exit
|
||||
as it has been found at startup. This option modifies the state of the
|
||||
`/RESET' and `Vcc' lines the 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:
|
||||
|
||||
@table @code
|
||||
@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.
|
||||
Note in particular that the programming algorithm for the AT90S1200
|
||||
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
|
||||
connected.
|
||||
|
||||
@itemx vcc
|
||||
@itemx vcc
|
||||
This option will leave those parallel port pins active (i. e. high) that
|
||||
can be used to supply `Vcc' power to the MCU.
|
||||
|
||||
@itemx novcc
|
||||
This option will pull the `Vcc' pins of the parallel port down at
|
||||
This option will pull the `Vcc' pins of the paral- lel port down at
|
||||
program exit.
|
||||
|
||||
@end table
|
||||
@@ -422,7 +332,7 @@ Multiple @var{exitspec} arguments can be separated with commas.
|
||||
|
||||
|
||||
@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:
|
||||
|
||||
@table @code
|
||||
@@ -435,16 +345,6 @@ Motorola S-record
|
||||
@itemx r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
|
||||
@itemx m
|
||||
immediate mode; actual byte values specified on the command line,
|
||||
seperated by commas or spaces in place of the @var{filename} field of
|
||||
the @option{-i}, @option{-o}, or @option{-U} options. This is useful
|
||||
for programming fuse bytes without having to create a single-byte file
|
||||
or enter terminal mode. If the number specified begins with @code{0x},
|
||||
it is treated as a hex value. If the number otherwise begins with a
|
||||
leading zero (@code{0}) it is treated as octal. Otherwise, the value is
|
||||
treated as decimal.
|
||||
|
||||
@itemx a
|
||||
auto detect; valid for input only, and only if the input is not provided
|
||||
at stdin.
|
||||
@@ -483,50 +383,17 @@ respective memory area to be read from the MCU. Can be specified as `-'
|
||||
to write to stdout.
|
||||
|
||||
@item -P @var{port}
|
||||
Use port to identify the device to which the programmer is attached.
|
||||
Normally, the default parallel port is used, but if the programmer type
|
||||
normally connects to the serial port, the default serial port will be
|
||||
used. See Appendix A, Platform Dependent Information, to find out the
|
||||
default port names for your platform. If you need to use a different
|
||||
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.
|
||||
Use port to identify the device to which the programmer is attached. By
|
||||
default the @code{/dev/ppi0} port is used, but if the programmer type
|
||||
normally connects to the serial port, the @code{/dev/cuaa0} port is the
|
||||
default. If you need to use a different parallel or serial port, use
|
||||
this option to spec- ify the alternate port name.
|
||||
|
||||
@item -t
|
||||
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
||||
or downloading files. See below for a detailed description of the
|
||||
terminal mode.
|
||||
|
||||
@item -U @var{memtype}:@var{op}:@var{filename}[:@var{format}]
|
||||
Perform a memory operation, equivalent to specifing the @option{-m},
|
||||
@option{-i} or @option{-o}, and @option{-f} options, except that
|
||||
multiple @option{-U} optins can be specified in order to operate on
|
||||
mulitple memories on the same command-line invocation. The
|
||||
@var{memtype} field specifies the memory type to operate on. The
|
||||
@var{op} field specifies what operation to perform:
|
||||
|
||||
@table @code
|
||||
@itemx r
|
||||
read the specified device memory and write to the specified file
|
||||
|
||||
@itemx w
|
||||
read the specified file and write it to the specified device memory
|
||||
|
||||
@itemx v
|
||||
read the specified device memory and the specified file and perform a verify operation
|
||||
|
||||
@end table
|
||||
|
||||
The @var{filename} field indicates the name of the file to read or
|
||||
write. The @var{format} field is optional and contains the format of
|
||||
the file to read or write. See the @option{-f} option for possible
|
||||
values.
|
||||
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
|
||||
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
|
||||
this option is used and the @option{-e} flag is specified to generate a
|
||||
chip erase, the previous counter will be saved before the chip erase, it
|
||||
is then incremented, and written back after the erase cycle completes.
|
||||
is then incremented, and written back after the erase cycle com- pletes.
|
||||
Presumably, the device would only be erased just before being
|
||||
programmed, and thus, this can be utilized to give an indication of how
|
||||
many erase-rewrite cycles the part has undergone. Since the FLASH
|
||||
memory can only endure a finite number of erase-rewrite cycles, one can
|
||||
use this option to track when a part is nearing the limit. The typical
|
||||
limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
||||
application needs the last four bytes of EEPROM memory, this option
|
||||
use this option to track when a part is nearing the limit. The typ-
|
||||
ical limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
|
||||
application needs the last four bytes of EEPROM mem- ory, this option
|
||||
should not be used.
|
||||
|
||||
@item -Y @var{cycles}
|
||||
@@ -563,64 +430,50 @@ should not be used.
|
||||
@section Example Command Line Invocations
|
||||
|
||||
@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:
|
||||
|
||||
@example
|
||||
@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
|
||||
|
||||
Reading | ################################################## | 100% 0.03s
|
||||
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: erasing chip
|
||||
avrdude: erase-rewrite cycle count is now 52
|
||||
avrdude: done.
|
||||
avrdude: performing op: 1, flash, 0, diag.hex
|
||||
avrdude: reading input file "diag.hex"
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: writing flash (19278 bytes):
|
||||
|
||||
Writing | ################################################## | 100% 7.60s
|
||||
|
||||
avrdude: 19456 bytes of flash written
|
||||
avrdude: verifying flash memory against diag.hex:
|
||||
avrdude: load data flash data from input file diag.hex:
|
||||
avrdude: input file diag.hex auto detected as Intel Hex
|
||||
avrdude: input file diag.hex contains 19278 bytes
|
||||
avrdude: reading input file "m128diag.hex"
|
||||
avrdude: input file m128diag.hex auto detected as Intel Hex
|
||||
avrdude: writing flash (18130 bytes):
|
||||
18175
|
||||
avrdude: 18176 bytes of flash written
|
||||
avrdude: verifying flash memory against m128diag.hex:
|
||||
avrdude: reading on-chip flash data:
|
||||
|
||||
Reading | ################################################## | 100% 6.83s
|
||||
|
||||
18175
|
||||
avrdude: verifying ...
|
||||
avrdude: 19278 bytes of flash verified
|
||||
avrdude: 18176 bytes of flash verified
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
%
|
||||
%
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Upload the flash memory from the ATmega128 connected to the STK500
|
||||
programmer and save it in raw binary format in the file named
|
||||
@code{c:/diag flash.bin}:
|
||||
@code{m128diag.flash}:
|
||||
|
||||
@example
|
||||
@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
|
||||
|
||||
Reading | ################################################## | 100% 0.03s
|
||||
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
|
||||
avrdude: reading flash memory:
|
||||
|
||||
Reading | ################################################## | 100% 46.10s
|
||||
|
||||
avrdude: writing output file "c:/diag flash.bin"
|
||||
131071
|
||||
avrdude: writing output file "m128diag.flash"
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
@@ -628,55 +481,6 @@ avrdude done. Thank you.
|
||||
@end cartouche
|
||||
@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 Node
|
||||
@@ -744,33 +548,6 @@ Leave terminal mode and thus AVRDUDE.
|
||||
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
In addition, the following commands are supported on the STK500
|
||||
programmer:
|
||||
|
||||
@table @code
|
||||
|
||||
@item vtarg @var{voltage}
|
||||
Set the target's supply voltage to @var{voltage} Volts.
|
||||
|
||||
@item varef @var{voltage}
|
||||
Set the adjustable voltage source to @var{voltage} Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
@emph{Aref} input on the STK500.
|
||||
|
||||
@item fosc @var{freq}[@var{M}|@var{k}]
|
||||
Set the master oscillator to @var{freq} Hz.
|
||||
An optional trailing letter @var{M}
|
||||
multiplies by 1E6, a trailing letter @var{k} by 1E3.
|
||||
|
||||
@item fosc off
|
||||
Turn the master oscillator off.
|
||||
|
||||
@item parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
|
||||
@end table
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@@ -837,8 +614,8 @@ avrdude>
|
||||
|
||||
@noindent
|
||||
Program the fuse bits of an ATmega128 (disable M103 compatibility,
|
||||
enable high speed external crystal, enable brown-out detection, slowly
|
||||
rising power). First display the factory defaults, then reprogram:
|
||||
enable high speed external crystal, enable brown-out detection). First
|
||||
display the factory defaults, then reprogram:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
@@ -865,8 +642,8 @@ avrdude> w efuse 0 0xff
|
||||
avrdude> w hfuse 0 0x89
|
||||
>>> w hfuse 0 0x89
|
||||
|
||||
avrdude> w lfuse 0 0x2f
|
||||
>>> w lfuse 0 0x2f
|
||||
avrdude> w lfuse 0 0x2e
|
||||
>>> w lfuse 0 0x2e
|
||||
|
||||
avrdude>
|
||||
@end cartouche
|
||||
@@ -942,18 +719,17 @@ The format of the programmer definition is as follows:
|
||||
@example
|
||||
programmer
|
||||
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||
desc = <description> ; # quoted string
|
||||
type = par | stk500 ; # programmer type
|
||||
baudrate = <num> ; # baudrate for avr910
|
||||
vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||
reset = <num> ; # pin number
|
||||
sck = <num> ; # pin number
|
||||
mosi = <num> ; # pin number
|
||||
miso = <num> ; # pin number
|
||||
errled = <num> ; # pin number
|
||||
rdyled = <num> ; # pin number
|
||||
pgmled = <num> ; # pin number
|
||||
vfyled = <num> ; # pin number
|
||||
desc = <description> ; # quoted string
|
||||
type = par | stk500 ; # programmer type
|
||||
vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||
reset = <num> ; # pin number
|
||||
sck = <num> ; # pin number
|
||||
mosi = <num> ; # pin number
|
||||
miso = <num> ; # pin number
|
||||
errled = <num> ; # pin number
|
||||
rdyled = <num> ; # pin number
|
||||
pgmled = <num> ; # pin number
|
||||
vfyled = <num> ; # pin number
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -1000,7 +776,7 @@ part
|
||||
@end example
|
||||
|
||||
@menu
|
||||
* Instruction Format::
|
||||
* Instruction Format::
|
||||
@end menu
|
||||
|
||||
@c
|
||||
@@ -1048,7 +824,7 @@ instruction for an AT90S2313 AVR part could be encoded as:
|
||||
|
||||
@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";
|
||||
|
||||
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
|
||||
@item
|
||||
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
|
||||
@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 Node
|
||||
@c
|
||||
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
|
||||
@node Platform Dependent Information, , Configuration File, Top
|
||||
@appendix Platform Dependent Information
|
||||
|
||||
@menu
|
||||
* Unix::
|
||||
* Windows::
|
||||
* Unix::
|
||||
* Windows::
|
||||
@end menu
|
||||
|
||||
@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
|
||||
it successfully start the driver.
|
||||
|
||||
Note that you must have administrator privilege to load the giveio driver.
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@@ -1544,55 +1318,4 @@ line driven and for writing the batch files.
|
||||
|
||||
@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
|
||||
|
||||
|
||||
199
avrdude/fileio.c
199
avrdude/fileio.c
@@ -360,10 +360,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
char * outfile, FILE * outf)
|
||||
{
|
||||
unsigned char * buf;
|
||||
unsigned int nextaddr;
|
||||
unsigned int nextaddr, stopaddr;
|
||||
int n, nbytes, addr_width;
|
||||
int i;
|
||||
unsigned char cksum;
|
||||
unsigned char startf, stopf ,emptyf;
|
||||
|
||||
char * tmpl=0;
|
||||
|
||||
@@ -372,11 +373,39 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
progname, recsize);
|
||||
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;
|
||||
|
||||
while (bufsize) {
|
||||
@@ -406,23 +435,34 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
/* skip the lines filled with 0xff */
|
||||
emptyf = 1;
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
if (buf[i] != 0xff) {
|
||||
emptyf=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
if (emptyf != 1) {
|
||||
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
}
|
||||
|
||||
nextaddr += n;
|
||||
nbytes +=n;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
@@ -895,8 +892,8 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
char * fname;
|
||||
unsigned char * buf;
|
||||
struct fioparms fio;
|
||||
int i;
|
||||
AVRMEM * mem;
|
||||
int using_stdio;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
@@ -910,33 +907,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
/* Open Raw Binary format in binary mode on Windows.*/
|
||||
if(format == FMT_RBIN)
|
||||
{
|
||||
if(fio.op == FIO_READ)
|
||||
{
|
||||
fio.mode = "rb";
|
||||
}
|
||||
if(fio.op == FIO_WRITE)
|
||||
{
|
||||
fio.mode = "wb";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* point at the requested memory buffer */
|
||||
buf = mem->buf;
|
||||
if (fio.op == FIO_READ)
|
||||
size = mem->size;
|
||||
|
||||
if (fio.op == FIO_READ) {
|
||||
/* 0xff fill unspecified memory */
|
||||
memset(buf, 0xff, size);
|
||||
}
|
||||
|
||||
using_stdio = 0;
|
||||
|
||||
if (strcmp(filename, "-")==0) {
|
||||
if (fio.op == FIO_READ) {
|
||||
fname = "<stdin>";
|
||||
@@ -946,22 +916,30 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
fname = "<stdout>";
|
||||
f = stdout;
|
||||
}
|
||||
using_stdio = 1;
|
||||
}
|
||||
else {
|
||||
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 (using_stdio) {
|
||||
fprintf(stderr,
|
||||
"%s: can't auto detect file format when using stdin/out.\n"
|
||||
" Please specify a file format using the -f option and try again.\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
format = fmt_autodetect(fname);
|
||||
if (format < 0) {
|
||||
fprintf(stderr,
|
||||
@@ -974,17 +952,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
progname, fio.iodesc, fname, fmtstr(format));
|
||||
}
|
||||
|
||||
if (format != FMT_IMM) {
|
||||
if (!using_stdio) {
|
||||
f = fopen(fname, fio.mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case FMT_IHEX:
|
||||
rc = fileio_ihex(&fio, fname, f, buf, size);
|
||||
@@ -998,26 +965,12 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
rc = fileio_rbin(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
case FMT_IMM:
|
||||
rc = fileio_imm(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||
progname, fio.iodesc, format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc > 0) {
|
||||
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) {
|
||||
/*
|
||||
* if we are reading flash, just mark the size as being the
|
||||
* highest non-0xff byte
|
||||
*/
|
||||
rc = avr_mem_hiaddr(mem);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ typedef enum {
|
||||
FMT_AUTO,
|
||||
FMT_SREC,
|
||||
FMT_IHEX,
|
||||
FMT_RBIN,
|
||||
FMT_IMM
|
||||
FMT_RBIN
|
||||
} FILEFMT;
|
||||
|
||||
struct fioparms {
|
||||
|
||||
@@ -117,7 +117,6 @@ SIGN [+-]
|
||||
|
||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
banked { yylval=NULL; return K_PAGED; }
|
||||
baudrate { yylval=NULL; return K_BAUDRATE; }
|
||||
bs2 { yylval=NULL; return K_BS2; }
|
||||
buff { yylval=NULL; return K_BUFF; }
|
||||
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_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
errled { yylval=NULL; return K_ERRLED; }
|
||||
flash { yylval=NULL; return K_FLASH; }
|
||||
@@ -155,8 +152,6 @@ retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||
serial { yylval=NULL; return K_SERIAL; }
|
||||
size { yylval=NULL; return K_SIZE; }
|
||||
stk500 { yylval=NULL; return K_STK500; }
|
||||
avr910 { yylval=NULL; return K_AVR910; }
|
||||
butterfly { yylval=NULL; return K_BUTTERFLY; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
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 res[4];
|
||||
int cycles;
|
||||
int rc;
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
@@ -337,6 +352,16 @@ static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ PROGRAMMER * pgm_new(void)
|
||||
pgm->type[0] = 0;
|
||||
pgm->config_file[0] = 0;
|
||||
pgm->lineno = 0;
|
||||
pgm->baudrate = 0;
|
||||
|
||||
for (i=0; i<N_PINS; i++)
|
||||
pgm->pinno[i] = 0;
|
||||
@@ -90,13 +89,6 @@ PROGRAMMER * pgm_new(void)
|
||||
*/
|
||||
pgm->paged_write = NULL;
|
||||
pgm->paged_load = NULL;
|
||||
pgm->write_setup = NULL;
|
||||
pgm->write_byte = NULL;
|
||||
pgm->read_byte = NULL;
|
||||
pgm->read_sig_bytes = NULL;
|
||||
pgm->set_vtarget = NULL;
|
||||
pgm->set_varef = NULL;
|
||||
pgm->set_fosc = NULL;
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ typedef struct programmer_t {
|
||||
char port[PGM_PORTLEN];
|
||||
unsigned int pinno[N_PINS];
|
||||
int ppidata;
|
||||
int baudrate;
|
||||
int fd;
|
||||
int page_size; /* page size if the programmer supports paged write/load */
|
||||
int (*rdy_led) (struct programmer_t * pgm, int value);
|
||||
@@ -67,16 +66,6 @@ typedef struct programmer_t {
|
||||
int page_size, int n_bytes);
|
||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes);
|
||||
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value);
|
||||
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value);
|
||||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, double v);
|
||||
int (*set_fosc) (struct programmer_t * pgm, double v);
|
||||
char config_file[PATH_MAX]; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
} PROGRAMMER;
|
||||
|
||||
108
avrdude/ppi.c
108
avrdude/ppi.c
@@ -43,33 +43,24 @@
|
||||
|
||||
extern char * progname;
|
||||
|
||||
enum {
|
||||
PPI_READ,
|
||||
PPI_WRITE,
|
||||
PPI_SHADOWREAD
|
||||
};
|
||||
|
||||
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
|
||||
/*
|
||||
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
|
||||
* to get/set the specified PPI registers.
|
||||
*/
|
||||
static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
|
||||
{
|
||||
static unsigned char shadow[3];
|
||||
int shadow_num;
|
||||
unsigned long set, get;
|
||||
|
||||
switch (reg) {
|
||||
case PPIDATA:
|
||||
set = PPISDATA;
|
||||
get = PPIGDATA;
|
||||
shadow_num = 0;
|
||||
*set = PPISDATA;
|
||||
*get = PPIGDATA;
|
||||
break;
|
||||
case PPICTRL:
|
||||
set = PPISCTRL;
|
||||
get = PPIGCTRL;
|
||||
shadow_num = 1;
|
||||
*set = PPISCTRL;
|
||||
*get = PPIGCTRL;
|
||||
break;
|
||||
case PPISTATUS:
|
||||
set = PPISSTATUS;
|
||||
get = PPIGSTATUS;
|
||||
shadow_num = 2;
|
||||
*set = PPISSTATUS;
|
||||
*get = PPIGSTATUS;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_set(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v |= bit;
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v |= bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,15 +100,17 @@ int ppi_set(int fd, int reg, int bit)
|
||||
int ppi_clr(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v &= ~bit;
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v &= ~bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,14 +121,16 @@ int ppi_clr(int fd, int reg, int bit)
|
||||
int ppi_get(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
||||
v &= bit;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &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)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v ^= bit;
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v ^= bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -174,14 +161,16 @@ int ppi_toggle(int fd, int reg, int bit)
|
||||
int ppi_getall(int fd, int reg)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
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)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
v = val;
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
v = val;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -205,7 +196,6 @@ int ppi_setall(int fd, int reg, int val)
|
||||
int ppi_open(char * port)
|
||||
{
|
||||
int fd;
|
||||
unsigned char v;
|
||||
|
||||
fd = open(port, O_RDWR);
|
||||
if (fd < 0) {
|
||||
@@ -214,14 +204,6 @@ int ppi_open(char * port)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 <unistd.h>
|
||||
#include <windows.h>
|
||||
#include <sys/time.h>
|
||||
#include <w32api/windows.h>
|
||||
#include "ppi.h"
|
||||
|
||||
|
||||
@@ -317,78 +315,6 @@ static void outb(unsigned char value, unsigned short port)
|
||||
return;
|
||||
}
|
||||
|
||||
/* These two functions usecPerfDelay and usleep are based on code from the
|
||||
* uisp project and are a replacement for the cygwin usleep library
|
||||
* function which seems to not delay for the correct time
|
||||
*/
|
||||
|
||||
BOOL usecPerfDelay(long t)
|
||||
{
|
||||
static BOOL perf_counter_checked = FALSE;
|
||||
static BOOL use_perf_counter = FALSE;
|
||||
static LARGE_INTEGER freq ;
|
||||
|
||||
if (! perf_counter_checked) {
|
||||
if (QueryPerformanceFrequency(&freq)){
|
||||
use_perf_counter = TRUE;
|
||||
}
|
||||
perf_counter_checked = TRUE;
|
||||
}
|
||||
|
||||
if (! use_perf_counter)
|
||||
return FALSE;
|
||||
|
||||
else {
|
||||
LARGE_INTEGER now;
|
||||
LARGE_INTEGER finish;
|
||||
QueryPerformanceCounter(&now);
|
||||
finish.QuadPart = now.QuadPart + (t * freq.QuadPart) / 1000000;
|
||||
do {
|
||||
QueryPerformanceCounter(&now);
|
||||
} while (now.QuadPart < finish.QuadPart);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
WARNING WARNING This function replaces the standard usleep() library function
|
||||
because it doesn't appear to delay for the correct time.
|
||||
*/
|
||||
|
||||
#ifndef MIN_SLEEP_USEC
|
||||
#define MIN_SLEEP_USEC 20000
|
||||
#endif
|
||||
|
||||
unsigned usleep( unsigned int uSeconds )
|
||||
{
|
||||
struct timeval t1, t2;
|
||||
struct timespec nanoDelay ;
|
||||
|
||||
if (usecPerfDelay(uSeconds))
|
||||
return(0);
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
|
||||
if( uSeconds > MIN_SLEEP_USEC )
|
||||
{
|
||||
nanoDelay.tv_sec = uSeconds / 1000000UL;
|
||||
nanoDelay.tv_nsec = (uSeconds / 1000000UL) * 1000 ;
|
||||
nanosleep( &nanoDelay, NULL ) ;
|
||||
}
|
||||
|
||||
/* loop for the remaining time */
|
||||
t2.tv_sec = uSeconds / 1000000UL;
|
||||
t2.tv_usec = uSeconds % 1000000UL;
|
||||
|
||||
timeradd(&t1, &t2, &t1);
|
||||
|
||||
do {
|
||||
gettimeofday(&t2, NULL);
|
||||
} while (timercmp(&t2, &t1, <));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500_private.h"
|
||||
#include "serial.h"
|
||||
|
||||
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
|
||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
||||
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p);
|
||||
static int stk500_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)
|
||||
{
|
||||
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 res[4];
|
||||
int cycles;
|
||||
int rc;
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
@@ -189,6 +333,16 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -364,7 +518,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
*/
|
||||
buf[0] = Cmnd_STK_SET_DEVICE;
|
||||
|
||||
buf[1] = p->stk500_devcode;
|
||||
buf[1] = p->devicecode;
|
||||
buf[2] = 0; /* device revision */
|
||||
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
||||
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
|
||||
@@ -603,7 +819,7 @@ static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void stk500_close(PROGRAMMER * pgm)
|
||||
{
|
||||
serial_close(pgm->fd);
|
||||
close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
@@ -662,10 +878,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int memtype;
|
||||
unsigned int addr;
|
||||
int a_div;
|
||||
int block_size;
|
||||
int i;
|
||||
int tries;
|
||||
unsigned int n;
|
||||
int flash;
|
||||
|
||||
if (page_size == 0) {
|
||||
page_size = 128;
|
||||
@@ -673,11 +888,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
memtype = 'F';
|
||||
flash = 1;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
memtype = 'E';
|
||||
flash = 0;
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
@@ -711,33 +924,20 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
#endif
|
||||
|
||||
for (addr = 0; addr < n; addr += page_size) {
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\r \r%6u", addr);
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
stk500_loadaddr(pgm, addr/a_div);
|
||||
buf[0] = Cmnd_STK_PROG_PAGE;
|
||||
buf[1] = (block_size >> 8) & 0xff;
|
||||
buf[2] = block_size & 0xff;
|
||||
buf[1] = (page_size >> 8) & 0xff;
|
||||
buf[2] = page_size & 0xff;
|
||||
buf[3] = memtype;
|
||||
stk500_send(pgm, buf, 4);
|
||||
|
||||
stk500_send(pgm, &m->buf[addr], block_size);
|
||||
|
||||
for (i=0; i<page_size; i++) {
|
||||
buf[0] = m->buf[addr + i];
|
||||
stk500_send(pgm, buf, 1);
|
||||
}
|
||||
buf[0] = Sync_CRC_EOP;
|
||||
stk500_send(pgm, buf, 1);
|
||||
|
||||
@@ -768,24 +968,12 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\r \r%6u", addr-1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return n_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,
|
||||
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 tries;
|
||||
unsigned int n;
|
||||
int block_size;
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
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) {
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
|
||||
if (addr + page_size > n_bytes) {
|
||||
block_size = n_bytes % page_size;
|
||||
}
|
||||
else {
|
||||
block_size = page_size;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\r \r%6u", addr);
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
stk500_loadaddr(pgm, addr/a_div);
|
||||
buf[0] = Cmnd_STK_READ_PAGE;
|
||||
buf[1] = (block_size >> 8) & 0xff;
|
||||
buf[2] = block_size & 0xff;
|
||||
buf[1] = (page_size >> 8) & 0xff;
|
||||
buf[2] = page_size & 0xff;
|
||||
buf[3] = memtype;
|
||||
buf[4] = Sync_CRC_EOP;
|
||||
stk500_send(pgm, buf, 5);
|
||||
@@ -865,7 +1044,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -4;
|
||||
}
|
||||
|
||||
stk500_recv(pgm, &m->buf[addr], block_size);
|
||||
stk500_recv(pgm, &m->buf[addr], page_size);
|
||||
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
@@ -876,108 +1055,10 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\r \r%6u", addr-1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
unsigned maj, min, hdw, topcard;
|
||||
unsigned maj, min, hdw;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
|
||||
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
||||
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
||||
stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
|
||||
|
||||
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
|
||||
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
|
||||
if (topcard < 3) {
|
||||
const char *n = "Unknown";
|
||||
|
||||
switch (topcard) {
|
||||
case 1:
|
||||
n = "STK502";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
n = "STK501";
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "%sTopcard : %s\n", p, n);
|
||||
}
|
||||
stk500_print_parms1(pgm, p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned vtarget, vadjust, osc_pscale, osc_cmatch;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
|
||||
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
||||
|
||||
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
||||
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
|
||||
fprintf(stderr, "%sOscillator : ", p);
|
||||
if (osc_pscale == 0)
|
||||
fprintf(stderr, "Off\n");
|
||||
else {
|
||||
int prescale = 1;
|
||||
double f = 3.6864e6;
|
||||
const char *unit;
|
||||
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
case 3: prescale = 32; break;
|
||||
case 4: prescale = 64; break;
|
||||
case 5: prescale = 128; break;
|
||||
case 6: prescale = 256; break;
|
||||
case 7: prescale = 1024; break;
|
||||
}
|
||||
f /= prescale;
|
||||
f /= (osc_cmatch + 1);
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
unit = "kHz";
|
||||
} else
|
||||
unit = "Hz";
|
||||
fprintf(stderr, "%.3f %s\n", f, unit);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void stk500_print_parms(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500_print_parms1(pgm, "");
|
||||
}
|
||||
|
||||
|
||||
void stk500_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK500");
|
||||
@@ -1202,9 +1163,7 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
||||
*/
|
||||
pgm->paged_write = stk500_paged_write;
|
||||
pgm->paged_load = stk500_paged_load;
|
||||
pgm->print_parms = stk500_print_parms;
|
||||
pgm->set_vtarget = stk500_set_vtarget;
|
||||
pgm->set_varef = stk500_set_varef;
|
||||
pgm->set_fosc = stk500_set_fosc;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE
|
||||
#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached
|
||||
|
||||
|
||||
// *****************[ STK status bit definitions ]***************************
|
||||
|
||||
|
||||
128
avrdude/term.c
128
avrdude/term.c
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
|
||||
struct command cmd[] = {
|
||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||
@@ -85,10 +75,6 @@ struct command cmd[] = {
|
||||
{ "sig", cmd_sig, "display device signature bytes" },
|
||||
{ "part", cmd_part, "display the current part information" },
|
||||
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
|
||||
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
|
||||
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
|
||||
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
|
||||
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
|
||||
{ "help", cmd_help, "help" },
|
||||
{ "?", cmd_help, "help" },
|
||||
{ "quit", cmd_quit, "quit" }
|
||||
@@ -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 i;
|
||||
|
||||
@@ -37,7 +37,7 @@ EXTRA_DIST = \
|
||||
|
||||
bin_PROGRAMS = loaddrv
|
||||
|
||||
loaddrv_LDFLAGS = -mno-cygwin
|
||||
loaddrv_CFLAGS = -mno-cygwin
|
||||
|
||||
loaddrv_SOURCES = \
|
||||
loaddrv.c \
|
||||
|
||||
Reference in New Issue
Block a user