1 Commits

Author SHA1 Message Date
Joerg Wunsch
078a334625 This commit was manufactured by cvs2svn to create tag
'release_4_0_0'.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/release_4_0_0@286 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-12 03:43:53 +00:00
38 changed files with 1938 additions and 6768 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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__ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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__ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,8 +26,7 @@ typedef enum {
FMT_AUTO,
FMT_SREC,
FMT_IHEX,
FMT_RBIN,
FMT_IMM
FMT_RBIN
} FILEFMT;
struct fioparms {

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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__ */

View File

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

View File

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

View File

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

View File

@@ -37,7 +37,7 @@ EXTRA_DIST = \
bin_PROGRAMS = loaddrv
loaddrv_LDFLAGS = -mno-cygwin
loaddrv_CFLAGS = -mno-cygwin
loaddrv_SOURCES = \
loaddrv.c \